- 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>
14 KiB
Audio-Schnitt-Tool — Konzept
Stand: 2026-06-01 · Atlas · Status: zum Review · KEIN CODE BIS THOMAS-OK
Zweck
Tool-Seite (eigene URL, nicht Spiel) zum Schneiden, Anordnen und Speichern der Audio-Timeline pro Mission. Wie Cubase/DaVinci, aber speziell für unsere Heli-Missionen. Was im Tool definiert ist, spielt das Spiel deterministisch ab (Tool = Wahrheit, Engine folgt).
Grundprinzipien
- Eine Timeline pro Mission — horizontale Zeitachse, links→rechts, scrollbar, zoombar
- Pro Audio = ein Balken auf der Timeline. Balken-Länge = echte MP3-Dauer (gemessen, gecacht). Verschieben per Drag&Drop.
- Niemals zwei Audios gleichzeitig — Tool verhindert visuell und logisch Überlappungen
- Strecken sind variabel — die Karten-Animations-Dauer im Spiel passt sich der Audio-Inhalts-Länge an, nicht umgekehrt. Lange Inhalte = langsamerer Flug zwischen den Wegpunkten.
- Phase-Gating im Spiel: der nächste Wegpunkt wird erst sichtbar, wenn das aktuelle Audio fertig ist. Klick vorab erlaubt, Audio läuft trotzdem.
Tool-UI
┌──────────────────────────────────────────────────────────────────────┐
│ ← M1 Damüls M2 ▶ [M1] [M2] [M3] ... [M25] │ ← Mission-Switcher
├──────────────────────────────────────────────────────────────────────┤
│ PLAN ▏ FLUG ▏ Abflug | Landung | Ende │ ← Phasen-Track
│ ───────────────────────────────────────────────────────────────── │
│ 0:00 0:30 1:00 1:30 2:00 2:30│ ← Zeitachse (sec)
│ ╿ │
│ ▌▌r_mission_intro_m1 (12s) ▌▌r_wp_geo_thueringen (7s) │ ← Audio-Track
│ ▌▌r_wp_geo_zwischenwasser (8s) │
│ ▌▌r_wp_geo_damuels │
│ ───────────────────────────────────────────────────────────────── │
│ 🚩Plan-Start 🟢WP1 thueringen 🟢WP2 zwischenwasser 🟢WP3 damuels │ ← Event-Marker
│ │
│ ┌─ Audio-Pool ────────────────────────────────────────────────┐ │ ← Audio-Pool unten,
│ │ 🔊 r_mission_intro_m1 12s Sarah/Tower │ │ Drag→Timeline
│ │ 🔊 r_wp_geo_thueringen 7s Briefing │ │
│ │ 🔊 r_wp_geo_zwischenwasser ... [Filter: alle / verwendet] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ [💾 Speichern] [▶ Vorschau abspielen] [↩ Reset auf Default] │ ← Aktionen
└──────────────────────────────────────────────────────────────────────┘
UI-Details
- Mission-Switcher oben: vor/zurück (Pfeile) + alle 25 Missionen als Tabs/Dropdown
- Phasen-Track zeigt Phasen-Sektionen (Plan, Flug, Abflug, Landung, Ende) in unterschiedlichen Farben/Schraffuren
- Zeitachse in Sekunden, zoombar via Mausrad/Buttons (z. B. 1 px = 0,1 s, 0,2 s, 0,5 s, 1 s …)
- Audio-Track zeigt Audio-Balken — Länge proportional zur Dauer. Klick auf Balken → markiert + zeigt Audio-ID + Text + Aktionen (löschen, verschieben, „Inhalt prüfen"). Drag verschiebt.
- Event-Marker als vertikale Linien mit kleinem Label (Wegpunkt erreicht, Phase-Wechsel, etc.). Werden teils automatisch gesetzt (z. B. pro Wegpunkt aus
mission.waypoints), teils manuell. - Audio-Pool unten als Liste/Tabelle mit Such-/Filterfunktion. Drag auf Timeline → fügt Balken hinzu. Audios die schon platziert sind, sind im Pool ausgegraut.
- Speichern → POST an PHP-Endpoint → schreibt
audio-timeline-m1.jsonins Verzeichnis - Vorschau → spielt die Timeline im Browser ab (sequenziell, mit Events als Subtitel-Anzeige)
- Reset → lädt Default-Timeline aus dem Regelwerk (für leere Missionen)
Sequenz-Garantie (Tool-Verhalten)
Wenn der User einen Balken so verschiebt, dass er einen anderen überlappt:
- Tool springt automatisch hinter den vorherigen Balken (+ konfigurierbarer Gap, z. B. 0,5 s)
- Visuelles Feedback (rote Outline beim Drag wenn Überlappung droht, snappt dann ein)
Datenmodell
Pro Mission: App/sims/heli/data/audio-timeline-<mid>.json
{
"_doc": "Audio-Timeline fuer M1 Damüls. Wird von /heli-audio-editor gespeichert + vom Spiel deterministisch abgespielt.",
"missionId": "m1",
"version": 1,
"lastSaved": "2026-06-01T10:30:00",
"gap": 0.5,
"phases": [
{
"id": "plan",
"label": "Routenplanung",
"color": "#4a7c8a",
"events": [
{ "id": "ev-plan-start", "t": 0, "label": "Plan-Start" },
{ "id": "ev-wp1", "t": 14, "label": "Wegpunkt sichtbar: thueringen", "waypoint": "thueringen" },
{ "id": "ev-wp2", "t": 22, "label": "Wegpunkt sichtbar: zwischenwasser", "waypoint": "zwischenwasser" },
...
{ "id": "ev-plan-end", "t": 65, "label": "Plan fertig" }
],
"audios": [
{ "id": "a1", "audioId": "r_mission_intro_m1", "t": 0, "dur": 12.3 },
{ "id": "a2", "audioId": "r_wp_geo_thueringen", "t": 14, "dur": 7.1 },
{ "id": "a3", "audioId": "r_nav_plan_correct", "t": 22, "dur": 3.2 },
{ "id": "a4", "audioId": "r_wp_geo_zwischenwasser", "t": 26, "dur": 8.5 },
...
{ "id": "aN", "audioId": "r_nav_plan_done", "t": 60, "dur": 5.0 }
]
},
{
"id": "flug",
"label": "Kartenflug",
"color": "#5a8a5e",
"events": [ ... ],
"audios": [ ... ]
}
],
"_notes": "Editor erlaubt nur Plan + Flug. Abflug + Landung werden vom alten Engine-Pfad gespielt (separate Phase-Markierung im Tool als grauer Block, nicht editierbar)."
}
Audio-Dauer-Cache: App/sims/heli/data/audio-durations.json
{
"_doc": "Audio-Dauern in Sekunden. Tool laedt MP3s clientseitig und liest <audio>.duration. Bei neuen Files automatisch nachpflegen.",
"lastUpdated": "2026-06-01T10:30:00",
"durations": {
"r_mission_intro_m1": 12.3,
"r_nachtrag_a": 2.1,
"r_wp_geo_thueringen": 7.1,
...
}
}
Beim ersten Tool-Aufruf: für jeden Audio-Eintrag in audio-texts.json, der noch nicht im Cache ist, MP3 via <audio>-Element laden + duration abfragen + cachen. Cache wird beim Save aktualisiert.
PHP-Save-Endpoint
App/php/api/heli-timeline.php:
POST /api/heli-timeline?mission=m1→ body JSON → schreibt indata/audio-timeline-m1.json(+Backup)GET /api/heli-timeline?mission=m1→ liest Datei zurückPOST /api/heli-audio-durations→ schreibt/updateddata/audio-durations.json
Sicherheit: nur internes Tool, kein Auth. (Wenn Production: hinter Lehrer-Login.)
Spiel-Integration (Engine-Refactor)
Heute (chaotisch)
- Plan-Audios werden in 4-5 verschiedenen Code-Stellen getriggert (initPlanPhase, showPlanInstruction, onPlanClick, …)
- Race-Conditions möglich (Mission-Intro + WP-Geo gleichzeitig)
- V1-Whitelist filtert teilweise
Neu (Timeline-getrieben)
audio-engine.js (neue zentrale Datei):
- Lädt beim Mission-Start
audio-timeline-<mid>.json - Pro Phase eine State-Machine:
phaseStart(phaseId)→ spielt das erste Audio der PhaseaudioEnded()→ fireseventbeit = ende-des-Audios, schaltet nächsten Wegpunkt frei, spielt nächstes Audio
- Game wartet auf Audio-Ende bevor nächster Wegpunkt sichtbar wird
- Klick-vor-Audio-Ende → Klick wird angenommen, aber als „Pre-Click" markiert. Audio läuft trotzdem fertig.
- Strecken-Animation passt sich an Audio-Dauer an (Flugzeit-Berechnung wird dynamisch)
Konkrete Code-Stellen die verschwinden
game.html:1056(Mission-Intro setTimeout) → ersetzt durch Timeline-Triggergame.html:1365(r_wp_geo in showPlanInstruction) → ersetzt durch Timelinegame.html:1400(r_nav_plan_correct/done in onPlanClick) → ersetzt durch Timelinegame.html:1552(r_mission_geo in initFlightPhase) → ersetzt durch Timeline
Plan + Flug = Engine-driven, Abflug + Landung = wie heute
Phase 3 + 5 (iframe-basiert) bleiben unangetastet. Wenn das später auch in die Timeline soll, müssen wir die iframes auf das gleiche Schema umbauen — aber das ist Phase 2 dieses Projekts.
Implementierungs-Reihenfolge
| Schritt | Was | Aufwand |
|---|---|---|
| 1 | Konzept-Doc OK von Thomas | — |
| 2 | PHP-Endpoint heli-timeline.php (GET/POST + Datei-Backup) |
1 h |
| 3 | Audio-Dauer-Cache: Skript das alle MP3s clientseitig misst und in audio-durations.json schreibt (einmaliger Setup) |
2 h |
| 4 | Tool-UI Grundgerüst: Mission-Switch, Phasen-Track, Zeitachse, Audio-Track (read-only) | 3 h |
| 5 | Tool-UI Editor: Drag&Drop, Audio-Pool, Speichern | 3 h |
| 6 | Default-Timeline-Generator: Atlas befüllt ALLE 25 Missionen vor (siehe Sektion „Default-Befüllung") | 3 h |
| 7 | M1 als erste Mission gemeinsam durchgehen + tunen (Atlas lernt) | gemeinsam |
| 8 | Engine-Refactor: audio-engine.js lädt Timeline + spielt deterministisch (nur Plan + Flug) |
4 h |
| 9 | Test M1: Tool → Spiel → läuft korrekt + sequenziell + Klick-vorab funktioniert | gemeinsam |
| 10 | Restliche 24 Missionen im Tool durchschneiden | gemeinsam |
| Total Atlas-Code | ca. 15 h | |
| Total Thomas-Review | ca. 3-4 h gemeinsam |
Default-Befüllung (Atlas macht die Hauptarbeit)
Thomas-Direktive: „Du füllst das Tool gleich mit deinem Vorschlag … hoffentlich muss ich nicht alle selbst machen."
→ Atlas erzeugt pro Mission eine komplette Default-Timeline. Thomas reviewt + tunet, was nicht passt. Atlas lernt aus den Korrekturen für die nächsten Missionen.
Generator-Regeln (Atlas befüllt automatisch)
Pro Mission liest der Generator:
- Mission-Daten aus
ALL_MISSIONS(waypoints, base, theme, scenario, heliKey) - Audio-Drehbuch-Regelwerk (welche Audios in welcher Phase, in welcher Reihenfolge)
- Audio-Dauern aus
audio-durations.json - Briefings aus
briefings.json(Wetter-Trigger ja/nein)
Daraus baut er die Default-Timeline:
PLAN-Phase:
T=0.0 r_mission_intro_<mid> (dur aus Cache)
T=+gap r_wp_geo_<wp1> (erster Wegpunkt-Hint, Trigger für Wegpunkt-Sichtbar-Event)
T=+dur EVENT: WP1 sichtbar
T=+gap r_nav_plan_correct (wenn Schüler klickt, Audio spielt zu Ende)
T=+dur EVENT: WP1 erreicht
T=+gap r_wp_geo_<wp2>
...
T=... r_nav_plan_done (letzter Wegpunkt)
FLUG-Phase:
T=0.0 r_mission_geo_<mid> (das lange Region-Briefing)
T=+gap r_nav_heli_intro_<helikey> (Crew-Vorstellung)
T=+gap r_nav_altitude_mountain ODER _valley (je Theme)
T=+gap r_nav_fuel_half
T=+gap r_nav_weather_enter (NUR wenn briefings.wetter gesetzt)
T=+gap r_im_zielgebiet (kurz vor Landung)
Mit gap = 0.5 s (Default-Pause zwischen Audios, im Tool änderbar).
Tool zeigt Generator-Status
Im UI-Header pro Mission:
- 🤖 „Default von Atlas, ungeändert" — du musst nichts tun, kannst direkt zur nächsten
- ✏️ „Von dir bearbeitet" — Diff-Anzeige (gelb markiert), zeigt was du verändert hast
- 💾 „Gespeichert" — letztes Save-Datum
Atlas lernt (Memory)
Wenn du an einer Mission etwas änderst — z. B. r_nav_fuel_half rausnimmst weil es nicht passt — schreibt Atlas das in ein Lern-Memo:
docs/audio-tool-lernkurve.md:
2026-06-01: Thomas hat aus M1 r_nav_fuel_half entfernt (Begründung: zu früh, störender Hinweis)
→ Default-Generator: r_nav_fuel_half künftig nur bei Missionen mit >5 Wegpunkten einreihen.
2026-06-01: Thomas hat in M6 das Wetter-Audio vorgezogen (vor Mission-Geo)
→ Default-Generator: wenn briefings.wetter gesetzt, r_nav_weather_enter VOR r_mission_geo platzieren.
Bei der nächsten Mission-Befüllung berücksichtigt Atlas diese Lerneinträge. So musst du nicht für 25 Missionen das gleiche tunen — die Lern-Regel reicht.
Workflow
[Atlas startet Tool] → 25 Default-Timelines werden vorgeneriert
↓
[Thomas öffnet M1] → sieht 🤖-Default, hört Vorschau im Spiel
↓
[Thomas tunet M1] → verschiebt 2 Audios, löscht 1
[Atlas merkt sich Begründung] → Memory-Eintrag
↓
[Thomas M2] → Default ist schon besser dank gelernter Regel
↓
[...iterativ M3...M25 — Aufwand sinkt pro Mission]
Realistische Schätzung pro Mission (nach Default):
- Erste 5 Missionen: ~10 min Review/Tunen (viel zu lernen)
- Mittlere 10 Missionen: ~3 min (kleine Anpassungen)
- Letzte 10 Missionen: ~1 min (meist nur Bestätigen)
Total: ~1.5 h gemeinsame Review-Zeit für alle 25 Missionen.
Was ich beim Bauen NICHT mache (wichtig)
- Keine weiteren Bug-Fixes an der alten Engine
- Keine neuen TTS-Runs bis das Tool steht (sonst Inhalts-Murks bevor Struktur sauber ist)
- Kein V3-Whitelist-Geraffel — die V1-Whitelist bleibt aktiv, nur die neue Engine umgeht sie sauber
- Kein Code-Anfassen ohne Konzept-OK
Offene Frage(n)
Nur eine — alles andere ist konkret genug:
Q1: Vorschau-Knopf im Tool — wirklich nötig?
„▶ Vorschau abspielen" würde die ganze Timeline sequenziell durchspielen mit Subtitel-Anzeige. Kostet ~2 h Tool-Entwicklung. Alternative: du speicherst, öffnest /heli-game?mission=m1 in neuem Tab und hörst dort die echte Engine. Spart Aufwand, ist authentischer.
Mein Tipp: Vorschau weglassen. Echtes Spiel ist der wahre Test.
Wenn das Konzept passt, fange ich mit Schritt 2 (PHP-Endpoint) an. Sag „los".