Files
wds/build.rs
T
irrlichtandClaude Sonnet 5 331caf417a Blender-Welten aus der .blend im Map-Ordner bauen
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
2026-09-02 00:53:29 +02:00

83 lines
3.6 KiB
Rust

//! Build-Hook: baut geänderte Assets automatisch beim Cargo-Build.
//!
//! Reines „Wann"-Stück — das eigentliche Bauen machen die Skripte unter
//! `tools/` (und bleiben von Hand aufrufbar). Hier melden wir Cargo nur, wann
//! es uns erneut ausführen soll, und stoßen die Skripte an:
//!
//! * `build-dialogues.sh` — `.ink` → `.ink.json` (inklecate)
//! * `build-models.sh` — `assets/maps/**/*.blend` → `.glb` (Blender)
//!
//! Cargo führt build.rs ausschließlich dann erneut aus, wenn eine der unten
//! via `rerun-if-changed` gemeldeten Dateien sich ändert. Unveränderte
//! Rebuilds kosten also nichts; nur nach einer Quell-Änderung läuft das
//! jeweilige Werkzeug (beide Skripte bauen intern inkrementell).
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
// --- Ink-Dialoge ------------------------------------------------------
println!("cargo:rerun-if-changed=tools/build-dialogues.sh");
println!("cargo:rerun-if-changed=tools/inklecate");
// Verzeichnis-mtime fängt neu hinzugekommene/gelöschte .ink-Dateien.
println!("cargo:rerun-if-changed=assets/interactions");
watch_ext(&root.join("assets/interactions"), "ink");
run_script(&root, "tools/build-dialogues.sh", "Dialog");
// --- Blender-Welten -------------------------------------------------
println!("cargo:rerun-if-changed=tools/build-models.sh");
// Ordner-mtime fängt neue/gelöschte Maps; die .blend selbst einzeln.
// Die erzeugten .glb werden NICHT beobachtet (das Skript schreibt sie).
watch_dirs_and_ext(&root.join("assets/maps"), "blend");
run_script(&root, "tools/build-models.sh", "Modell");
}
/// Jede Datei mit Endung `ext` direkt in `dir` einzeln bei Cargo anmelden.
fn watch_ext(dir: &Path, ext: &str) {
let Ok(entries) = std::fs::read_dir(dir) else { return };
for entry in entries.flatten() {
let p = entry.path();
if p.extension().and_then(|s| s.to_str()) == Some(ext) {
println!("cargo:rerun-if-changed={}", p.display());
}
}
}
/// Wie [`watch_ext`], aber rekursiv — und jedes Unterverzeichnis wird selbst
/// beobachtet (fängt neu angelegte/entfernte Maps).
fn watch_dirs_and_ext(dir: &Path, ext: &str) {
let Ok(entries) = std::fs::read_dir(dir) else { return };
println!("cargo:rerun-if-changed={}", dir.display());
for entry in entries.flatten() {
let p = entry.path();
if p.is_dir() {
watch_dirs_and_ext(&p, ext);
} else if p.extension().and_then(|s| s.to_str()) == Some(ext) {
println!("cargo:rerun-if-changed={}", p.display());
}
}
}
/// Ein `tools/`-Skript laufen lassen. Ausgabe einsammeln (Cargo blendet
/// Build-Script-stdout sonst aus); Fehlschlag ist fatal, ein nicht startbares
/// bash nur eine Warnung — die committeten Artefakte reichen dann.
fn run_script(root: &Path, rel: &str, label: &str) {
let script = root.join(rel);
match Command::new("bash").arg(&script).output() {
Ok(out) if out.status.success() => { /* still bei Erfolg — Detail via Hand-Aufruf */ }
Ok(out) => {
let stdout = String::from_utf8_lossy(&out.stdout);
let stderr = String::from_utf8_lossy(&out.stderr);
for line in stdout.lines().chain(stderr.lines()) {
println!("cargo:warning={line}");
}
panic!("{label}-Build fehlgeschlagen — siehe Warnungen oben. Einzeln debuggen: ./{rel}");
}
Err(e) => {
println!("cargo:warning={label}-Build übersprungen ({e}). Bei Bedarf von Hand: ./{rel}");
}
}
}