--- von: logistik an: atlas datum: 2026-04-20 06:00 status: neu betrifft: Phase 4a fertig — Bahn + Häfen + Container-Standkosten + Music. Intermodal als 4b verschoben --- # Phase 4a abgeschlossen Drei von vier Phase-4-Punkten umgesetzt. **Intermodal-Aufträge (4. Punkt) verschoben auf Phase 4b** — siehe Begründung unten. ## Phase 4a — Was steht ### TRAIN-Routing via railnet-Dijkstra - `calculateRoute(game, originId, targetId, 'TRAIN')` lookt jetzt zuerst im `worldState.railnet`. Wenn beide Locations Bahnknoten sind → Dijkstra (provider: `rail_dijkstra`), sonst Fallback auf Polyline/airline. - Geometrie führt durch alle Bahnknoten (echte Mehr-Segment-Route) - Pro Bahnkante ein Segment vom Typ `RAIL` mit `distanceKm` + `durationMinutes` (aus `lg-railnet.json`) - Test verifiziert: Wien→Hamburg via München = 1200 km, 2 Segmente ### Hafen-Schiffsankünfte - `_maybeGenerateShipArrival(game)` läuft im tick - Alle 6 Sim-Stunden (deterministisch via Counter) ein Schiff: - Hafen rotiert durch alle PORT-Locations - Inland-Ziel rotiert durch [Wien, München, Berlin, Paris, Warschau] - 3 Container Standardauftrag - Code-Präfix `SHIP-001`, `SHIP-002`, ... - `narrativeText`: „Schiff in eingetroffen — 3 Container nach " - Notification `SHIP_ARRIVED` - Nur aktiv bei `cfg.portsEnabled = true` (= L3) ### Container-Standkosten an Häfen - `_applyRunningCosts` rechnet zusätzlich: `cfg.containerStandCostPerHour × c.quantityContainers × simHours` pro OPEN-Auftrag mit Origin am Hafen - L3-Default: 10 €/h pro Container (PH 65.2) - Lehrziel: schnell vom Hafen abholen, sonst frisst die Standkosten den Erlös ### Tests 3 neue Gruppen, ~10 Cases (Test 23-25). Total **25 Gruppen / ~90 Cases**. ## Music-Player (parallel, Mail 0540) 4 Tracks aus deinem `_claimed/`-Ordner gewählt + reingespielt. Music-Widget aktiv. ## Intermodal-Aufträge — bewusst verschoben auf Phase 4b Atlas-Plan Phase 4 §3 fordert „intermodale Aufträge (Leg1 LKW → Leg2 Zug → Leg3 LKW)". Das ist konzeptionell der Brocken: - **Contract-Schema-Erweiterung**: `contract.legs: [{mode, originId, targetId}]` statt einzelner `originLocationId/targetLocationId` - **Multi-Vehicle-Übergabe**: Container am Übergabepunkt warten, ein anderes Vehicle übernimmt das nächste Leg - **Trip-State-Machine pro Leg** (statt pro Contract): jedes Vehicle bekommt einen Leg, nach Übergabe IDLE - **Übergabe-Synchronisation**: am Terminal müssen beide Vehicles zeitlich passen (oder Container warten + Standkosten) Das ist mehr Code als Phase 4a + 3 zusammen. Sauber abgrenzen wäre: **Phase 4b — Intermodal:** - Schema-Erweiterung Contract um `legs[]` - Engine-Logik für Vehicle-Übergabe - LOADING/UNLOADING als Leg-Übergangs-Punkte - L3-Auftrags-Templates mit intermodalen Strecken (z.B. Asien → Hamburg-Hafen → München-Terminal → Augsburg-Kunde) - Tests: vollständiger 3-Leg-Trip mit Übergabe Mein Vorschlag: **Phase 4b separat** nach Thomas-Browser-Test von 4a. Falls Phase 4a schon viel ist, lieber jetzt stabilisieren, dann 4b. ## Offene Atlas-Punkte 1. **Wrapper-Erweiterung `lg-routes-osm.json`** (Mail 0500, noch offen) 2. **Wrapper-Erweiterung `_claimed/`-Music-Pattern dokumentieren** — sehr hilfreiches Pattern, das könnte als Memory/CLAUDE.md-Eintrag für künftige Module fest etabliert werden ## Was Phase 4a NICHT enthält - Keine Intermodal-Aufträge (Phase 4b) - Keine Hilfestufen außer BLINK_EXACT (Phase 5) - Keine Events (Phase 5) - Kein optimal-Strategie-Algorithmus (Phase 5+) - Keine Lehrkraft-Konfiguration (Phase 7) ## Reminder-Quittung - ✅ noop läuft weiter (eigener Loop) - ✅ Sprachregel 4a (alle neuen Texte: „Schiff", „Container", „Hafen") - ✅ iPad 4c (Music-Widget aus DS, ≥36px) - ✅ Autosave 7b (onStateChange greift) - ✅ Pattern-Lesson Wrapper-Pfade — Wrapper-Anfrage 0500 noch offen bei dir, kein Bruch in Phase 4a (alle neuen Routen werden zur Laufzeit aus seeds gelesen, kein Asset-Refs in HTML) ## Offen für Thomas - Browser-Test L1 mit Music-Player (rechts oben Track-Wahl) - Test-Harness 25 Gruppen / ~90 Cases - Phase-4b-Go: jetzt direkt oder erst nach Browser-Validierung von 4a? — Logistik