Ziel: die Lehrperson sieht auf einen Blick, was in der Klasse gerade los ist — wer aktiv ist, wer hinterher ist, wer heute noch nichts gemacht hat, wer die Top 3 und wer die Schwächsten 3 sind — und kann pro Schüler:in bei Bedarf bis ins Detail einsteigen. Vier Ebenen: Status & Ranking ganz oben, dann Filter auf die ganze Klassenliste, dann pro Schüler:in eine Zeile mit Live-Stats (jeder Wert mit Range-Balken), und auf Klick der Detail-Drill-Down.
Der Filter oben (Tag · Woche · Monat · Schuljahr) wirkt auf alle Fleiß-Säulen-Anzeigen gleichzeitig — Klassen-Fleiß im Live-Cockpit und Schüler:innen-Fleiß-Matrix im Ergebnisse-Tab. Die folgenden Skizzen zeigen, wie die Säulen-Auflösung pro Variante aussieht.
Hover über jede Pill zeigt eine Kurz-Spec — nützlich besonders für die Lehrperson, die das Cockpit zum ersten Mal sieht. Probier es oben am Filter mal aus.
Die gewählte Einstellung wird in localStorage gespeichert.
Bei jedem späteren Aufruf des Cockpits steht der Filter direkt auf dem
zuletzt gewählten Wert — keine Mehrfach-Klicks pro Tag.
Der Wert ist pro Lehrperson (Browser-lokal), nicht pro Klasse — das hält die Bedienung leichtgewichtig. Falls jemand mehrere Klassen oft umschaltet, kann später auf Server-Seite ein User-Preference-Feld dazu (siehe Memory).
Die Plattform bedient gezielt Österreich, Deutschland, Schweiz, Liechtenstein.
Schul-Anfangs- und Endmonate ziehen wir aus App/php/lib/Country.php
(existiert schon für andere Sprach-/Lehrplan-Themen).
| Land | Schulanfang | Schulende | Bemerkung |
|---|---|---|---|
| 🇦🇹 Österreich | September | Juli | 1. Schultag Mo nach 1. September (Ost) bzw. 2. Mo im September (West) |
| 🇩🇪 Deutschland | August / September | Juli | variiert nach Bundesland · BY/BW: Mitte Sep · HH/B/MV: Anfang Aug |
| 🇨🇭 Schweiz | August | Juli / August | variiert nach Kanton · ZH/BE/SG: Mitte Aug · TI: Anfang Sep |
| 🇱🇮 Liechtenstein | August | Juli | angelehnt an Schweiz (Mitte Aug) |
Konkret im Code: Country::schoolYearStart('AT') liefert {month: 9, dayApprox: 5},
Country::schoolYearStart('CH') liefert {month: 8, dayApprox: 15}.
Die Schuljahr-Säulen-Anzeige beginnt beim ersten Monat nach dem Schulanfang mit Aktivität
und endet beim letzten — leere Monate am Rand werden weggelassen (Sommerferien-Lücken
im Schuljahr also auch automatisch unsichtbar, falls eine Klasse über Ferien nichts spielt).
DE-Bundesland-Logik: in DE genauer Schulanfang ist Bundesland-spezifisch.
Pragmatisch: pro Klasse ein Feld classes.school_region (optional) — sonst Default „Mitte August".
Sehr selten relevant für die Säulen-Anzeige, weil ein Säulen-Bucket ein ganzer Monat ist.
title-Attribute (~15 min), localStorage-Persistenz ist
ein Wrapper um das State-Setting (~20 min), das Schuljahr-aus-Country für AT/DE/CH/LI braucht
eine neue Methode in Country.php plus die kleine 4-Zeilen-Mapping-Tabelle (~30 min)
sowie eine kleine Anpassung im Säulen-Renderer (~15 min). Tests + Edge-Cases
(Schuljahres-Wechsel im August/September, Halbjahr-Ferien-Lücken) ~10 min.
Jede Simulation liefert einen normalisierten Modul-Score 0–100 %, der die Leistung in einer Session widerspiegelt. Der Gesamt-Benchmark einer Schüler:in ist der Mittelwert aller ihrer abgeschlossenen Sessions — gewichtet so, dass eine häufig gespielte Sim nicht alles dominiert (max. 3 Sessions pro Modul zählen ein, danach gilt nur das beste Ergebnis).
| Modul | Was ergibt 100 %? | Berechnung (Vorschlag) |
|---|---|---|
| 🌍 Klimawächter | Temp ≤ +1 °C, Inselüberflutung 0 %, Budget > 1000, Bevölkerung 100 % | (tempScore + inselScore + budgetScore + popScore) / 4 |
| 🚁 Heli | Alle Wegpunkte ohne Fehlversuch, Audio durch | planCorrect/planTotal × (1 − planAttempts/15) |
| 🚌 Busfahrt | Quiz Erste-Wahl-Quote 100 %, Distanz-Abweichung < 30 km Ø | 0.7×quizFirstTryRate + 0.3×(1 − distMean/200) |
| 🍽️ Weltküche | Alle Gerichte abgeschlossen, <3 Fehlklicks pro Zutat | completedDishes/totalDishes × (1 − mistakes/maxMistakes) |
| 🌾 Farmer | Erfolgsrate 100 %, Jahr ≥ 20 erreicht, CO₂ niedrig | 0.5×successRate + 0.3×(years/20) + 0.2×(1 − co2Norm) |
| 🪐 Sonnensystem | Alle 20 Aufgaben gelöst, möglichst Erste-Wahl | completed/total × (1 − attempts/maxAttempts) |
| 🏛️ EU-Werkstatt | Alle 4 Fälle korrekt, Mülleimer leer | firstTryHits/totalSteps × (1 − muelleimer/totalAttempts) |
| ⚡ Energiemanager | Alle 8 Blöcke ohne Defizit, alle 6 Sets durch | perfectBlocks/totalBlocks × setIndex/setTotal |
| 🌊 Fluss | Biodiv ≥ 80, Economy ≥ 60, Flood < 20, Population stabil | (biodiv + economy + (100-flood) + popStable) / 4 |
| ✈️ Fluggesellschaft | Alle Aufträge gewonnen, Quiz Erste-Wahl 100 %, hohe Marge | 0.5×wonRate + 0.3×quizFirstTry + 0.2×marginScore |
| 📦 Logistik | ≥80 % Aufträge pünktlich abgeschlossen, Endbilanz positiv | 0.7×onTimeRate + 0.3×profitNorm |
| 📅 Entscheidungstag | Tag-Ziel erreicht, CO₂/kWh-Limit eingehalten | noch zu definieren |
Wichtig: der Prozentwert ist nicht eine Note — er ist eine Orientierung. Beim Klick auf „Detail" sieht die Lehrperson, woraus sich die Zahl zusammensetzt (welches Modul, welche Dimension hat ihn nach unten oder oben gezogen). Schüler:innen sehen den eigenen Wert nicht direkt — das verhindert Wettkampfdruck. Die Lehrperson kann pro Klasse entscheiden, ob sie ihn teilen möchte.
Klick auf „Live anschauen →" öffnet einen Vollbild-Spectator-Modus, in dem die Lehrperson
die Sim aus Schüler-Perspektive mit-sieht (heute schon teilweise via ?view=teacher).
Plus: rechts daneben ein Daten-Panel mit den Modul-spezifischen Live-Werten der API.
App/php/lib/Benchmark.php — pro Modul eine Formel laut Tabelle oben. Input: assessments.results-JSON pro Submission. Output: {moduleId, modulePct, dimensions:[{key,label,score}]}. Aggregat pro Schüler:in: max. 3 beste pro Modul, dann Mittelwert über alle Module mit Submissions./api/live?class_id=X erweitern um:
aktiv|heute|kalt|nie) + Tages-SummarybenchmarkPct pro Schüler:in (über alle Apps) + perModule-BreakdowntopN / bottomN als bequeme Ranking-ListenweeklyByDay: Klassen-Lernzeit pro Tag, gestapelt nach ModulneedsHelp-Heuristik (Heli-Fails ≥10, Klima-Budget < 0, Weltküche-Fehlklicks > 15/Runde, >10 min ohne Heartbeat während Sim offen)GGS_LIVE_RANGES = { co2:{min:280, max:600, bad:'high'}, budget:{min:0, max:1000, bad:'low'} }. Frontend rendert dann automatisch die Range-Bars in den Mini-Stats. Spart das Hartkodieren pro Sim.renderLiveSummary komplett ersetzen — 4 neue Render-Funktionen: renderLiveStatus (Tiles + Ranking + Klassen-Säulen), renderLiveFilter, renderLiveStudentList, renderLiveDetail.POST /api/live {action:'nudge', studentId, text} — pusht Toast in laufende Schüler-Sim via Pause-Polling-Channel.Erste Schritte konkret: (1) Benchmark.php-Formeln mit Thomas durchgehen und finalisieren. (2) Range-Definitionen pro Sim als JSON-Schema spec'en (zentrale Stelle). (3) Lokal renderLiveStatus prototypisch bauen, gegen Mock-Daten testen. (4) Echtes Backend nachziehen wenn UI sitzt.
Entwurf · liegt unter .dontDeploy/entwurfswerkzeug/live-konzept.html ·
Stand 2026-06-10 · GeoGraSim/Atlas