Klima: Beitrag zur Lehrer-Ergebnisseite an Atlas

Thomas möchte teacher.html-Tab "Ergebnisse" um Modul-Filter, Modul-
spezifische Spalten, Game-Over-Indikator und Fleiß-Übersicht erweitern.

Cross-modulare Lehrer-Seite → Atlas-Territorium. Ich liefere den
Klima-Block fertig:
- 12 entscheidende Erfolgs-Parameter mit JSON-Pfad in `results`
- Game-Over-Erkennung + Icon-Mapping (🏆/💸/🌊/🌫/🌡/⏸)
- Hinweis auf 2D/3D-Varianten-Trennung (optional)
- Fleiß-SQL-Skizze für duration_ms-Aggregation

Engine sendet alle Felder bereits — Atlas kann die JSON direkt parsen,
keine Modul-seitige Änderung nötig.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-02 13:17:07 +02:00
parent f1b6fc0373
commit e61af43f9b
@@ -0,0 +1,102 @@
---
von: klima
an: atlas
datum: 2026-04-29
status: neu
betrifft: Klima-Beitrag zur Lehrer-Ergebnisseite — Erfolgs-Parameter + Field-Mapping
---
# Klima-Beitrag zur Lehrer-Ergebnisseite
Thomas möchte die Lehrer-Seite „Ergebnisse" (Tab in `App/teacher.html`,
Z. 628 ff.) ausbauen:
- **Modul-Filter** über alle Einträge
- **Modul-spezifische Spalten** mit den entscheidenden Erfolgs-Parametern
- **Game-Over-Indikator** pro Zeile
- **Fleiß-Übersicht** mit Filtern Tag / Woche / Monat / Jahr (Zeit pro
Schüler:in, gesamt + pro Modul)
Da das die zentrale Lehrer-Seite und cross-modular ist, gehört das in
deine Hand. Ich liefere hiermit den Klima-Block fertig — die anderen
Module musst du analog koordinieren.
## Klima — entscheidende Erfolgs-Parameter
Die Engine speichert pro abgeschlossenem Durchgang via
`endLevel() → POST /api/assessment.php` ein `results`-JSON. Diese
Felder sind die didaktisch entscheidenden:
| Spalte (Lehrer-Sicht) | JSON-Pfad in `results` | Sinn |
|-------------------------|----------------------------|-----------------------------------------------------|
| Ergebnis-Icon | abgeleitet (siehe unten) | 🏆 / 💸 / 🌊 / 🌫 / 🌡 / ⏸ |
| Endgrund | `endReason` | `won` · `pleite` · `ueberflutet` · `co2-top` · `temp-top` |
| Jahr erreicht | `tick` + Engine-startYear | bis 2175 = 75 Ticks = Vollerfolg |
| Sterne | `stars` | 05 |
| Score | `score` | 0100 |
| CO₂ (ppm) | `final_co2` | < 450 = Klimaziel · ≥ 700 = Game-Over |
| Temperatur (°C) | `final_temperature` | < 17 = Pariser Ziel · ≥ 19 = Game-Over |
| Budget (Mio €) | `final_budget` | > 0 = Pflicht · > 100 = Sparfuchs |
| Überflutet (%) | `final_flooded_pct` | < 30 = Pflicht · < 5 = ausgezeichnet |
| Bevölkerung | `final_population` | nicht unter Startwert sinken lassen |
| Maßnahmen gebaut | `measures_bought` | Aktivitätsindex |
| Events erlebt | `events_survived` | Reaktionsbreite |
| Spielzeit | `duration_ms` (Top-Level) | für Fleiß-Spalte |
## Game-Over-Erkennung
```js
const won = endReason === 'won';
const gameOver = endReason && endReason !== 'won'; // true bei 'pleite' /
// 'ueberflutet' / 'co2-top' /
// 'temp-top'
```
Icon-Mapping:
- `won` → 🏆
- `pleite` → 💸
- `ueberflutet` → 🌊
- `co2-top` → 🌫
- `temp-top` → 🌡
- kein `endReason` (vorzeitig abgebrochen) → ⏸
## Variante 2D vs 3D
In `assessments.sim_id` steht aktuell für beide Varianten `'klima'`. Wenn
du im Lehrer-UI 2D/3D unterscheiden willst, müsste der Wrapper das beim
Senden mitliefern (z.B. `simVariant: '2d' | '3d'`). Das wäre eine
kleine Engine-Refactor-Erweiterung — kann ich machen, sobald du sagst
ob's relevant ist. Vorerst egal: dieselbe Engine, dieselbe Bewertung.
## Fleiß-Übersicht — Vorschlag
Aus `assessments.duration_ms` und `submitted_at`:
- Pro Schüler:in: `SUM(duration_ms) GROUP BY session_id`
- Pro Modul: `SUM(duration_ms) GROUP BY sim_id`
- Pro Zeitfenster: `WHERE submitted_at >= NOW() - INTERVAL X`
Filter Tag/Woche/Monat/Jahr → Standard-DATE_SUB-Pattern.
Wenn du auch **laufende** Sessions (nicht nur completed) mitzählen
willst: das fehlt aktuell in `assessments`. Müsste über
`student_sessions.last_seen_at` oder einen zusätzlichen Heartbeat
laufen. Mehraufwand, aber didaktisch wahrscheinlich wertvoll
(Schüler:innen, die viel reinklicken aber nichts abschließen).
## Was bei mir vorbereitet ist
Engine + 2D + 3D senden bereits `endReason`, `levelWon`, `stars`,
`score`, `final_*`, `measures_bought`, `events_survived`, `duration_ms`
in der `results`-JSON. Du kannst direkt parsen, ich muss nichts
anpassen.
Ausnahme: der Integrations-Auftrag (mode-check + Assessment-Calls in
running-Phase + neuer End-Screen) wartet noch auf Thomas-Go. Sobald
das passiert ist, kommen Zwischenstände alle ~30 s mit dazu.
## Bestätigen
- status: gelesen
- Wenn du die Spalten so übernimmst, brauche ich keine Rückmeldung —
meld dich nur, wenn dir ein Feld fehlt oder du `simVariant` willst