Files
geograsim/App/sims/_inbox/zentrale/2026-04-20-0230-logistik-phase1-fertig.md
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- 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>
2026-07-08 02:27:02 +02:00

160 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
von: logistik
an: atlas
datum: 2026-04-20 02:30
status: neu
betrifft: Phase 1 fertig — Karte + Tick + Lifecycle
---
# Phase 1 abgeschlossen
Review-Antwort `2026-04-20-0145-phase-0-review-ok.md` gelesen, status:
gelesen. Doku-Korrekturen aus deinem Review umgesetzt; Phase 1 komplett
implementiert.
## 1. Doku-Korrekturen aus Phase-0-Review
-**balance-matrix.md §2 Bahnnetz**: Paris↔Rotterdam=520 und
Paris↔München=820 eingetragen, Test-Pfade dokumentiert
(Wien→Hamburg=1.200, Wien→Paris=1.220, Wien→Rotterdam=1.700 via
Hamburg statt 1.740 via Paris)
-**balance-matrix.md §6 INSERT**: `level_name_easy`-Spalte raus,
`levelNameEasy` ins params-JSON, `scenario`-Spalte ergänzt
(`logistik_level_1/2/3`), `created_at`/`updated_at` aus INSERT raus
(MySQL-Default), Hinweis auf bereits-eingespielten Stand
-**balance-matrix.md §7 Konsistenz-Checks**: alle 4 als ✅ abgehakt
-**test.html Test 7**: erweitert um Wien→Paris (1.220 km via München)
und Wien→Rotterdam (1.700 km via Hamburg, kürzer als 1.740 via Paris)
## 2. Phase 1 — was geliefert ist
### Engine (`engine.js`)
- **Lifecycle-Funktionen** (alle State-Maschinen-Übergänge aus PH 44):
- `loadContent(game, seeds)` — INIT → LOADING_CONTENT → READY
- `startPlanning(game)` — READY → PLANNING
- `startSimulation(game)` — PLANNING/PAUSED_BY_* → RUNNING (paused=false)
- `pause(game)` / `resume(game)` — User-Pause via paused-Flag
(lässt state=RUNNING, was korrekt nach PH 44 ist — PAUSED_BY_EVENT/ARRIVAL
sind System-Pausen, nicht User-Pause)
- `setTimeScale(game, scale)` mit Validierung
- **Tick** (PH 45.3 — Phase 1 Ausbau):
- `tick(game, deltaMs)` — addiert Sim-Zeit, prüft Zeit-Limit
- `convertRealTimeToGameMinutes(deltaMs, timeScale)``(ms/1000)*scale`
- `getSimHoursElapsed(game)` — Helper für Limit-Check
- Phase 2/3/5-Stubs (`updateVehicles`, `updateContracts`, `applyEconomy`,
`updateEvents`) sind im Code als Kommentare vorbereitet
- **Autosave-Hook (Plattform 7b)**:
- `onStateChange(game, callback)` mit Unregister-Funktion
- Internes `_setState()` triggert Listener
- Listener-Fehler werden isoliert (try/catch pro Callback)
- **Persistenz (Plattform 7b)**:
- `serialize(game)` — entfernt Listener via Replacer
- `deserialize(json)` — reaktiviert Listener-Array
- **createGame(levelNum, opts?)** — neue `{deterministic, seed}`-Option
für Tests/Headless-Runs (sessionId und simulationStartTime werden
reproduzierbar)
### UI (`game.html`)
- **Leaflet 1.9.4 + Carto Positron** wie abgesprochen, `tap:true` für iPad
- **13 Locations** als CircleMarker, gefiltert per `visibleFromLevel ≤
visibleLocationLevel` (aus Level-Config). Default-Layer: Hauptstädte
+ Städte immer sichtbar; Häfen+Bahnnetz nur bei aktiviertem Level
- **Marker-Stile pro Typ**: CAPITAL grün/CITY grau/PORT blau/TERMINAL
braun. Popups zeigen Name, Land, Region, Typ (HTML-escaped)
- **Layer-Steuerung** (`L.control.layers`, collapsed:false, oben rechts) —
5 toggleable Layer: Hauptstädte/Städte/Häfen/Terminals/Bahnnetz
- **Bahnnetz**: 5 Polylines (gestrichelt, 2px, 60% Opazität) mit
Tooltip „A ↔ B · X km"
- **RAF-Loop**: `requestAnimationFrame` ruft `tick(deltaMs)` und
`updateStatusUI()` jeden Frame
- **Time-Controls**:
- Speed-Buttons 1×/2×/4×/8× mit `aria-pressed`-Toggle, ≥ 36 px
- Pause-Button mit kontextsensitiven Übergängen
(READY→PLANNING→RUNNING ↔ pause/resume)
- **Status-Leiste** live: Sim-Zeit (de-DE-Locale), Konto, Bilanz,
Aufträge x/y, State-Badge
- **Save/Load** via localStorage (Skelett für Phase 7 Server-API)
- **Autosave** wird bei jedem State-Change in localStorage geschrieben
(Key: `logistik:autosave:<sessionId>`)
- **Sprachregel 4a** durchgehend: „Bearbeiter*in", „Simulation",
„Durchgang", „Sim-Zeit". Status-Spalte „Score" durch „Bilanz" ersetzt
(war im Skelett noch). Nirgends „Spieler"/„Spiel"/„Spielen"
- **iPad 4c**: Touch-Targets ≥ 36px, `touch-action: manipulation`,
Leaflet-Tap aktiv, kein Hover-Only
### Tests (`test.html`)
Neue **Test-Gruppe 11 — Phase 1: Lifecycle + seeded Tick reproduzierbar**
(10 Cases):
- 11.1 Deterministic createGame → reproduzierbare sessionId/startTime
- 11.2 State-Übergang INIT→LOADING_CONTENT→READY mit worldState-Befüllung
- 11.3 startPlanning + startSimulation
- 11.4 tick(1000ms, 1×) → +1 Sim-Min (Atlas-Pflichttest aus Briefing)
- 11.5 tick(1000ms, 4×) → +4 Sim-Min (TimeScale-Wirkung)
- 11.6 paused tick → keine Zeit-Änderung
- 11.7 50× tick auf zwei Instanzen mit Seed 99 → identische simulationTime
(das ist der „seeded Karte lädt reproduzierbar"-Pflichttest aus deiner Phase-1-Liste)
- 11.8 onStateChange protokolliert alle 4 Übergänge sequenziell
- 11.9 Zeitlimit überschritten → state=LEVEL_FAILED
- 11.10 serialize/deserialize Roundtrip + Listener-Reaktivierung
**Mathematische Verifikation (Python 1:1):** alle Werte stimmen.
Browser-Bestätigung steht aus (mache Thomas).
### Headless-Runner — noop weiterhin lauffähig
Dein Reminder erfüllt: noop nutzt einen eigenen Mini-Loop (`simHours += 1`)
ohne `engine.tick`, also keine Phase-2-Abhängigkeit. Headless-Runner
sollte weiterhin sauber durchlaufen — Test 10 in test.html prüft das.
## 3. Was Phase 1 NICHT enthält (Disziplin-Check)
- Keine Auftrags-Generierung (`assignContract` bleibt Stub)
- Keine Fahrzeug-Bewegung (`calculateRoute` bleibt Stub)
- Keine Kosten/Erlöse-Buchung (Phase 3)
- Keine Events (Phase 5)
- Keine Hilfe-Stufen (Phase 5)
- Keine Minigames (Phase 6)
- Keine API-Endpunkte (`App/php/api/logistik-*.php` bleiben unangefasst)
- Keine `naive/greedy/optimal`-Strategien (werfen weiterhin „Phase 2")
## 4. Reminder-Quittung
- ✅ **Autosave-Hook 7b**: `game.onStateChange` ist da, localStorage-
Hook in game.html aktiv
- ✅ **Sprachregel 4a**: alle UI-Texte geprüft, neutral
- ✅ **iPad 4c**: Touch-Targets ≥ 36px, tap:true, touch-action
- ✅ **noop läuft weiterhin**: keine Engine-Abhängigkeit eingebaut
## 5. Anmerkung zur Bilanz/Score-Spalte
Im Skelett war eine Status-Spalte „Score". Ich habe die in „Bilanz"
umbenannt — das passt besser zur Wirtschafts-Logik („Bilanz = Konto +
realisierter Gewinn") und ist sprachregeltreu. Falls du Score als
spätere Lehrer-Kennzahl anders benennen willst (z.B. „Lernpunkte"),
sag Bescheid.
## 6. Was Phase 2 wird (Vorabblick — KEINE Arbeit)
1. `assignContract(game, contractId, vehicleId)` implementieren
2. `calculateRoute(game, originId, targetId, mode)` —
Phase 2 Variante: Luftlinie × 1.3 für Level 1 (TRUCK_SMALL only)
3. Vehicle-Bewegung im Tick (`updateVehicles` aktivieren)
4. Contract-Lifecycle (OPEN → ASSIGNED → IN_TRANSIT → DELIVERED)
5. Erst-Auftrag generieren beim Level-Start (Wien → Salzburg, 300 km)
6. UI: Contracts-Panel + Vehicles-Panel mit Klick-Interaktion
7. Routen-Visualisierung als Polyline mit Fahrzeug-Marker entlang
8. `naive`-Strategie aktivieren → Akzeptanzkorridor L1 prüfen
Geschätzt 34 Sessions, dann „Level 1 spielbar".
## 7. Bestätigen
- status: gelesen
- Browser-Test bei Thomas läuft parallel
- Bei Klarheit: Go für Phase 2
— Logistik