- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/ - 12 code-workspace-Files - STATUS-*.md - viele M/D/R-Änderungen an bereits getrackten Files - .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6.6 KiB
Balance-Korridor (Regeln R-1, R-2, R-3)
Stand: 2026-04-24 Gilt für: Logistik Europa (Modul 11), Vorlage für andere Sim-Module
Dieses Dokument formalisiert den Balance-Anspruch („jedes Level muss man gewinnen UND verlieren können") als drei Regeln und beschreibt eine mechanische Methode, sie zu prüfen.
1. Anspruch
Ein Level ist balanciert, wenn:
- Der/die Bearbeiter*in Zeit zum Nachdenken hat, bevor sie ins Minus rutscht (R-1 Runway).
- Mit gutem Spiel gewinnen kann (R-2 Winnable).
- Mit schlechtem oder keinem Spiel verlieren kann (R-3 Loseable).
Keine der drei Bedingungen darf systematisch verfehlt werden — sonst ist das Level entweder Frustquelle (kann nur verlieren) oder Pseudo- Lernspiel (kann nur gewinnen, keine Konsequenz).
2. Regel R-1 — Startbudget-Runway
Bereits in level-progression.md §2 hergeleitet.
Hier nur die Formel:
startBudget ≥ 1.5 × ( rentalCostPerDay × vehicleCount
+ idleCostPerHour × vehicleCount × 12 )
Interpretation: Anfangsbudget reicht für 1.5 Tage Operating ohne Einnahmen. Gibt Puffer für Fehltrip + strategische Entscheidung.
3. Regel R-2 — Winnable
Bei optimalem oder mindestens guten Spiel muss der Level spätestens beim dritten Versuch mit positivem End-Saldo gegenüber
minTargetEarningsenden.
Formal (Median über 5 Seeds):
- L1:
runLevel(1, *, naive)→successful: trueANDendBalance − startBudget ≥ +1.000 € - L1:
runLevel(1, *, greedy)→successful: trueANDendBalance − startBudget ≥ +2.000 € - L2:
runLevel(2, *, greedy)→successful: trueANDendBalance − startBudget ≥ 0 - L2:
runLevel(2, *, optimal)→successful: trueANDendBalance − startBudget ≥ +5.000 € - L3:
runLevel(3, *, optimal)→successful: trueANDendBalance − startBudget ≥ 0
(Werte aus balance-matrix.md §3 übernommen.)
Was wir gerade messen können:
- L1: ✓ naive, greedy, optimal laufen — alle prüfbar
- L2: ✓ greedy + optimal laufen — prüfbar
- L3: ✓ optimal läuft (Best-Net-Heuristik seit 2026-04-24) — prüfbar
→ optimal ist keine echte globale Optimierung (VRP-TW ist NP-hart),
sondern eine Best-Net-Heuristik: pro Tick wird die (Contract, Vehicle)-
Paarung mit maximalem erwarteten Netto ausgewählt
(reward × 1.15 − pickup-fare − delivery-fare − erwartete Verspätungsstrafe).
Dominiert greedy in allen drei Leveln und reicht als Proxy für „gutes Spiel".
4. Regel R-3 — Loseable
Untätigkeit oder grobes Fehlspiel muss zuverlässig zum Verlieren führen, sonst ist das Level keine Lernsituation.
Formal (Median über 5 Seeds):
- L1:
runLevel(1, *, noop)→successful: falseANDendBalance < minTargetEarnings - L2:
runLevel(2, *, noop)→successful: false - L3:
runLevel(3, *, noop)→successful: false - L2:
runLevel(2, *, naive)→successful: false(zusätzlich gefordert: schlechte Disposition reicht nicht) - L3:
runLevel(3, *, naive)→successful: false - L3:
runLevel(3, *, greedy)→successful: falseODERknapp negativ
Implizite Anforderung: Auch ohne Untätigkeit muss der Schweregrad mit Level steigen. L3 darf nicht durch greedy lösbar sein (sonst ist es nur ein L2-Klon).
5. Aktuelle Verifikation (Stand 2026-04-24)
R-1 (mathematisch)
| Level | Required ≥ | Hat | Verdikt |
|---|---|---|---|
| L1 | 0 | 8.000 | ✅ |
| L2 | 1.170 | 5.000 | ✅ |
| L3 | 4.650 | 5.000 (nach Fix vom 2026-04-24) | ✅ |
R-2 / R-3 (per Headless-Runner — siehe headless-runner.html)
Status: VOLLSTAENDIG
- noop, naive, greedy, optimal laufen alle
- Korridor-Check-Button in headless-runner.html pruft R-1 + R-2 + R-3
ueber alle 60 Durchlaeufe (3 Lvl × 4 Strategien × 5 Seeds)
Konkrete Runs noch ausständig — beim Server-/Browser-Test mit headless-runner.html „Balance-Korridor-Check"-Button drücken (kommt mit dem Patch dieses Dokuments).
6. Methode zur Sicherstellung („was tun, wenn ein Level neu konfiguriert wird")
6a. Pre-Deploy-Check (vor jeder Level-Param-Änderung)
- R-1 mit Taschenrechner: Formel oben rechnen, muss ≥ erfüllt sein.
Engine-seitig schon eingebaut:
_validateRuleR1inloadContentloggtconsole.warnbei Verletzung. - R-2/R-3 via Headless-Runner:
headless-runner.htmlöffnen, „Balance-Korridor-Check" drücken. Ergebnis-Tabelle vergleichen mit Soll-Korridor (siehe §3 + §4). - Bei Verletzung: Param ändern (üblicherweise
startBudget,minTargetEarnings,eventProbabilityMultiplier), erneut prüfen. - Erst dann committen.
6b. Continuous Verification (perspektivisch, sobald Atlas freigibt)
- Test-Suite-Script (Node.js):
npm run balance-checkführtLogistikRunner.runMatrix({levels:[1,2,3], strategies:[...], seeds:[1..5]})und vergleicht gegen Korridor. Exit-Code 0 = pass, 1 = fail. - CI-Hook beim Push: blockiert Merge, wenn Korridor nicht erreicht.
- Voraussetzung: Node-Engine-Export (engine.js läuft schon UMD-konform).
6c. Manueller Sanity-Check (ergänzend)
Reine Zahlen reichen nicht — der „Spielspaß" ist nicht messbar. Nach jedem Param-Change zusätzlich:
- 1× Live-Test im Browser pro Level mit naive Spielstil (mehrere Fehltrips).
- 1× Test mit gezielt-strategischem Spielstil.
- Fühlt sich der Schwierigkeitsgrad richtig an, oder kommt Frust auf?
Die mechanischen Regeln R-1/R-2/R-3 sind notwendig, aber nicht hinreichend.
7. Offene Punkte
Kurzfristig (vor dem Schul-Pilot)
optimal-Strategie als Best-Net-Heuristik implementiert (2026-04-24, headless-runner.js, 120 Zeilen). Kriterium pro Tick: maxreward × 1.15 − pickup-fare − delivery-fare − erwartete Strafe, dann feasible Zuweisungen in Sortierreihenfolge feuern.- „Balance-Korridor-Check"-Button in
headless-runner.htmleinbauen (erledigt, prueft R-1/R-2/R-3 mechanisch).
Mittelfristig
- Node-Test-Script mit Exit-Code für CI.
- Per-Modul-Generalisierung: das Korridor-Pattern in
App/docs/integration-konzept.mdals Plattform-Vertrag dokumentieren, damit jedes Modul (Klima, Heli, …) die gleiche Disziplin hat.
Langfristig
- Stochastische Robustheit: Korridor nicht nur über 5 Seeds prüfen, sondern Konfidenzintervall (z.B. 95 % über 100 Seeds). Aktuell nicht nötig — die Engine ist deterministisch und 5 Seeds geben uns schon eine gute Stichprobe.