While a game runs in the editor, the editor itself keeps up with every frame of it. With many objects spawning and dying this costs more than the behaviors do. The project settings should say how often the editor follows a running game.
Measured
Scene Performance test in cbbf160bb7e8: 200 gold pickups from the crate, each with a Pickup behavior of 97 nodes. Browser profile after the behavior lookup fix (a7e793f):
Share
What
~17 %
A spawn or destroy (here about every 0.1 s) makes Play mirror the structure into the model (PlaySession.tick → syncToModel().structure → state.preview()). That is a full project update: the hierarchy is rebuilt with every gold row, the scene view redraws.
~7 %
state.runtimeTick() refreshes the panels in every frame.
~6 %
world.syncToModel() mirrors the world into the model in every frame.
~13 %
Drawing (Pixi).
~15 %
Behaviors.
fps at the same scene: ~505 entities 23 fps, ~410 entities 40 fps, ~320 entities 48 fps.
The same path exists for the editor run in the scene view (EditorRun, commit(write) and runtimeTick).
Proposal
The game itself always runs every frame. Only what the editor shows about it is throttled. A game started outside the editor is not affected.
New section in Project settings: "While playing"
Hierarchy and structure (spawn, destroy, reparent)
Live: every change, as today.
Throttled: at most N times per second. Changes in between are collected, nothing is lost.
On pause: only when the game is paused or stopped.
Panel values (inspector, variables, bag values, tile maps)
Live: every frame, as today.
Throttled: at most N times per second.
On pause: only when paused or stopped.
Scene view while the game tab is in front
Live / Throttled / Off. Today it redraws with every structure change even when you cannot see it.
Graph and state machine highlight (which node pulsed, which state is active)
Live / Throttled. A pulse that falls between two updates must still flash once, otherwise short pulses vanish.
Rate for Throttled: one number in updates per second, 1 to 30, default 4. One rate for all four, so the dialog stays small.
A preset button above the rows sets all four at once: Live, Balanced (all throttled at 4/s, scene view off behind the game tab), Minimal (all on pause).
Rules that hold in any setting
Pause, step and stop always bring every panel up to date at once. What you inspect while paused is exact.
Selecting an object during a run updates its inspector at once, even if the next throttled update is still due.
The mirror into the model (syncToModel) runs only as often as its readers need it. With everything on On pause it runs only when paused. This is not a setting of its own, it follows from 1 and 2.
Saved in the project file. A project without the section loads as today (Live), so nothing changes until you choose.
The check scripts can set the mode per run, so e2e keeps testing Live and gets its own checks for Throttled and On pause.
Out of scope
Throttling the game, its physics or its behaviors.
A performance overlay (fps, entity count, share per system). Could be its own issue, it would have made this measurement much easier.
Open questions
Default for new projects:Live as today, or Balanced? (proposal: Balanced for new projects, Live for existing ones, because a throttled hierarchy is a visible change for a project that already works.)
Per area or preset only?(proposal: preset plus the four rows as above. If that is too much, only the preset.)
Hierarchy on Throttled: with hundreds of spawned objects, should spawned objects appear folded as one group row ("Gold × 200") instead of 200 rows? (proposal: not in this issue. First measure what the throttle alone brings.)
While a game runs in the editor, the editor itself keeps up with every frame of it. With many objects spawning and dying this costs more than the behaviors do. The project settings should say how often the editor follows a running game.
## Measured
Scene `Performance test` in `cbbf160bb7e8`: 200 gold pickups from the crate, each with a Pickup behavior of 97 nodes. Browser profile after the behavior lookup fix (`a7e793f`):
| Share | What |
|---|---|
| ~17 % | A spawn or destroy (here about every 0.1 s) makes Play mirror the structure into the model (`PlaySession.tick` → `syncToModel().structure` → `state.preview()`). That is a full project update: the hierarchy is rebuilt with every gold row, the scene view redraws. |
| ~7 % | `state.runtimeTick()` refreshes the panels in every frame. |
| ~6 % | `world.syncToModel()` mirrors the world into the model in every frame. |
| ~13 % | Drawing (Pixi). |
| ~15 % | Behaviors. |
fps at the same scene: ~505 entities 23 fps, ~410 entities 40 fps, ~320 entities 48 fps.
The same path exists for the editor run in the scene view (`EditorRun`, `commit(write)` and `runtimeTick`).
## Proposal
The game itself always runs every frame. Only what the editor shows about it is throttled. A game started outside the editor is not affected.
### New section in Project settings: "While playing"
1. **Hierarchy and structure** (spawn, destroy, reparent)
- *Live*: every change, as today.
- *Throttled*: at most N times per second. Changes in between are collected, nothing is lost.
- *On pause*: only when the game is paused or stopped.
2. **Panel values** (inspector, variables, bag values, tile maps)
- *Live*: every frame, as today.
- *Throttled*: at most N times per second.
- *On pause*: only when paused or stopped.
3. **Scene view** while the game tab is in front
- *Live* / *Throttled* / *Off*. Today it redraws with every structure change even when you cannot see it.
4. **Graph and state machine highlight** (which node pulsed, which state is active)
- *Live* / *Throttled*. A pulse that falls between two updates must still flash once, otherwise short pulses vanish.
5. **Rate** for *Throttled*: one number in updates per second, 1 to 30, default 4. One rate for all four, so the dialog stays small.
A preset button above the rows sets all four at once: **Live**, **Balanced** (all throttled at 4/s, scene view off behind the game tab), **Minimal** (all on pause).
### Rules that hold in any setting
- Pause, step and stop always bring every panel up to date at once. What you inspect while paused is exact.
- Selecting an object during a run updates its inspector at once, even if the next throttled update is still due.
- The mirror into the model (`syncToModel`) runs only as often as its readers need it. With everything on *On pause* it runs only when paused. This is not a setting of its own, it follows from 1 and 2.
- Saved in the project file. A project without the section loads as today (*Live*), so nothing changes until you choose.
- The check scripts can set the mode per run, so e2e keeps testing *Live* and gets its own checks for *Throttled* and *On pause*.
### Out of scope
- Throttling the game, its physics or its behaviors.
- A performance overlay (fps, entity count, share per system). Could be its own issue, it would have made this measurement much easier.
## Open questions
1. **Default for new projects:** *Live* as today, or *Balanced*? *(proposal: Balanced for new projects, Live for existing ones, because a throttled hierarchy is a visible change for a project that already works.)*
2. **Per area or preset only?** *(proposal: preset plus the four rows as above. If that is too much, only the preset.)*
3. **Hierarchy on *Throttled*:** with hundreds of spawned objects, should spawned objects appear folded as one group row ("Gold × 200") instead of 200 rows? *(proposal: not in this issue. First measure what the throttle alone brings.)*
balanced klingt gut, für alle projekte (auch die vorhandenen)
preset only (keine weitere konfiguration)
auch gleich in dem issue mitmachen: objects die spawnen im root (also ohne parent) in eine Gruppe "{Assetname}" packen (wenn nicht vorhanden => automatisch anlegen)
1. balanced klingt gut, für alle projekte (auch die vorhandenen)
2. preset only (keine weitere konfiguration)
3. auch gleich in dem issue mitmachen: objects die spawnen im root (also ohne parent) in eine Gruppe "{Assetname}" packen (wenn nicht vorhanden => automatisch anlegen)
Umgesetzt in 94c1055 (Wiki: 68c8798). Davor liegt a7e793f, der Cache im Behavior-Interpreter, der die Behaviors selbst schneller macht.
Was es jetzt gibt
Project settings → While playing mit den Presets Live, Balanced und Minimal, wie beantwortet ohne Einzelzeilen. Alle Projekte, auch die alten, laden als Balanced.
Balanced: Hierarchie und Panel-Werte 4× pro Sekunde, der Scene-View hinter dem Game-Tab zeichnet erst wieder, wenn er sichtbar wird.
Minimal: Hierarchie und Werte nur bei Pause, Graph-Tabs 4× pro Sekunde.
Das Spiel wird nie gedrosselt. Pause, Step und Stop bringen alles sofort auf den aktuellen Stand, eine Strukturänderung zwischen zwei Updates geht nicht verloren.
Gespawnte Root-Objekte landen in einer Gruppe „{Assetname}“ (z. B. „Gold“), zugeklappt. Gespawnte Kinder bleiben unter ihrem Parent.
Abweichung vom Vorschlag
Unter Balanced laufen Graph- und State-Machine-Tab live. Bei 4 Updates pro Sekunde ruckeln die Perlen auf den Exec-Kanten sichtbar (zwei Checks in e2e 18 sind daran gefallen), und die Tabs zeichnen nur, wenn sie sichtbar sind. In der Messung waren sie nie ein Kostenpunkt. Gedrosselt werden sie nur unter Minimal.
Gemessen an „Performance test“ (Wegwerf-Kopie, je 3 s, fps)
p95 der Frame-Zeit bei ~500 Entities: 60 ms (Live), 41 ms (Balanced), 23 ms (Minimal).
Tests
./check.sh: 193 Dateien, 2799 Tests, grün.
Voller e2e-Lauf lokal: 1562 Checks, grün. Neues Modul 59 (Preset per Maus, Update-Raten, Scene-View hinter dem Game-Tab, Minimal mit Pause).
Gegenproben: 4 Unit, 2 Browser, alle greifen.
Umgesetzt in 94c1055 (Wiki: 68c8798). Davor liegt a7e793f, der Cache im Behavior-Interpreter, der die Behaviors selbst schneller macht.
## Was es jetzt gibt
- **Project settings → While playing** mit den Presets **Live**, **Balanced** und **Minimal**, wie beantwortet ohne Einzelzeilen. Alle Projekte, auch die alten, laden als **Balanced**.
- **Balanced:** Hierarchie und Panel-Werte 4× pro Sekunde, der Scene-View hinter dem Game-Tab zeichnet erst wieder, wenn er sichtbar wird.
- **Minimal:** Hierarchie und Werte nur bei Pause, Graph-Tabs 4× pro Sekunde.
- Das Spiel wird nie gedrosselt. Pause, Step und Stop bringen alles sofort auf den aktuellen Stand, eine Strukturänderung zwischen zwei Updates geht nicht verloren.
- **Gespawnte Root-Objekte landen in einer Gruppe „{Assetname}“** (z. B. „Gold“), zugeklappt. Gespawnte Kinder bleiben unter ihrem Parent.
## Abweichung vom Vorschlag
Unter **Balanced** laufen Graph- und State-Machine-Tab **live**. Bei 4 Updates pro Sekunde ruckeln die Perlen auf den Exec-Kanten sichtbar (zwei Checks in e2e 18 sind daran gefallen), und die Tabs zeichnen nur, wenn sie sichtbar sind. In der Messung waren sie nie ein Kostenpunkt. Gedrosselt werden sie nur unter Minimal.
## Gemessen an „Performance test“ (Wegwerf-Kopie, je 3 s, fps)
| Entities | vor a7e793f | Live | Balanced | Minimal |
|---|---|---|---|---|
| ~500 | 23 | 38,6 | **56** | 60,6 |
| ~410 | 40 | 50,2 | **59,5** | 60,9 |
| ~315 | 48 | 56,9 | **60,5** | 60,6 |
p95 der Frame-Zeit bei ~500 Entities: 60 ms (Live), 41 ms (Balanced), 23 ms (Minimal).
## Tests
- `./check.sh`: 193 Dateien, 2799 Tests, grün.
- Voller e2e-Lauf lokal: 1562 Checks, grün. Neues Modul 59 (Preset per Maus, Update-Raten, Scene-View hinter dem Game-Tab, Minimal mit Pause).
- Gegenproben: 4 Unit, 2 Browser, alle greifen.
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.
While a game runs in the editor, the editor itself keeps up with every frame of it. With many objects spawning and dying this costs more than the behaviors do. The project settings should say how often the editor follows a running game.
Measured
Scene
Performance testincbbf160bb7e8: 200 gold pickups from the crate, each with a Pickup behavior of 97 nodes. Browser profile after the behavior lookup fix (a7e793f):PlaySession.tick→syncToModel().structure→state.preview()). That is a full project update: the hierarchy is rebuilt with every gold row, the scene view redraws.state.runtimeTick()refreshes the panels in every frame.world.syncToModel()mirrors the world into the model in every frame.fps at the same scene: ~505 entities 23 fps, ~410 entities 40 fps, ~320 entities 48 fps.
The same path exists for the editor run in the scene view (
EditorRun,commit(write)andruntimeTick).Proposal
The game itself always runs every frame. Only what the editor shows about it is throttled. A game started outside the editor is not affected.
New section in Project settings: "While playing"
A preset button above the rows sets all four at once: Live, Balanced (all throttled at 4/s, scene view off behind the game tab), Minimal (all on pause).
Rules that hold in any setting
syncToModel) runs only as often as its readers need it. With everything on On pause it runs only when paused. This is not a setting of its own, it follows from 1 and 2.Out of scope
Open questions
Umgesetzt in
94c1055(Wiki: 68c8798). Davor liegta7e793f, der Cache im Behavior-Interpreter, der die Behaviors selbst schneller macht.Was es jetzt gibt
Abweichung vom Vorschlag
Unter Balanced laufen Graph- und State-Machine-Tab live. Bei 4 Updates pro Sekunde ruckeln die Perlen auf den Exec-Kanten sichtbar (zwei Checks in e2e 18 sind daran gefallen), und die Tabs zeichnen nur, wenn sie sichtbar sind. In der Messung waren sie nie ein Kostenpunkt. Gedrosselt werden sie nur unter Minimal.
Gemessen an „Performance test“ (Wegwerf-Kopie, je 3 s, fps)
a7e793fp95 der Frame-Zeit bei ~500 Entities: 60 ms (Live), 41 ms (Balanced), 23 ms (Minimal).
Tests
./check.sh: 193 Dateien, 2799 Tests, grün.