S3: Gegner, Spatial Grid und weiche Separation #16
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
Blocked by: #14, #15
Gegner erscheinen am Rand, laufen radial auf den Turm zu — und das Spatial Grid aus ADR-0004 entsteht hier, weil es ab jetzt drei Konsumenten bedient.
Inhalt
Enemyträgt HP. Ein Archetyp genügt im Skelett; die drei bis vier aus der Kalibrierung kommen später.Akzeptanz
examples/perf_spike.rsgemessen hat — mit dem Grid-Aufschlag aus ADR-0004 von ≤ 0,10 ms bei 10 000 Gegnern. Nachmessen, nicht annehmen.Nicht in diesem Ticket: Wellen-Takt, Bosse, Gegner-Archetypen, Angriff auf den Turm.
Gebaut auf
slice/skeleton(0f93a93,f1b8586).Inhalt
src/enemy.rs— cap-getriebener Spawner, radiale Bewegung mit Stopp an der Angriffsreichweite, weiche Separation. Ein Archetyp,Healthals Component ohne Leser (#17).src/spatial.rs— Uniform Grid alsResource, Rebuild pro Frame, Zellgröße =max(Separationsradius, Trefferradius). Eine geteilte Abfragefor_each_in_radius, Narrow Phase inklusive.main.rsverdrahtet, nicht aus der Registrierungsreihenfolge geerbt.Balance-Werte, alle Platzhalter außerHARD_ENEMY_CAP.Akzeptanz
Zwei Funde gegen ADR-0004 — ADR geändert, nicht Code daran vorbeigebaut
1. Der Maßstab in §3 war falsch, die Schranke hält
Gemessen im Release-Profil bei
HARD_ENEMY_CAP, Median über 20 Läufe je System:move_enemiesrebuild_spatial_gridDer Rebuild ist rund 2,7x teurer als
move_enemies, nicht billiger. §3 zählt Arithmetik — zwei Divisionen und zweifloorgegen eine Normalisierung mit Wurzel — und übersieht, was hier dominiert:move_enemiesist ein linearer Lauf über eine Tabelle, der Rebuild schreibt in ~7 000 verstreuteVecs und zahlt Cache-Misses. DerVec-Push, den §3 als „Rest der Ersparnis" abtut, ist der Kostenpunkt.Die Entscheidung bleibt trotzdem stehen: Sie stand nie auf dem Vergleich, sondern auf der absoluten Schranke von 0,10 ms. 0,057 ms sind 0,34 % des Frame-Budgets. Und das inkrementelle Update wird dadurch nicht attraktiver — es bezahlt denselben verstreuten Schreibzugriff bei jedem Zellwechsel, und bei radialer Konvergenz wechseln ständig welche.
Geändert: Nachtrag zu ADR-0004 §3, Revisions-Auslöser 1 auf die absolute Schranke umgestellt (alte Fassung als solche vermerkt), dieselbe Korrektur an der Akzeptanz von Spec-Feature 3. Der Auslöser ist jetzt als laufender Check hinterlegt —
the_rebuild_stays_within_its_budget_at_the_hard_cap,cargo test --release -- --ignored --nocapture.Nachzumessen nach dem Wechsel auf echte Texturen und mit HUD, wie alle Zahlen aus #4.
2. §1 Ablage:
Vec<(Entity, Vec2)>stattVec<Entity>Die Position wird neben der
Entityim Bucket geführt. Grund ist die Separation aus §5: sie schreibtTransformund liest dabei dieTransforms ihrer Nachbarn. Mit bloßenEntitys müsste sie dieselbe Gegner-Query gleichzeitig lesend und schreibend halten — in Bevy nicht ausleihbar, und die Auswege (ParamSet, ein zweiter Puffer-Durchlauf) kosten mehr als einVec2je Eintrag. Ablage geändert, Entscheidung unberührt. Nachtrag in §1.Offen, gehört nicht hierher: ‹k›=8, ‹f›=0,5, Separationsradius 14 und Soll-Population 400 sind Startwerte. Sie findet nur Spielen, und der Beleg ist der Blick auf den Turmring — steht so in ADR-0004 und in der Spec unter „Offen".