ein toggle bei einem behavior object in einer scene (passender name fehlt mir noch):
wenn der toggle aktiviert ist, soll das behavior außerhalb des play modes trotzdem laufen (sprich immer)
das behavior ist natürlich nicht aktiv wenn die scene nicht geladen ist wo sich das behavior befindet (sprich genauso wie im play mode, nur ohne play mode)
Umgesetzt (2026-09-09). Der Schalter heisst Run in editor und steht im Inspector eines
Behavior-Objekts direkt unter Enabled. Ist er an, laeuft das Behavior weiter, waehrend das
Projekt nicht spielt (src/editor/EditorRun.ts, vom Editor neben der Play-Session getickt).
Die eine Entscheidung, die der Schalter erzwingt
Play arbeitet auf einer Wegwerf-Kopie — deshalb ist Spielen fuer das gespeicherte Projekt
gefahrlos. Ausserhalb von Play gibt es diese Kopie nicht, und damit stand die Frage im Raum, was
ein laufendes Behavior ueberhaupt anfassen darf. Entschieden wurde (Rueckfrage an den User) fuer
die Unity-Semantik (ExecuteInEditMode):
Was das Behavior bewegt oder schreibt, ist eine echte Aenderung am gespeicherten Modell.
Sie wird autosaved, die Panels zeigen sie — und Undo holt sie nicht zurueck.
Das macht den Schalter maechtig (ein Behavior kann Inhalt bauen oder anordnen) und ist genau der
Grund, warum er standardmaessig aus ist. Der E2E-Check haelt beide Haelften fest: der Server
liefert die verschobene Position aus, und nach zwei Undos ist der Schalter weg, die Bewegung nicht.
Was der Editor-Lauf bewusst nicht bekommt
Eingaben
Tastatur und Maus bleiben beim Editor, sonst wuerde Tippen in einem Textfeld Behaviors ausloesen. On key …, On click und Is key down feuern hier nie; On start, On update, On timer und Kollisionen schon.
Container-Inhalt
syncFromModel schreibt den Inhalt platzierter Container als normale Objekte aus (baking) und loescht dabei deren instanceEdits — im Editor waere das eine stille, irreversible Aenderung. Der Lauf instanziiert deshalb mit bakeContainers: false. Preis: ein Behavior innerhalb eines platzierten Containers laeuft ausserhalb von Play nicht.
ein zweites Leben
Nur die Behaviors der geladenen Szene laufen, und nur im Edit-Modus. Play stoppt den Editor-Lauf — dort laeuft ohnehin jedes Behavior. Eine Exception im Graphen oder ein Stop game-Node beendet den Lauf und schreibt den Grund in die Notice-Zeile, statt ihn 60× pro Sekunde zu wiederholen.
Der zweite Punkt der Notiz faellt damit von selbst heraus: die Welt wird aus der aktiven Szene
gebaut, ein Behavior einer anderen Szene hat gar keine Entity. Beim Szenenwechsel wird der Lauf
neu aufgebaut oder verworfen.
Kein Save-Sturm
Ein Behavior, das jeden Frame etwas verschiebt, macht das Modell jeden Frame schmutzig — 60×
pro Sekunde speichern waere die naheliegende Katastrophe. Zwei Dinge verhindern das:
syncToModel() meldet jetzt, ob ueberhaupt geschrieben wurde ({structure, values} statt
eines blossen boolean). Ein Behavior, das nur liest oder wartet, macht gar nichts schmutzig.
setSaveStatus('dirty') emittiert nur bei Wechsel, der Autosave-Timer wird also nicht jeden
Frame neu gestellt. Gemessen: 2 Speicherungen in 2 Sekunden, nicht ~120.
Ein Darstellungsfehler, den erst der Screenshot gezeigt hat
schemaForAsset liefert fuer ein Behavior COMMON_PROPS + Typschema + Variablen. Der
Object-Inspector zeigte alles ausser enabled unter der Ueberschrift VARIABLES — der neue
Schalter landete also dort, wo nur steht, was das Behavior deklariert, und die Notiz „The
behavior declares no variables." verschwand fuer immer. Beides ist repariert: die Typschema-Zeilen
eines Behaviors stehen jetzt bei Enabled, die Sektion darunter fuehrt wieder nur die Variablen.
Aufgefallen ist es nur, weil ich mir den Screenshot angesehen habe — die Checks waren zufrieden.
Ein Messgeraet statt eines geratenen Offsets
Der erste Anlauf klickte die Checkbox ueber locate('Enabled').x + 55. Das trifft nur Zeilen,
deren Label in die 64-px-Spalte passt — Run in editor ist breiter und schiebt seine Checkbox
11 px nach rechts, also ging der Klick daneben und fuenf Checks fielen um. Neu ist deshalb __gm.inspectorField(label): es liefert die Bildschirmmitte des Controls einer Inspector-
Zeile, gefunden ueber sein Label. Damit ist jeder kuenftige Inspector-Check unabhaengig von der
Labelbreite.
Belegt
Acht Unit-Tests (tests/editor/editor-run.test.ts, plus einer in container.test.ts fuer das
Nicht-Backen). Gegengeprueft: dreht man den Filter auf „alle Behaviors" und die Szenen-Bedingung
weg, fallen vier von sieben um; mit bakeContainers: true faellt der Container-Test.
Dazu zehn E2E-Checks in Modul 17:
PASS a placed behavior does not run outside play mode until it is asked to
– {"running":false,"time":0,"behaviors":[]} x=0
PASS the inspector offers the switch on a behavior object, with Enabled and above the variables
– {"enabledBox":{"x":1070,"y":221},"runBox":{"x":1081,"y":253},"variables":{…,"y":509.5}}
PASS switching it on is an ordinary override on the object – {"runInEditor":true}
PASS the behavior runs although Play was never pressed
– {"running":true,"time":0.46,"behaviors":["er-logic"]} mode=edit
PASS the owner drifts on, and the moved object is the stored one – x 48.33 → 108.32
PASS what the behavior moved is saved, not just shown – stored x=308.31 (started at 0)
PASS saving stays debounced while it runs, instead of once per frame – 2 saves in 2 s
PASS taking the switch back stops the run and the object stands still – x=329.98
PASS undo takes back the switch, never the movement it caused – overrides={} x=351.65, started at 0
PASS the step leaves nothing of its own behind
Der Schritt baut sich seine eigene Kiste samt Behavior (On update → Move(owner)) statt den
Mover der Fixture zu nehmen — der laeuft ueber die Pfeiltasten, und die sieht der Editor-Lauf
absichtlich nie. Am Ende raeumt er alles wieder weg.
Screenshot 36-editor-run.
Übernommen aus todo-notes/done/execute-behavior-in-editor-mode.md beim Umzug auf das Issue-System (2026-09-12).
Angelegt: 2026-09-09 · ed455f1 — Note down three wishes for the game view
Abgeschlossen: 2026-09-09 · 8f31afa — Let a behavior run while the editor is open
Gemeldet von: admin
ein toggle bei einem behavior object in einer scene (passender name fehlt mir noch):
- wenn der toggle aktiviert ist, soll das behavior außerhalb des play modes trotzdem laufen (sprich immer)
- das behavior ist natürlich nicht aktiv wenn die scene nicht geladen ist wo sich das behavior befindet (sprich genauso wie im play mode, nur ohne play mode)
---
**Umgesetzt (2026-09-09).** Der Schalter heisst **`Run in editor`** und steht im Inspector eines
Behavior-Objekts direkt unter `Enabled`. Ist er an, laeuft das Behavior weiter, waehrend das
Projekt *nicht* spielt (`src/editor/EditorRun.ts`, vom Editor neben der Play-Session getickt).
## Die eine Entscheidung, die der Schalter erzwingt
Play arbeitet auf einer **Wegwerf-Kopie** — deshalb ist Spielen fuer das gespeicherte Projekt
gefahrlos. Ausserhalb von Play gibt es diese Kopie nicht, und damit stand die Frage im Raum, was
ein laufendes Behavior ueberhaupt anfassen darf. Entschieden wurde (Rueckfrage an den User) fuer
die **Unity-Semantik** (`ExecuteInEditMode`):
> Was das Behavior bewegt oder schreibt, ist eine **echte Aenderung am gespeicherten Modell**.
> Sie wird autosaved, die Panels zeigen sie — und **Undo holt sie nicht zurueck**.
Das macht den Schalter maechtig (ein Behavior kann Inhalt bauen oder anordnen) und ist genau der
Grund, warum er **standardmaessig aus** ist. Der E2E-Check haelt beide Haelften fest: der Server
liefert die verschobene Position aus, und nach zwei Undos ist der Schalter weg, die Bewegung nicht.
## Was der Editor-Lauf bewusst *nicht* bekommt
| | |
|---|---|
| **Eingaben** | Tastatur und Maus bleiben beim Editor, sonst wuerde Tippen in einem Textfeld Behaviors ausloesen. `On key …`, `On click` und `Is key down` feuern hier nie; `On start`, `On update`, `On timer` und Kollisionen schon. |
| **Container-Inhalt** | `syncFromModel` schreibt den Inhalt platzierter Container als normale Objekte aus (*baking*) und loescht dabei deren `instanceEdits` — im Editor waere das eine stille, irreversible Aenderung. Der Lauf instanziiert deshalb mit `bakeContainers: false`. **Preis:** ein Behavior *innerhalb* eines platzierten Containers laeuft ausserhalb von Play nicht. |
| **ein zweites Leben** | Nur die Behaviors der **geladenen** Szene laufen, und nur im Edit-Modus. Play stoppt den Editor-Lauf — dort laeuft ohnehin jedes Behavior. Eine Exception im Graphen oder ein `Stop game`-Node beendet den Lauf und schreibt den Grund in die Notice-Zeile, statt ihn 60× pro Sekunde zu wiederholen. |
Der zweite Punkt der Notiz faellt damit von selbst heraus: die Welt wird aus der aktiven Szene
gebaut, ein Behavior einer anderen Szene hat gar keine Entity. Beim Szenenwechsel wird der Lauf
neu aufgebaut oder verworfen.
## Kein Save-Sturm
Ein Behavior, das jeden Frame etwas verschiebt, macht das Modell jeden Frame schmutzig — 60×
pro Sekunde speichern waere die naheliegende Katastrophe. Zwei Dinge verhindern das:
- `syncToModel()` meldet jetzt, **ob** ueberhaupt geschrieben wurde (`{structure, values}` statt
eines blossen `boolean`). Ein Behavior, das nur liest oder wartet, macht gar nichts schmutzig.
- `setSaveStatus('dirty')` emittiert nur bei **Wechsel**, der Autosave-Timer wird also nicht jeden
Frame neu gestellt. Gemessen: **2 Speicherungen in 2 Sekunden**, nicht ~120.
## Ein Darstellungsfehler, den erst der Screenshot gezeigt hat
`schemaForAsset` liefert fuer ein Behavior `COMMON_PROPS + Typschema + Variablen`. Der
Object-Inspector zeigte alles ausser `enabled` unter der Ueberschrift **VARIABLES** — der neue
Schalter landete also dort, wo nur steht, was das Behavior *deklariert*, und die Notiz „The
behavior declares no variables." verschwand fuer immer. Beides ist repariert: die Typschema-Zeilen
eines Behaviors stehen jetzt bei `Enabled`, die Sektion darunter fuehrt wieder nur die Variablen.
Aufgefallen ist es nur, weil ich mir den Screenshot angesehen habe — die Checks waren zufrieden.
## Ein Messgeraet statt eines geratenen Offsets
Der erste Anlauf klickte die Checkbox ueber `locate('Enabled').x + 55`. Das trifft nur Zeilen,
deren Label in die 64-px-Spalte passt — `Run in editor` ist breiter und schiebt seine Checkbox
11 px nach rechts, also ging der Klick daneben und fuenf Checks fielen um. Neu ist deshalb
`__gm.inspectorField(label)`: es liefert die Bildschirmmitte des **Controls** einer Inspector-
Zeile, gefunden ueber sein Label. Damit ist jeder kuenftige Inspector-Check unabhaengig von der
Labelbreite.
## Belegt
Acht Unit-Tests (`tests/editor/editor-run.test.ts`, plus einer in `container.test.ts` fuer das
Nicht-Backen). Gegengeprueft: dreht man den Filter auf „alle Behaviors" und die Szenen-Bedingung
weg, fallen **vier von sieben** um; mit `bakeContainers: true` faellt der Container-Test.
Dazu zehn E2E-Checks in Modul 17:
```
PASS a placed behavior does not run outside play mode until it is asked to
– {"running":false,"time":0,"behaviors":[]} x=0
PASS the inspector offers the switch on a behavior object, with Enabled and above the variables
– {"enabledBox":{"x":1070,"y":221},"runBox":{"x":1081,"y":253},"variables":{…,"y":509.5}}
PASS switching it on is an ordinary override on the object – {"runInEditor":true}
PASS the behavior runs although Play was never pressed
– {"running":true,"time":0.46,"behaviors":["er-logic"]} mode=edit
PASS the owner drifts on, and the moved object is the stored one – x 48.33 → 108.32
PASS what the behavior moved is saved, not just shown – stored x=308.31 (started at 0)
PASS saving stays debounced while it runs, instead of once per frame – 2 saves in 2 s
PASS taking the switch back stops the run and the object stands still – x=329.98
PASS undo takes back the switch, never the movement it caused – overrides={} x=351.65, started at 0
PASS the step leaves nothing of its own behind
```
Der Schritt baut sich seine eigene Kiste samt Behavior (`On update → Move(owner)`) statt den
Mover der Fixture zu nehmen — der laeuft ueber die Pfeiltasten, und die sieht der Editor-Lauf
absichtlich nie. Am Ende raeumt er alles wieder weg.
Screenshot `36-editor-run`.
---
*Übernommen aus `todo-notes/done/execute-behavior-in-editor-mode.md` beim Umzug auf das Issue-System (2026-09-12).*
- **Angelegt:** 2026-09-09 · `ed455f1` — Note down three wishes for the game view
- **Abgeschlossen:** 2026-09-09 · `8f31afa` — Let a behavior run while the editor is open
- **Gemeldet von:** admin
admin
added the todo-note label 2026-09-12 15:03:51 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
ein toggle bei einem behavior object in einer scene (passender name fehlt mir noch):
Umgesetzt (2026-09-09). Der Schalter heisst
Run in editorund steht im Inspector einesBehavior-Objekts direkt unter
Enabled. Ist er an, laeuft das Behavior weiter, waehrend dasProjekt nicht spielt (
src/editor/EditorRun.ts, vom Editor neben der Play-Session getickt).Die eine Entscheidung, die der Schalter erzwingt
Play arbeitet auf einer Wegwerf-Kopie — deshalb ist Spielen fuer das gespeicherte Projekt
gefahrlos. Ausserhalb von Play gibt es diese Kopie nicht, und damit stand die Frage im Raum, was
ein laufendes Behavior ueberhaupt anfassen darf. Entschieden wurde (Rueckfrage an den User) fuer
die Unity-Semantik (
ExecuteInEditMode):Das macht den Schalter maechtig (ein Behavior kann Inhalt bauen oder anordnen) und ist genau der
Grund, warum er standardmaessig aus ist. Der E2E-Check haelt beide Haelften fest: der Server
liefert die verschobene Position aus, und nach zwei Undos ist der Schalter weg, die Bewegung nicht.
Was der Editor-Lauf bewusst nicht bekommt
On key …,On clickundIs key downfeuern hier nie;On start,On update,On timerund Kollisionen schon.syncFromModelschreibt den Inhalt platzierter Container als normale Objekte aus (baking) und loescht dabei dereninstanceEdits— im Editor waere das eine stille, irreversible Aenderung. Der Lauf instanziiert deshalb mitbakeContainers: false. Preis: ein Behavior innerhalb eines platzierten Containers laeuft ausserhalb von Play nicht.Stop game-Node beendet den Lauf und schreibt den Grund in die Notice-Zeile, statt ihn 60× pro Sekunde zu wiederholen.Der zweite Punkt der Notiz faellt damit von selbst heraus: die Welt wird aus der aktiven Szene
gebaut, ein Behavior einer anderen Szene hat gar keine Entity. Beim Szenenwechsel wird der Lauf
neu aufgebaut oder verworfen.
Kein Save-Sturm
Ein Behavior, das jeden Frame etwas verschiebt, macht das Modell jeden Frame schmutzig — 60×
pro Sekunde speichern waere die naheliegende Katastrophe. Zwei Dinge verhindern das:
syncToModel()meldet jetzt, ob ueberhaupt geschrieben wurde ({structure, values}statteines blossen
boolean). Ein Behavior, das nur liest oder wartet, macht gar nichts schmutzig.setSaveStatus('dirty')emittiert nur bei Wechsel, der Autosave-Timer wird also nicht jedenFrame neu gestellt. Gemessen: 2 Speicherungen in 2 Sekunden, nicht ~120.
Ein Darstellungsfehler, den erst der Screenshot gezeigt hat
schemaForAssetliefert fuer ein BehaviorCOMMON_PROPS + Typschema + Variablen. DerObject-Inspector zeigte alles ausser
enabledunter der Ueberschrift VARIABLES — der neueSchalter landete also dort, wo nur steht, was das Behavior deklariert, und die Notiz „The
behavior declares no variables." verschwand fuer immer. Beides ist repariert: die Typschema-Zeilen
eines Behaviors stehen jetzt bei
Enabled, die Sektion darunter fuehrt wieder nur die Variablen.Aufgefallen ist es nur, weil ich mir den Screenshot angesehen habe — die Checks waren zufrieden.
Ein Messgeraet statt eines geratenen Offsets
Der erste Anlauf klickte die Checkbox ueber
locate('Enabled').x + 55. Das trifft nur Zeilen,deren Label in die 64-px-Spalte passt —
Run in editorist breiter und schiebt seine Checkbox11 px nach rechts, also ging der Klick daneben und fuenf Checks fielen um. Neu ist deshalb
__gm.inspectorField(label): es liefert die Bildschirmmitte des Controls einer Inspector-Zeile, gefunden ueber sein Label. Damit ist jeder kuenftige Inspector-Check unabhaengig von der
Labelbreite.
Belegt
Acht Unit-Tests (
tests/editor/editor-run.test.ts, plus einer incontainer.test.tsfuer dasNicht-Backen). Gegengeprueft: dreht man den Filter auf „alle Behaviors" und die Szenen-Bedingung
weg, fallen vier von sieben um; mit
bakeContainers: truefaellt der Container-Test.Dazu zehn E2E-Checks in Modul 17:
Der Schritt baut sich seine eigene Kiste samt Behavior (
On update → Move(owner)) statt denMover der Fixture zu nehmen — der laeuft ueber die Pfeiltasten, und die sieht der Editor-Lauf
absichtlich nie. Am Ende raeumt er alles wieder weg.
Screenshot
36-editor-run.Übernommen aus
todo-notes/done/execute-behavior-in-editor-mode.mdbeim Umzug auf das Issue-System (2026-09-12).ed455f1— Note down three wishes for the game view8f31afa— Let a behavior run while the editor is open