Files
geograsim/App/sims/_inbox/zentrale/2026-04-18-2245-klima-engine-schritt-1-2-fertig.md
Adminator dfb9e80664 Klima: Engine extrahiert + 2D refactored + Drama-Track + Bugfixes
- engine.js als headless Single Source of Truth (KlimaEngine)
- game-2d.html nutzt engine (-515 Zeilen Duplikation)
- rising-pressure.mp3 als Drama-Slot, Auto-Switch bei kritischem State
- state.animMs: alle Animationen bei Pause eingefroren, Speed skaliert
- Pro-Haus-Schornstein-Abbau je nach Erneuerbaren-Anteil
- Bugfix: Bürger-Dialog überlebt Refresh via pendingCitizenEventId
- Toast-Viewport volle Canvas-Breite, Musik-Default 22 %
- _status.md Konvention eingeführt, Inbox-Nachrichten erhalten
2026-04-18 23:50:17 +02:00

76 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
von: klima
an: atlas
datum: 2026-04-18 22:45
status: neu
betrifft: Engine-Refactor — Schritt 1 + 2 durch, Schritt 3-5 in Übergabe
---
# Zwischenstand: Engine + 2D-Umstellung fertig
## Fertig
### Schritt 1 — `App/sims/klima/engine.js`
Headless-Engine als `window.KlimaEngine` — keine DOM-Aufrufe, keine
kwAudio, kein fetch. Enthält alle Regel-Konstanten (`MEASURES`,
`DIFFICULTY`, `ACHIEVEMENTS`, `CITIZEN_EVENTS`, `FIRST_BUY_HINTS`,
`CO2_FLOOR`, `TEMP_FLOOR`) und die komplette Spiellogik (Tick, Kauf/
Abriss, Klima-Physik, Bürger-Events, Achievements, Serialize/
Deserialize).
API:
const game = KlimaEngine.createGame(levelId, { levelConfig });
const result = KlimaEngine.tick(game);
// result = { newEvents, unlockedAchievements, citizenEvent, endReason, timelineSample }
KlimaEngine.buyMeasure(game, id, { resolveMeta, forceNegBalance });
KlimaEngine.applyCitizenChoice(game, eventId, choiceIdx, { resolveMeta });
KlimaEngine.serialize(game); KlimaEngine.deserialize(data);
Event-Emission läuft über `game._pendingEvents` / `_pendingAchievements`,
pro Aufruf gedraint — die View bekommt genau die Events dieses Aufrufs
zurück (für Toast, Sound, Overlay) und kann sie rendern, ohne eine
zweite `state.events`-Mutation zu triggern.
### Schritt 2 — `App/sims/klima/game-2d.html`
Alle Regel-Konstanten sind jetzt Aliases auf `KlimaEngine.*`. Alle
Logik-Funktionen sind dünne UI-Wrapper:
- `state` ist eine Engine-Instanz (`let state = KlimaEngine.createGame(1)`)
+ View-Flags via Object.assign
- `simulateTick`, `buyMeasure`, `demolishMeasure`, `triggerCitizenDialog`
→ Engine-Wrapper
- `serializeState` / `deserializeState` delegieren
- `showEvent` wurde geteilt in `showEventUI` (nur Toast/Sound, für
Engine-Events) und `showEvent` (pusht + UI, für Legacy-Pfade wie
"Budget zu niedrig" Toast und "Save geladen" Hinweis)
- `resolveMeta: () => ({ pos: pickBuildPosition(id) })` — Engine spreizt
die Extra-Daten in das Instance-Objekt, sodass der Canvas-Draw-Code
(`inst.pos.x/y`) unverändert läuft und alte Saves rückwärtskompatibel
geladen werden
Lines game-2d.html: 4552 → 4037 (515 durch entfernte Duplikate).
### Sonstige 2D-Verbesserungen im selben Zug
- Toast-Viewport volle Canvas-Breite (10px Rand), kompakteres Padding
- Hintergrundmusik: Default 22 %, Auto-Start bei erster User-Geste
- Häuser mit Schornstein-Rauchfahne, abhängig von
`renewablePower / powerDemand` (100 % erneuerbar → kein Rauch)
- Flughafen-Helikopter fliegt jetzt (statt zu parken): 26-34 s Zyklus
pro Airport, mehrheitlich Flug + gelegentliches Pad-Parken
## Offen: Schritt 3-5
In `_inbox/klima/2026-04-18-2240-handover-engine-steps3-5.md` liegt die
Übergabe-Notiz mit Detail-Plan für die nächste Session. Schritt 3 (3D V2)
ist der dicke Brocken und will eine eigene Session.
## Bestätigen
- status: gelesen
- Keine Rückmeldung nötig — Thomas testet parallel, wenn etwas in 2D
regrediert ist, meldet er es direkt