--- 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` | 0–5 | | Score | `score` | 0–100 | | 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