Alles Inhaltliche kommt aus vier Quellen: **Blender** (Welt), **Ink** (Dialoge/Story), **signals.toml** (Verdrahtung), **Assets-Ordner** (Texturen/Sounds). Fehler in Inhalten stürzen nie ab — sie werden beim Start in der Konsole gemeldet (`[model]`, `[audio]`, `[tex]`, …). ## 3D / Blender - **Format:** glTF Binary (`.glb`) nach `assets/maps/props/` — alle Dateien dort werden beim Start geladen. - **Beim Export anhaken:** „Include → Custom Properties" (sonst kommen keine der Properties unten an!). - **Maßstab:** 1 Blender-Meter = 1 Engine-Meter. Augenhöhe 1,6 m, Türen/Durchgänge ≥ 2 m hoch und ≥ 0,8 m breit denken. - **Material-Name = Textur-Name:** Material `holz` → `assets/textures/holz.tga`. Fehlt die Textur (oder das Material), erscheint die Platzhalter-Textur. - **Texturen:** TGA, unkomprimiert oder RLE, 24/32 bit. ### Custom Properties auf Mesh-Objekten | Property | Wirkung | |---|---| | *(keine)* | nur sichtbar, kein Anfassen | | `collide = 1` | sichtbar **und** solide (Spieler kollidiert mit der konvexen Hülle des Meshes — Dellen/Löcher werden überspannt) | | `collide = proxy` | unsichtbares Kollisionsvolumen (für Fein-Collider neben Sichtgeometrie) | | `signal = ` **mit** collide | Klick-Ziel: Anklicken feuert das Signal `` | | `signal = ` **ohne** collide | unsichtbare Trigger-Zone: Betreten feuert `` einmal (erneut erst nach Verlassen; „nur einmal überhaupt" selbst per KV-Flag bauen) | - `collide = 0` schaltet ab, ohne die Property zu löschen. - Objektname ist der Interact-Key: Blender-Suffixe (`Ding.001`) werden beim Signal-Lookup automatisch gestrippt — `[Ding]` in signals.toml trifft alle. ### Custom Properties auf Empties | Property | Wirkung | |---|---| | `role = spawn` | Spieler-Startpunkt (Fußpunkt = Empty-Position) | | `sound = ` | Ambient-Loop `assets/sounds/.wav` an dieser Position | | `radius = ` | Hörradius des Sounds (linear leiser bis Stille; Default 8) | ## Audio - **Format:** WAV, **mono, 16 bit, 44100 Hz** — nichts anderes. Ablage in `assets/sounds/`, angesprochen ohne Endung (`pickup` → `pickup.wav`). - **Ambient:** per Empty (siehe oben), loopt immer — Loop-Punkt sauber schneiden. - **Einmal-SFX:** per Action `play_sound ` (aus signals.toml oder Ink-Tag). ## Dialoge / Ink - `.ink` nach `assets/interactions/` — wird beim Build automatisch kompiliert (bei Bedarf von Hand: `./tools/build-dialogues.sh`). - Gestartet per Action `start_ink .ink.json`. - **Variablen:** alle Ink-`VAR` landen automatisch im Spiel-KV und synchen in beide Richtungen — `_`-Prefix (`VAR _tmp = 0`) bleibt Ink-lokal. - **Tags feuern Actions:** `# set has_key true`, `# play_sound klick`, `# mode play` … (gleiche Verben wie signals.toml). Unbekannte Tags sind erlaubt (reine Metadaten). ## signals.toml (`assets/signals.toml`) - Verdrahtet Signal → Aktionen. Signal-Namen: Objektname (Klick), Wert der `signal`-Property (Zonen/Klick-Ziele), oder frei (aus Ink). - Verben: `start_ink`, `set`, `inc`, `clear`, `debug_log`, `play_sound`, `mode play|free|menu`. - `$self` = auslösender Objektname (für generische Einträge wie `set $self true`). - `[init]` feuert einmal beim Start — Ort für KV-Defaults. ## Testen - `cargo run` — Konsole zeigt beim Start, was ankam: Objekte, Dreiecke, Empties und **jede Custom Property**. Fehlt eine → Export-Haken prüfen. - Im Spiel (Konsole = das Terminal, aus dem gestartet wurde): `noclip` zum freien Fliegen, `kv` zeigt alle Variablen, `signal ` feuert jedes Signal von Hand, `reload` lädt signals.toml neu.