Analog zur Ink-Pipeline: eine .blend neben ihrer .glb im Map-Ordner (assets/maps/<map>/<name>.blend) wird von tools/build-models.sh headless zu <name>.glb exportiert, inkrementell per mtime. build.rs stößt das beim cargo-Build an, sobald sich eine .blend geändert hat. - Export: blender -b --factory-startup ... export_scene.gltf mit export_extras (collide/signal/role), export_apply, yup, image AUTO. - Blender über $BLENDER oder PATH; fehlt es, wird der Schritt still übersprungen — die committeten .glb reichen zum Bauen/Spielen. - Ein Export-Fehler bei vorhandenem Blender ist fatal (wie bei Ink). - build.rs teilt sich jetzt run_script/watch-Helfer für beide Pipelines. - Cinemaroom.blend -> assets/maps/cinema/cinema.blend verschoben und die .glb einmal daraus gebaut. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0196AM4UyAJEXVtPvp5DdKr8
84 lines
4.1 KiB
Markdown
84 lines
4.1 KiB
Markdown
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
|
|
|
|
- **Ablage:** die `.blend` in ihren Map-Ordner legen —
|
|
`assets/maps/<map>/<name>.blend`. `cargo build` (oder
|
|
`./tools/build-models.sh`) exportiert sie zu `<name>.glb` daneben; von
|
|
Hand exportieren musst du nichts. Die Welt sind alle `.glb` unter
|
|
`assets/maps/props/`; ein anderer Ordner per `cargo run -- --maps <dir>`.
|
|
- **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.
|
|
- **Texturen:** Bild im Material als Base Color zuweisen (PNG) — es wird
|
|
beim Export in die `.glb` eingebettet. Damit die Datei self-contained
|
|
bleibt: „File → External Data → Pack Resources". Fehlt das Bild,
|
|
erscheint die Platzhalter-Textur.
|
|
- **Kacheln / Skalieren:** über einen **Mapping-Node** vor dem
|
|
Image-Texture-Node (Location/Scale). Die Engine backt das
|
|
(`KHR_texture_transform`) beim Laden in die UVs ein.
|
|
- **Custom Properties** (unten) kommen automatisch mit; Modifier werden
|
|
beim Export angewandt.
|
|
|
|
### 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 = <name>` **mit** collide | Klick-Ziel: Anklicken feuert das Signal `<name>` |
|
|
| `signal = <name>` **ohne** collide | unsichtbare Trigger-Zone: Betreten feuert `<name>` 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 = <name>` | Ambient-Loop `assets/sounds/<name>.wav` an dieser Position |
|
|
| `radius = <m>` | 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 <name>` (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 <datei>.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` — baut geänderte `.blend` neu und zeigt beim Start, was
|
|
ankam: Objekte, Dreiecke, Empties und **jede Custom Property**. Fehlt
|
|
eine, sitzt sie in Blender nicht am Objekt (Object Properties → Custom
|
|
Properties), nicht am Mesh-Data.
|
|
- Im Spiel (Konsole = das Terminal, aus dem gestartet wurde): `noclip` zum
|
|
freien Fliegen, `kv` zeigt alle Variablen, `signal <name>` feuert jedes
|
|
Signal von Hand, `reload` lädt signals.toml neu.
|