Aus #265 („Out of scope: A performance overlay (fps, entity count, share per system). Could be its own issue, it would have made this measurement much easier.“).
Befund
Die Toolbar zeigt die Bildrate (src/editor/panels/Toolbar.ts:90, gemessen in Editor.measureFps, src/editor/Editor.ts:924).
Wie viele Objekte gerade laufen und wohin die Zeit eines Frames geht (Behaviors, Physik, Zeichnen, Spiegeln ins Modell, Panels), sieht man nicht. Für #265 brauchte es dafür ein Browser-Profil der Szene Performance test.
Zu bauen (Vorschlag)
Ein Overlay über der Game View, ein- und ausschaltbar in der Kopfzeile des Game-Tabs. Es zeigt fps, die Zahl der Entities und je Bereich die mittlere Zeit pro Frame in ms: Behaviors, Physik, Zeichnen, Editor-Anteil.
Gemessen mit performance.now() um die Schritte in GameRun.tick (src/runtime/GameRun.ts:39) und PlaySession.tick (src/editor/PlaySession.ts:223), gemittelt über 0,5 s wie die fps.
Tests: Unit für die Mittelung, e2e: Overlay an, die Werte erscheinen, die Zahl der Entities stimmt mit __gm.world() überein.
Offen (mit Vorschlag)
Ort: Overlay über dem Spiel oder eine Zeile in der Kopfzeile? Vorschlag: Overlay oben links, halbtransparent, standardmäßig aus.
Auch beim Run in der Scene View? Vorschlag: zuerst nur Play.
Aus #265 („Out of scope: A performance overlay (fps, entity count, share per system). Could be its own issue, it would have made this measurement much easier.“).
## Befund
- Die Toolbar zeigt die Bildrate (`src/editor/panels/Toolbar.ts:90`, gemessen in `Editor.measureFps`, `src/editor/Editor.ts:924`).
- Wie viele Objekte gerade laufen und wohin die Zeit eines Frames geht (Behaviors, Physik, Zeichnen, Spiegeln ins Modell, Panels), sieht man nicht. Für #265 brauchte es dafür ein Browser-Profil der Szene *Performance test*.
## Zu bauen (Vorschlag)
- Ein Overlay über der Game View, ein- und ausschaltbar in der Kopfzeile des Game-Tabs. Es zeigt fps, die Zahl der Entities und je Bereich die mittlere Zeit pro Frame in ms: Behaviors, Physik, Zeichnen, Editor-Anteil.
- Gemessen mit `performance.now()` um die Schritte in `GameRun.tick` (`src/runtime/GameRun.ts:39`) und `PlaySession.tick` (`src/editor/PlaySession.ts:223`), gemittelt über 0,5 s wie die fps.
- Nur im Editor, die Spielseite (#266) bleibt ohne.
- Tests: Unit für die Mittelung, e2e: Overlay an, die Werte erscheinen, die Zahl der Entities stimmt mit `__gm.world()` überein.
## Offen (mit Vorschlag)
1. **Ort:** Overlay über dem Spiel oder eine Zeile in der Kopfzeile? Vorschlag: Overlay oben links, halbtransparent, standardmäßig aus.
2. **Auch beim Run in der Scene View?** Vorschlag: zuerst nur Play.
meleki
added the new label 2026-09-29 18:26:30 +02:00
Done in 77f4c2c, wiki 9d65087 (Concepts, Architecture, Development). Built as decided in the comment above: overlay top left, Game View only.
What you get
The Game tab header has a Performance switch next to the scale. It shows an overlay in the top left corner of the Game View, half transparent and off by default.
The overlay only shows while a game runs. Clicks go through it to the game.
It shows fps, the number of entities and the mean time per frame in ms, averaged over 0.5 s like the fps counter:
60 fps · 7 entities
Behaviors 0.10 ms
Physics 0.13 ms
Animation 0.00 ms
Drawing 0.49 ms
Editor 0.11 ms
In the first half second of a run it shows dashes instead of numbers.
The switch is not saved and holds until the page is reloaded. The released game (#266) has no overlay and runs without a meter.
Different from the proposal
Animation has its own line. The AnimationSystem is a system of its own, and counting it under Behaviors would have skewed that number.
Drawing is the build of the game picture (GameViewport.redraw) plus app.render(). It is main thread time only. The GPU work after it is not in the number, and app.render() draws the whole canvas including the panels.
Editor is the rest of the editor tick after the systems and the game picture: mirroring into the model, panels and console.
Under the hood
src/editor/frameMeter.ts holds the pure rule: FrameMeter and the lines of the overlay.
World.timeSystem times every system the world ticks. PlaySession maps the systems to the three areas and sets the hook again after Load scene.
The overlay is src/editor/viewport/PerformanceOverlay.ts, fed from Editor.tick.
Tests
unit frame-meter 9 passed, all new
gate (melektaus-atx) 197 files, 2853 tests, CHECK EXIT 0
e2e 59 (melektaus-atx) ALL PASSED - 18 checks, 5 new (59e), run twice
59e uses the real mouse on the switch: no overlay without a running game, the overlay appears top left while playing, the entity count matches __gm.world() (7), five lines with numbers and Drawing above 0, a second click hides it again.
Counter-checks work: an editor share that does not subtract the systems fails 2 unit tests. Systems running in pause that are not reported fail 1. An overlay that gets no times fails 59e.
Chromium rounds performance.now() to 0.1 ms. The mean over about 30 frames smooths that out.
The e2e total of 1601 is counted (1596 + 5). The CI run for 77f4c2c was not waited for.
Done in `77f4c2c`, wiki `9d65087` (*Concepts*, *Architecture*, *Development*). Built as decided in the comment above: overlay top left, Game View only.
**What you get**
- The Game tab header has a **Performance** switch next to the scale. It shows an overlay in the top left corner of the Game View, half transparent and off by default.
- The overlay only shows while a game runs. Clicks go through it to the game.
- It shows fps, the number of entities and the mean time per frame in ms, averaged over 0.5 s like the fps counter:
```
60 fps · 7 entities
Behaviors 0.10 ms
Physics 0.13 ms
Animation 0.00 ms
Drawing 0.49 ms
Editor 0.11 ms
```
- In the first half second of a run it shows dashes instead of numbers.
- The switch is not saved and holds until the page is reloaded. The released game (#266) has no overlay and runs without a meter.
**Different from the proposal**
- **Animation has its own line.** The `AnimationSystem` is a system of its own, and counting it under Behaviors would have skewed that number.
- **Drawing** is the build of the game picture (`GameViewport.redraw`) plus `app.render()`. It is main thread time only. The GPU work after it is not in the number, and `app.render()` draws the whole canvas including the panels.
- **Editor** is the rest of the editor tick after the systems and the game picture: mirroring into the model, panels and console.
**Under the hood**
- `src/editor/frameMeter.ts` holds the pure rule: `FrameMeter` and the lines of the overlay.
- `World.timeSystem` times every system the world ticks. `PlaySession` maps the systems to the three areas and sets the hook again after `Load scene`.
- The overlay is `src/editor/viewport/PerformanceOverlay.ts`, fed from `Editor.tick`.
**Tests**
```
unit frame-meter 9 passed, all new
gate (melektaus-atx) 197 files, 2853 tests, CHECK EXIT 0
e2e 59 (melektaus-atx) ALL PASSED - 18 checks, 5 new (59e), run twice
```
- 59e uses the real mouse on the switch: no overlay without a running game, the overlay appears top left while playing, the entity count matches `__gm.world()` (7), five lines with numbers and Drawing above 0, a second click hides it again.
- Counter-checks work: an editor share that does not subtract the systems fails 2 unit tests. Systems running in pause that are not reported fail 1. An overlay that gets no times fails 59e.
- Chromium rounds `performance.now()` to 0.1 ms. The mean over about 30 frames smooths that out.
- The e2e total of 1601 is counted (1596 + 5). The CI run for `77f4c2c` was not waited for.
The overlay has a new top line, Possible. It shows the frame rate the measured work would allow if nothing waited for the display. The fps line below it stops at the display's rate (60 on most screens), this one does not.
Possible 1200 fps
60 fps · 7 entities
Behaviors 0.10 ms
Physics 0.14 ms
Animation 0.00 ms
Drawing 0.51 ms
Editor 0.09 ms
(measured in the e2e run on melektaus-atx)
It is 1000 ms over the sum of the five times, rounded down. In the example that is 0.84 ms, so 1200 fps.
It is an upper bound: the GPU's time is not measured and not in it. In scenes that are heavy to draw, the real limit is lower.
The Editor share is in the sum, because it costs time while playing in the editor. A released game can do a little better.
In the first half second of a run it shows – fps, like the other lines.
Under the hood
possibleFps in src/editor/frameMeter.ts, used by performanceLines.
e2e 59: ALL PASSED, 19 checks (+1). The new check computes the number from the measured times itself and compares it with the line (1200 = 1200).
Counter-check: when possibleFps leaves out the editor's share, the unit test fails.
The e2e total of 1602 is counted (1601 + 1). I did not wait for the CI run of f14c4ec.
## Follow-up: the possible frame rate
Commit `f14c4ec`, wiki `6413fa5`.
### What you get
The overlay has a new top line, **Possible**. It shows the frame rate the measured work would allow if nothing waited for the display. The fps line below it stops at the display's rate (60 on most screens), this one does not.
```
Possible 1200 fps
60 fps · 7 entities
Behaviors 0.10 ms
Physics 0.14 ms
Animation 0.00 ms
Drawing 0.51 ms
Editor 0.09 ms
```
(measured in the e2e run on `melektaus-atx`)
- It is **1000 ms over the sum of the five times**, rounded down. In the example that is 0.84 ms, so 1200 fps.
- It is an **upper bound**: the GPU's time is not measured and not in it. In scenes that are heavy to draw, the real limit is lower.
- The **Editor** share is in the sum, because it costs time while playing in the editor. A released game can do a little better.
- In the first half second of a run it shows `– fps`, like the other lines.
### Under the hood
- `possibleFps` in `src/editor/frameMeter.ts`, used by `performanceLines`.
### Tests
- Unit `frame-meter`: 11 passed (+2 for `possibleFps`)
- Gate: 197 files, 2855 tests, `CHECK EXIT 0` (2853 + 2)
- e2e 59: ALL PASSED, 19 checks (+1). The new check computes the number from the measured times itself and compares it with the line (1200 = 1200).
- Counter-check: when `possibleFps` leaves out the editor's share, the unit test fails.
- The e2e total of 1602 is counted (1601 + 1). I did not wait for the CI run of `f14c4ec`.
admin
moved this to Done in Development on 2026-09-30 21:00:52 +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.
Aus #265 („Out of scope: A performance overlay (fps, entity count, share per system). Could be its own issue, it would have made this measurement much easier.“).
Befund
src/editor/panels/Toolbar.ts:90, gemessen inEditor.measureFps,src/editor/Editor.ts:924).Zu bauen (Vorschlag)
performance.now()um die Schritte inGameRun.tick(src/runtime/GameRun.ts:39) undPlaySession.tick(src/editor/PlaySession.ts:223), gemittelt über 0,5 s wie die fps.__gm.world()überein.Offen (mit Vorschlag)
Done in
77f4c2c, wiki9d65087(Concepts, Architecture, Development). Built as decided in the comment above: overlay top left, Game View only.What you get
Different from the proposal
AnimationSystemis a system of its own, and counting it under Behaviors would have skewed that number.GameViewport.redraw) plusapp.render(). It is main thread time only. The GPU work after it is not in the number, andapp.render()draws the whole canvas including the panels.Under the hood
src/editor/frameMeter.tsholds the pure rule:FrameMeterand the lines of the overlay.World.timeSystemtimes every system the world ticks.PlaySessionmaps the systems to the three areas and sets the hook again afterLoad scene.src/editor/viewport/PerformanceOverlay.ts, fed fromEditor.tick.Tests
__gm.world()(7), five lines with numbers and Drawing above 0, a second click hides it again.performance.now()to 0.1 ms. The mean over about 30 frames smooths that out.77f4c2cwas not waited for.Follow-up: the possible frame rate
Commit
f14c4ec, wiki6413fa5.What you get
The overlay has a new top line, Possible. It shows the frame rate the measured work would allow if nothing waited for the display. The fps line below it stops at the display's rate (60 on most screens), this one does not.
(measured in the e2e run on
melektaus-atx)– fps, like the other lines.Under the hood
possibleFpsinsrc/editor/frameMeter.ts, used byperformanceLines.Tests
frame-meter: 11 passed (+2 forpossibleFps)CHECK EXIT 0(2853 + 2)possibleFpsleaves out the editor's share, the unit test fails.f14c4ec.