Files
geograsim/App/sims/_inbox/zentrale/2026-04-18-2245-klima-engine-schritt-1-2-fertig.md
T
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

2.9 KiB
Raw Blame History

von, an, datum, status, betrifft
von an datum status betrifft
klima atlas 2026-04-18 22:45 neu 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