S1: Projekt-Gerüst, Arena, Kamera, Turm #14
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #13
Das Gerüst, in dem alles andere hängt.
src/main.rsist nochHello, world!.Inhalt
DefaultPlugins, Fenster, orthographische Kamera.AppState-Enum mit mindestensRunundMeta. Der Zustandswechsel ist der Ort, an dem später Run-Start und Run-Ende hängen — er muss von Anfang an da sein, sonst wird er nachträglich überall eingefädelt.Towerin der Mitte, Programmer-Art (farbige Sprites, keine Assets).Rungespawnt und beim Verlassen despawnt (ADR-0002 §6). Das ist keine Optimierung, sondern die Grundlage dafür, dass am Run-Ende nichts aufgeräumt werden muss.balancebleibt frei von Gameplay-Logik, Gameplay liest später nurRes<Balance>.Akzeptanz (aus Spec Feature 1)
EffectiveStats— im Skelett genügt: keineTower-Entity.Meta → Run → Metalässt keine Entity zurück, nachweisbar über einen Zähler oder eindebug_assert.Nicht in diesem Ticket: Gegner, Schießen, HUD, Wellen. Nur das Gerüst.
Gebaut.
src/main.rs,src/balance/{mod,values}.rs,src/arena.rs,src/tower.rs— 392 Zeilen, keine neuen Dependencies.Nachgeprüft, nicht geglaubt
cargo clean -p infinitowerplus vollständiger Rebuild: null Warnungen.cargo test:tower::tests::meta_run_meta_leaves_nothing_behindgrün.DespawnOnExitschlägt er fehl (left: 1, right: 0), danach wiederhergestellt und wieder grün. Er ist nicht vakuant.Zwei Dinge, die besser sind als beauftragt
ADR-0001 ist compilerdurchgesetzt, nicht nur per Konvention. Die Konstanten in
values.rssindpub(super);Balance::from_constants()ist der einzige Weg heraus. Die Regel „kein Gameplay liest eine Konstante" lässt sich damit nicht versehentlich brechen, sondern nur absichtlich.ADR-0002 §6 wird von einem Bevy-Built-in erfüllt. Statt eines Aufräum-Systems trägt die Turm-Entity
DespawnOnExit(AppState::Run). Die ADR forderte „kein Aufräum-Code, den man beim nächsten Feature erweitern müsste" — hier gibt es kein System, das man falsch einordnen oder vergessen könnte. Der Test zählt außerdem alle Entities, nicht nur Türme, und fängt damit auch künftige run-gebundene Entities, die jemand ohne Run-Bindung spawnt.Statt
#[allow(dead_code)]steht#[expect(dead_code, reason = "read by the gameplay tickets #16-#18")]ambalance-Modul — der Compiler fordert die Zeile zurück, sobald das letzte Feld einen Leser hat.Platzhalterwerte
arena.radiusperf_spike.rsenemy.speedperf_spike.rsenemy.healthtower.damagetower.attack_intervaltower.healthcombat.hit_radiusperf_spike.rsmeta.gain_per_killAlle acht sind im Code als
PLACEHOLDERausgezeichnet.Vier Befunde des Agenten, zur Kenntnis
AppState::Runist Default, damitcargo runohne Tastendruck einen sichtbaren Turm zeigt. Die Alternative — imStartupheimlichNextStatesetzen — verschluckt dasOnEnter(Meta)des ersten Frames und fiele bei #18 still auf die Füße. Mit// ponytail:markiert, Umdrehen ist eine Zeile und gehört zu #18.Balance.capsist ein leeres Struct. ADR-0002 §2 verlangt einen Cap je geclamptem Stat — die fünf betroffenen Stats existieren im Skelett noch nicht. Der Bereich ist benannt und erreichbar, nur ohne Felder. Vertagung, kein Widerspruch.tower.attack_intervalin Sekunden, weilmultsonst kein Teiler auf eine Dauer sein kann. Das Ticket-Wording ist überholt, nicht der Code — genau die Reihenfolge, die die Karte vorgibt.type Stat = f32liegt vorerst inbalance. ADR-0002 §4 definiert den Alias, ordnet ihn keinem Modul zu. Wenn die Stat-Pipeline kommt, gehört er vermutlich in ein eigenesstats-Modul.Der eine Punkt, der weiterwandert
meta.gain_per_killist ein flacher Betrag pro Kill — die Spec sagt aber, der Meta-Ertrag ist drop-basiert: Chance je Normalgegner, garantiert je Boss, Menge wellenabhängig. Das ist eine andere Mechanik, nicht bloß eine andere Zahl.Für ein Skelett ohne Wellen und ohne Bosse ist der flache Wert das einzig Baubare, und der Agent hat die Abweichung am Konstanten-Doc vermerkt statt sie zu verschlucken. Damit sie nicht zur stillschweigenden Mechanikentscheidung gegen die Spec wird, ist sie als ausdrückliche Auflage an #18 gehängt.