Physik Stufe 0: Rapier einbinden, im Editor laden und messen (Spike zu #144) #145

Closed
opened 2026-09-18 16:45:26 +02:00 by meleki · 1 comment
Owner

Stufe 0 aus #144: Rapier einbinden und messen, bevor Physik v1 darauf baut.

Entscheidungen aus #144 (Kommentar 1108)

  • Library: Rapier 2D (@dimforge/rapier2d-compat).
  • Der Editor lädt Rapier auch, nicht erst der Play-Modus, weil später auch außerhalb von Play simuliert werden soll. Geladen wird trotzdem als eigener Chunk im Hintergrund nach dem Start, damit der erste Bildaufbau des Editors nicht wartet.
  • Einheiten: nach außen Pixel, intern 100 px = 1 m.
  • Vorerst die normale, nicht die deterministische Variante.

Zu bauen

  • Paket als Dependency, ein Lademodul src/runtime/physics/ mit einem einzigen gecachten Ladevorgang (loadPhysics()), Umrechnung px ↔ m an einer Stelle.
  • Der Editor startet den Ladevorgang nach dem Boot. Stand, Ladezeit und Version über den Debug-Hook abfragbar.
  • Schlägt das Laden fehl, steht es in der Console. Der Editor läuft ohne Physik weiter (heute nutzt sie noch nichts).

Messen

  • Größe des Chunks im Build (roh und gzip), Haupt-Bundle unverändert.
  • Ladezeit im Browser (lokal und im CI-Container).
  • Init in vitest (Node).
  • Eine Kiste fällt auf eine Box und bleibt liegen, als Unit-Test gegen die Engine.

Nicht in diesem Issue

Rigidbody-Objekt, Properties, Anbindung an CollisionSystem: das ist Stufe 1.

Stufe 0 aus #144: Rapier einbinden und messen, bevor Physik v1 darauf baut. ## Entscheidungen aus #144 (Kommentar 1108) - Library: **Rapier 2D** (`@dimforge/rapier2d-compat`). - **Der Editor lädt Rapier auch**, nicht erst der Play-Modus, weil später auch außerhalb von Play simuliert werden soll. Geladen wird trotzdem als eigener Chunk im Hintergrund nach dem Start, damit der erste Bildaufbau des Editors nicht wartet. - Einheiten: nach außen Pixel, intern 100 px = 1 m. - Vorerst die normale, nicht die deterministische Variante. ## Zu bauen - Paket als Dependency, ein Lademodul `src/runtime/physics/` mit einem einzigen gecachten Ladevorgang (`loadPhysics()`), Umrechnung px ↔ m an einer Stelle. - Der Editor startet den Ladevorgang nach dem Boot. Stand, Ladezeit und Version über den Debug-Hook abfragbar. - Schlägt das Laden fehl, steht es in der Console. Der Editor läuft ohne Physik weiter (heute nutzt sie noch nichts). ## Messen - Größe des Chunks im Build (roh und gzip), Haupt-Bundle unverändert. - Ladezeit im Browser (lokal und im CI-Container). - Init in vitest (Node). - Eine Kiste fällt auf eine Box und bleibt liegen, als Unit-Test gegen die Engine. ## Nicht in diesem Issue Rigidbody-Objekt, Properties, Anbindung an `CollisionSystem`: das ist Stufe 1.
admin added this to the Development project 2026-09-18 16:58:44 +02:00
admin moved this to Next in Development on 2026-09-18 16:58:55 +02:00
Author
Owner

Erledigt mit d02bcca.

Was drin ist

  • Dependency @dimforge/rapier2d-compat ^0.20.0.
  • src/runtime/physics/engine.ts: loadPhysics() (lädt einmal, alle Aufrufer bekommen dasselbe Ergebnis, ein Fehlschlag wird nicht wiederholt), physicsStatus() (idle / loading / ready mit Ladezeit und Version / failed), PIXELS_PER_METRE = 100 mit toMetres / toPixels.
  • Der Editor lädt Rapier nach dem Öffnen des Projekts im Hintergrund aus einem eigenen Chunk (Antwort 4 in #144), der erste Bildaufbau wartet nicht. Bei einem Fehlschlag steht [physics] … in der Console, der Editor läuft weiter.
  • Debug-Hook __gm.physics().
  • Für den Nutzer ändert sich noch nichts, Rigidbody und Anbindung kommen mit Stufe 1.

Gemessen

Was Ergebnis
Rapier-Chunk 2.117 KB roh, 791,8 KB gzip (Vite)
Haupt-Bundle 264,84 → 265,03 KB gzip (+0,19 KB)
Live über nginx gzip, 804 KB in 0,14 s
Laden + Init, lokal (Chromium) 204 ms
Laden + Init, CI-Container (Task 129) 105 ms
vitest (Node) lädt ohne Zusatzaufwand, keine Warnung
CSP keine gesetzt, WASM braucht keine Header-Änderung

Die Angabe „263 KB“ in #144 kam aus gzip -9; ab jetzt werden nur Vite-Zahlen verglichen.

Tests

  • 4 Unit-Tests in tests/core/physics-engine.test.ts: einmaliges Laden + Version, Umrechnung, freier Fall gegen ½·g·t² (Toleranz 1,5 px, Rapier rechnet Unterschritte), Kiste bleibt auf einer Box liegen.
  • Neues e2e-Modul 41 physics mit 3 Checks: ready ohne Play, eigener Chunk, keine Console-Ausgabe.
  • Gegenproben (ohne Cache, Status bleibt loading, falsche Einheit, statischer Import) wurden alle gefangen.
  • CI zu d02bcca: Task 128 CHECK EXIT 0 (103 Test Files), Task 129 ALL PASSED – 1045 checks, Smokes 24/19/21. Die Summe 1045 ist damit gemessen.

Doku: Wiki Architecture.md (Rapier unter Stack, Ordner src/runtime/physics/), Development.md und README mit der neuen Summe.

Rapier bleibt. Weiter geht es mit Stufe 1 aus #144.

Erledigt mit `d02bcca`. **Was drin ist** - Dependency `@dimforge/rapier2d-compat` ^0.20.0. - `src/runtime/physics/engine.ts`: `loadPhysics()` (lädt einmal, alle Aufrufer bekommen dasselbe Ergebnis, ein Fehlschlag wird nicht wiederholt), `physicsStatus()` (`idle` / `loading` / `ready` mit Ladezeit und Version / `failed`), `PIXELS_PER_METRE = 100` mit `toMetres` / `toPixels`. - Der Editor lädt Rapier nach dem Öffnen des Projekts im Hintergrund aus einem eigenen Chunk (Antwort 4 in #144), der erste Bildaufbau wartet nicht. Bei einem Fehlschlag steht `[physics] …` in der Console, der Editor läuft weiter. - Debug-Hook `__gm.physics()`. - Für den Nutzer ändert sich noch nichts, Rigidbody und Anbindung kommen mit Stufe 1. **Gemessen** | Was | Ergebnis | |---|---| | Rapier-Chunk | 2.117 KB roh, 791,8 KB gzip (Vite) | | Haupt-Bundle | 264,84 → 265,03 KB gzip (+0,19 KB) | | Live über nginx | gzip, 804 KB in 0,14 s | | Laden + Init, lokal (Chromium) | 204 ms | | Laden + Init, **CI-Container** (Task 129) | **105 ms** | | vitest (Node) | lädt ohne Zusatzaufwand, keine Warnung | | CSP | keine gesetzt, WASM braucht keine Header-Änderung | Die Angabe „263 KB“ in #144 kam aus `gzip -9`; ab jetzt werden nur Vite-Zahlen verglichen. **Tests** - 4 Unit-Tests in `tests/core/physics-engine.test.ts`: einmaliges Laden + Version, Umrechnung, freier Fall gegen ½·g·t² (Toleranz 1,5 px, Rapier rechnet Unterschritte), Kiste bleibt auf einer Box liegen. - Neues e2e-Modul 41 `physics` mit 3 Checks: `ready` ohne Play, eigener Chunk, keine Console-Ausgabe. - Gegenproben (ohne Cache, Status bleibt `loading`, falsche Einheit, statischer Import) wurden alle gefangen. - CI zu `d02bcca`: Task 128 `CHECK EXIT 0` (103 Test Files), Task 129 `ALL PASSED – 1045 checks`, Smokes 24/19/21. Die Summe 1045 ist damit gemessen. **Doku:** Wiki `Architecture.md` (Rapier unter Stack, Ordner `src/runtime/physics/`), `Development.md` und README mit der neuen Summe. Rapier bleibt. Weiter geht es mit Stufe 1 aus #144.
admin moved this to Done in Development on 2026-09-18 18:02:15 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#145