Files
wds/artist.md
T
irrlichtandClaude Sonnet 5 fc3494466e Welt-Texturen aus der .glb statt aus assets/textures/
Der Loader zieht jetzt die baseColorTexture jedes Materials aus dem
BIN-Chunk und dekodiert sie (PNG, via png-Crate) → model::Texture mit
Pixeln. Die Namenskonvention "Materialname = Dateiname" und der
assets/textures/-Pfad für Welt-Texturen entfallen; assets/textures/
bleibt nur noch für UI/Fonts/Platzhalter.

- engine::image: neuer, geteilter RGBA8-Image-Typ (aus tga.rs gezogen)
  plus PNG-Decoder. tga.rs liefert weiter denselben Typ.
- gltf: material -> texture -> image -> bufferView auflösen, Bild aus
  BIN dekodieren; fehlt ein Glied, bleibt image None (Platzhalter).
  KHR_texture_transform (Blenders Mapping-Node) wird beim Laden in die
  UVs eingebacken.
- model::Model: materials: Vec<String> -> textures: Vec<Texture>.
- render: die Pixel je Schlüssel aus den Modellen sammeln (erstes
  Vorkommen gewinnt, Schlüssel ohne Bild -> Platzhalter).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0196AM4UyAJEXVtPvp5DdKr8
2026-09-02 00:29:46 +02:00

3.9 KiB

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 (anderer Ordner: cargo run -- --maps <dir>).
  • Beim Export anhaken: „Include → Custom Properties" (sonst fehlen die Properties unten) und „Include → Textures" / „Data → Images" (sonst fehlen die Texturen).
  • 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 — es wird beim Export in die .glb eingebettet und mitgeladen (kein assets/textures/ mehr). Format PNG (Export „Images: PNG" oder „Automatic"). 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 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 — 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 <name> feuert jedes Signal von Hand, reload lädt signals.toml neu.