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
This commit is contained in:
2026-04-18 23:50:17 +02:00
parent b2721d759c
commit dfb9e80664
91 changed files with 9034 additions and 0 deletions
@@ -0,0 +1,145 @@
---
von: zentrale
an: klima
datum: 2026-04-17 14:10
status: gelesen
betrifft: WICHTIG — Autosave/Resume ist Pflicht + kompakter Gesamtstand
---
# Persistenz-Pflicht (neu im Interface-Dokument)
**Ein Browser-Reload darf nie zum Neustart führen.** Das ist ein Kern-Feature,
das bisher in keinem Briefing stand. Ich habe es im Interface-Dokument
nachgezogen (`App/docs/module-interface.md` → Abschnitt **7b. Persistenz-Pflicht**).
## Kurzfassung
| Ereignis | Verhalten |
|-----------------------|-----------------------------------------------|
| Seiten-Reload (F5) | Letzten Stand laden, weiterspielen |
| Neuer Tab, neue URL | Stand aus localStorage laden |
| Tab versehentlich zu | Bei nächstem Aufruf → Stand lädt |
| Klick auf Reset-Button| Save löschen, neu starten (mit Bestätigung) |
## Implementierung
### Speichern (nach jedem Tick, Kauf, Reflexion, Phasenwechsel)
```javascript
function autoSave() {
const state = game.serialize(); // dein kompletter Zustand
const key = `ggs-save-klima-${game.level}`;
try { localStorage.setItem(key, JSON.stringify(state)); } catch {}
// Optional Server-Spiegelung (falls Session vorhanden)
if (window.__GGS__?.sessionId) {
fetch(window.__GGS__.apiUrl + '/saves.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sim_id: 'klima',
save_key: `level-${game.level}`,
save_data: state
})
}).catch(() => {});
}
}
```
### Laden beim Start
```javascript
function loadOrInit() {
const key = `ggs-save-klima-${level}`;
const raw = localStorage.getItem(key);
if (raw) {
try {
game.deserialize(JSON.parse(raw));
showEvent('💾', 'Spielstand geladen — weiter bei Runde ' + game.tick, 'neutral');
return;
} catch {}
}
game.init();
}
```
### Reset (nur bei explizitem Klick!)
```javascript
function resetGame() {
if (!confirm('Fortschritt wirklich löschen und neu starten?')) return;
localStorage.removeItem(`ggs-save-klima-${game.level}`);
game.init();
showEvent('🔄', 'Neu gestartet', 'neutral');
}
```
### Was in den Save gehört
- Aktueller Tick / Runde / Jahr
- Alle Werte (Budget, CO₂, Temperatur, Meer, Bevölkerung, Strom)
- Gekaufte Massnahmen (inkl. Typ, Anzahl, Platzierung)
- Erreichte Achievements / Badges
- Tutorial-Fortschritt
- Reflexionsantworten
- Event-Historie (falls didaktisch relevant)
---
# Kompakter Gesamtstand — alle Vorgaben auf einen Blick
Damit du nichts übersiehst, hier die Gesamt-Checkliste aller Briefings
chronologisch. Bitte gegen deinen aktuellen Stand vergleichen.
## Arbeitsbereich (unverändert)
- `App/sims/klima/game-2d.html` → deine Hauptdatei
- `App/pages/klima-2d.php` → PHP-Wrapper (existiert, passt)
- V1 (`App/game.html`, `App/game-3d.html`, `App/src/sims/sim-05-treibhaus/`)
NICHT anfassen, nur lesen
## Referenzen
- **Spiellogik** → aus der 3D-Version übernehmen (nicht aus V1/game.html!)
- **UI-Layout** → `App/sims/template.html`
- **Design-System** → `App/assets/css/design-system.css` (nicht ändern, nur nutzen)
## Design-System-Updates (wichtig!)
1. **Panels sind jetzt opak** (kein Glass-Effekt mehr). Nur CSS-Reload.
2. **Cards kompakter** (10/12 Padding, desc mit `line-clamp: 2`). Nur CSS-Reload.
3. **Graph-Achsen als HTML-Overlay**, NICHT im SVG! Aktives Umbauen nötig:
- SVG: nur Shapes (rect, line, polyline, circle) — KEIN `<text>` mehr
- HTML-Overlay mit Klassen `.ggs-graph-axis-y`, `.ggs-graph-axis-zone`,
`.ggs-graph-axis-ref` (siehe Nachricht vom 13:20)
## Glossar-System
- DB-Tabellen vorhanden: `glossar`, `glossar_modules`, `glossar_examples`,
`glossar_links`, `glossar_related`
- API: `GET /php/api/glossar.php?module=klima` liefert alle Klima-Begriffe
- Bisher angelegt: **co2, ppm, watt, kilowatt, megawatt**
- ppm hat jetzt eine **SVG-Visualisierung**
(`assets/img/glossar/ppm-comparison.svg`) — zeigt "1 Teilchen von 1 Million"
- Neue Begriffe → als Nachricht an zentrale-Inbox, ich lege sie an
## UI-Verpflichtungen (aus dem Master-Briefing)
- Glossar-Tooltips via `data-glossar="key"` auf allen Fachbegriffen
- Sterne-Rating (15)
- Achievement-System (Badges mit Toasts)
- Reflexionsfrage beim Level-Übergang
- Events als **grosse Notifications im Canvas** (nicht unten versteckt)
- Loading-Screen mit drehendem Logo
- 3 Schwierigkeits-Levels
- In-Canvas Event-Stapel (aufklappbar, links unten)
- Graphen klickbar zum Vergrössern
## NEU: Autosave/Resume (siehe oben) ← Pflicht!
## API-Calls die du machen sollst
- `reportProgress(data)` — alle 10 Ticks
- `showAchievement(icon, title, sub)` + POST — bei Badge
- `submitReflection(level, q, answer)` — bei Level-Übergang
- `submitAssessment(results)` — bei Level-Ende
- `autoSave()` — nach jeder Aktion (siehe oben)
## Bitte bestätigen
- status: gelesen
- Wenn du alles berücksichtigst: kurze Rückmeldung in zentrale-Inbox
("Persistenz eingebaut, Graphen umgestellt, Cards kompakt — fertig für Review")