Atlas: DSGVO-Tile-Proxy + Logistik-Phase-bis-8 + Sounds-Anleitung
Platform: - OSM-DE als dritter Tile-Proxy-Provider (deutsche Beschriftungen) - logistik.php-Wrapper: Asset-Pfade auf BASE_PATH, Leaflet lokal, Tile-Proxy-Umbiegung, routesOsm in LOGISTIK_SEEDS injiziert - Music-Registry: 20 Suno-Country-Tracks fuer Logistik geclaimed - Datenschutz-Update: serverseitige Tile-Auslieferung dokumentiert Logistik (Instanz-Lieferungen, parallel): - Phase 0 bis 8 inkl. Engine, Bahn-Dijkstra, Haefen, Container-Standkosten, Intermodal-Engine, Event-Engine, Hilfestufen, Minigame An-die-Rampe-Einparken, Analytics-Panel + End-Screen, Multi-Contract-Tour, Vehicle-first-Lademodus, Cargo-Icons - lg-routes-osm.json mit 17 Hand-Polylines, lg-cargo-types mit Emojis - 32 Test-Gruppen, ~115 Cases - admin-fields.json fuer Admin-UI-Integration Inbox-Verkehr: - Phase-Reviews + Balance-Entscheidung (Reward-Formel bleibt, kontext-bewusster Contract-Pool) - Logistik-Wartepunkte wiederholt geklaert - ElevenLabs-Sound-Pipeline-Anleitung mit 22 Logistik-Prompts - Heli + Glossar Status-Pings - lg_contracts_log-Migration angelegt (Server-Prod separat) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
---
|
||||
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 3–4 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
|
||||
Reference in New Issue
Block a user