ADR: Wo leben Balancing-Daten — Code oder Assets? #5

Closed
opened 2026-08-10 07:58:32 +00:00 by RDietermann · 1 comment
Owner

Part of #1
Blocked by: #3

Entscheidung plus ADR unter docs/adr/.

Die Frage: Wellenkurven, Upgrade-Kosten, Gegner-Stats und Card-Effekte — als Rust-Konstanten im Code, oder als Daten-Assets (RON/TOML) über den AssetServer?

Abwägung: Iterationsgeschwindigkeit beim Balancing (Hot-Reload) gegen Typsicherheit und einen Build-Schritt weniger. Für ein Lernprojekt zählt zusätzlich, was man beim Bauen lernt.

Fertig, wenn die ADR die Entscheidung, die verworfene Alternative und den Auslöser für eine spätere Revision benennt.

Part of #1 Blocked by: #3 Entscheidung plus ADR unter `docs/adr/`. **Die Frage**: Wellenkurven, Upgrade-Kosten, Gegner-Stats und Card-Effekte — als Rust-Konstanten im Code, oder als Daten-Assets (RON/TOML) über den `AssetServer`? **Abwägung**: Iterationsgeschwindigkeit beim Balancing (Hot-Reload) gegen Typsicherheit und einen Build-Schritt weniger. Für ein Lernprojekt zählt zusätzlich, was man beim Bauen lernt. **Fertig, wenn** die ADR die Entscheidung, die verworfene Alternative und den Auslöser für eine spätere Revision benennt.
RDietermann added the wayfinder:task label 2026-08-10 07:58:32 +00:00
RDietermann changed title from ADR: Wo leben Balancing-Daten - Code oder Assets? to ADR: Wo leben Balancing-Daten — Code oder Assets? 2026-08-10 08:00:35 +00:00
Author
Owner

Entschieden: Rust-Konstanten in einem Modul balance, das eine Balance-Resource befüllt. Gameplay-Systeme lesen ausschließlich Res<Balance> und sehen die Konstanten nie — damit ist genau eine Funktion die Naht für einen späteren Asset-Ladepfad.

ADR in docs/adr/0001-balancing-daten-als-rust-konstanten.md.

Die Entscheidung steht auf gemessenen Zahlen, nicht auf Bauchgefühl:

Vorgang Zeit
Inkrementeller Rebuild --release 9–10 s
Inkrementeller Rebuild dev 22–26 s
Prozessstart bis Frames ~1,4 s
Edit-to-see-Loop ~11 s

Der überraschende Befund: Release baut schneller als Debug — das Linken der Debug-Info dominiert. Damit ist das stärkste Argument für Hot-Reload empirisch widerlegt, nämlich die Annahme, Balancing brauche Release und der Rebuild sei deshalb teuer. Und der teure Teil eines Tuning-Zyklus ist ohnehin nicht der Build, sondern das Spielen: eine Wellenkurve bewertet man, indem man von Welle 1 an spielt. Die 11 s sind ein einstelliger Prozentsatz davon.

Verworfen:

  • Konstanten verstreut im Gameplay-Code — gleiche Iterationskosten, aber ein späterer Wechsel fasst jedes System an.
  • Daten-Assets über den AssetServer — Bevy 0.19 hat keinen eingebauten generischen Daten-Loader, ein eigener AssetLoader ist Pflicht. Hot-Reload braucht das nicht-default Feature file_watcher, das notify nachzieht und nur auf Desktop läuft. Auf Wasm gibt es keinen Dateisystem-Watcher.
  • bevy_common_assets — spart nur den Loader-Code, nicht die übrigen Kosten.
  • Umgebungsvariablen wie in examples/perf_spike.rs — trägt für Spike-Knöpfe, nicht für 50-Level-Tabellen.

Revisions-Auslöser, bewusst als beobachtbare Ereignisse formuliert statt als Gefühl: (1) Release-Rebuild nach reiner src/balance/-Änderung überschreitet wiederholt 30 s, (2) eine protokollierte Tuning-Session enthält mehr als 30 Rebuild-Zyklen pro Stunde mit Diff nur in src/balance/, oder (3) Balancing muss ohne Rust-Toolchain änderbar sein. Bei (1) und (2) ist zuerst ein Debug-Panel die Antwort, erst danach Assets; (3) führt direkt zu Assets.

Zwei Folgeaufgaben sind in der ADR vermerkt, aber nicht umgesetzt: Run-Telemetrie und ein Debug-Panel mit Sprung-zu-Welle sind der eigentliche Hebel für Balancing-Iteration. Beide setzen auf der hier festgelegten Naht auf und gehören zu #8.

**Entschieden: Rust-Konstanten in einem Modul `balance`, das eine `Balance`-Resource befüllt.** Gameplay-Systeme lesen ausschließlich `Res<Balance>` und sehen die Konstanten nie — damit ist genau eine Funktion die Naht für einen späteren Asset-Ladepfad. ADR in `docs/adr/0001-balancing-daten-als-rust-konstanten.md`. **Die Entscheidung steht auf gemessenen Zahlen, nicht auf Bauchgefühl:** | Vorgang | Zeit | |---|---| | Inkrementeller Rebuild `--release` | 9–10 s | | Inkrementeller Rebuild `dev` | 22–26 s | | Prozessstart bis Frames | ~1,4 s | | **Edit-to-see-Loop** | **~11 s** | Der überraschende Befund: **Release baut schneller als Debug** — das Linken der Debug-Info dominiert. Damit ist das stärkste Argument für Hot-Reload empirisch widerlegt, nämlich die Annahme, Balancing brauche Release und der Rebuild sei deshalb teuer. Und der teure Teil eines Tuning-Zyklus ist ohnehin nicht der Build, sondern das Spielen: eine Wellenkurve bewertet man, indem man von Welle 1 an spielt. Die 11 s sind ein einstelliger Prozentsatz davon. **Verworfen:** - Konstanten verstreut im Gameplay-Code — gleiche Iterationskosten, aber ein späterer Wechsel fasst jedes System an. - Daten-Assets über den `AssetServer` — Bevy 0.19 hat **keinen** eingebauten generischen Daten-Loader, ein eigener `AssetLoader` ist Pflicht. Hot-Reload braucht das nicht-default Feature `file_watcher`, das `notify` nachzieht und nur auf Desktop läuft. Auf Wasm gibt es keinen Dateisystem-Watcher. - `bevy_common_assets` — spart nur den Loader-Code, nicht die übrigen Kosten. - Umgebungsvariablen wie in `examples/perf_spike.rs` — trägt für Spike-Knöpfe, nicht für 50-Level-Tabellen. **Revisions-Auslöser**, bewusst als beobachtbare Ereignisse formuliert statt als Gefühl: (1) Release-Rebuild nach reiner `src/balance/`-Änderung überschreitet wiederholt 30 s, (2) eine protokollierte Tuning-Session enthält mehr als 30 Rebuild-Zyklen pro Stunde mit Diff nur in `src/balance/`, oder (3) Balancing muss ohne Rust-Toolchain änderbar sein. Bei (1) und (2) ist zuerst ein Debug-Panel die Antwort, erst danach Assets; (3) führt direkt zu Assets. **Zwei Folgeaufgaben** sind in der ADR vermerkt, aber nicht umgesetzt: Run-Telemetrie und ein Debug-Panel mit Sprung-zu-Welle sind der eigentliche Hebel für Balancing-Iteration. Beide setzen auf der hier festgelegten Naht auf und gehören zu #8.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RDietermann/InfiniTower#5