docs: add ADR-0004 spatial grid, fix Fraction stat mode, extend spec
This commit is contained in:
@@ -6,8 +6,9 @@
|
||||
wir erkennen, dass es fertig ist
|
||||
- **Baut auf:** [ADR-0001](adr/0001-balancing-daten-als-rust-konstanten.md) (Balancing-Daten),
|
||||
[ADR-0002](adr/0002-stat-und-modifier-pipeline.md) (Stat- und Modifier-Pipeline),
|
||||
[ADR-0003](adr/0003-save-format-ort-und-migration.md) (Save-Format), `CONTEXT.md` (Glossar und
|
||||
Slice-Scope), Karte in Issue #1
|
||||
[ADR-0003](adr/0003-save-format-ort-und-migration.md) (Save-Format),
|
||||
[ADR-0004](adr/0004-spatial-grid-fuer-gegner-nachbarschaft.md) (Spatial Grid und weiche
|
||||
Separation), `CONTEXT.md` (Glossar und Slice-Scope), Karte in Issue #1
|
||||
- **Vokabular:** verbindlich aus `CONTEXT.md`. Diese Spec führt keine neuen Begriffe ein, außer den
|
||||
beiden in Abschnitt „Zwei Grenzwerte, zwei Begriffe" ausgewiesenen.
|
||||
|
||||
@@ -71,10 +72,13 @@ Alles hier ist entschieden. Alles andere ist ‹Platzhalter› oder steht unter
|
||||
| Card-Slots | Start **1**, Wachstum auf **5**; die Slot-Zahl ist selbst Progression | #11 |
|
||||
| Card-Quelle | Drop aus Fortschritt (Boss-Kill, neuer Wellen-Rekord). Kein Kauf, keine dritte Währung | #11 |
|
||||
| Card-Randbedingungen | Slot 2 fällt **früh** (erste paar Runs); **mindestens zwei Epics** | #11 |
|
||||
| Slot-Quelle | **Kauf aus der Meta-Währung im Workshop**, exponentiell wachsende Kosten wie bei den Stat-Upgrades. Kein zweiter Freischalt-Mechanismus, keine Meilenstein-Schwelle | diese Spec (löst Widerspruch 2) |
|
||||
| Utility-Tab | **Ökonomie-Upgrades, keine Kampf-Stats** — vier Zeilen, siehe Feature 6 | #3-Kalibrierung, `docs/WikiData.md`; diese Spec (löst Widerspruch 5) |
|
||||
| Gegner-gegen-Gegner | **Spatial Grid mit weicher Separation**; dasselbe Grid trägt Zielauswahl, Reichweiten-Scan und Projektil-Kollision | ADR-0004 (löst Lücke 9) |
|
||||
| Ultimate | genau eine: **Death Wave**, radialer Sweep, automatisch ausgelöst | #9 |
|
||||
| Auslöse-Regel | **Cooldown UND ein Weltzustand**, je Fähigkeit fest verdrahtet, nicht einstellbar; feuern mehrere gleichzeitig, feuern alle | #12 |
|
||||
| Währungen | zwei: `Coins` (In-Run, verfällt) und die Meta-Währung (Workshop). Nicht ineinander konvertierbar | Issue #1, #11 |
|
||||
| Turm-Stats | 12, siehe Tabelle in ADR-0002 §3 | ADR-0002 |
|
||||
| Turm-Stats | 16, siehe Tabelle in ADR-0002 §3 samt Nachtrag vom 2026-08-10 | ADR-0002 |
|
||||
|
||||
**Prüfkriterium für die fertige Kurve** (#8, gilt für die vier freien Zahlen):
|
||||
|
||||
@@ -122,6 +126,14 @@ Der Spawner ist **cap-getrieben, nicht plan-getrieben**: er füllt bis zur `targ
|
||||
auf, statt N Gegner nach Zeitplan zu setzen (Cap-Analyse, Issue #1). Gegner laufen radial von außen
|
||||
auf den Turm zu und greifen ihn im Nahbereich an.
|
||||
|
||||
Gegner **stapeln nicht frei übereinander**: Sie drücken sich weich auseinander, nach
|
||||
[ADR-0004](adr/0004-spatial-grid-fuer-gegner-nachbarschaft.md). Das ist keine Kollisionsauflösung —
|
||||
Überlappung bleibt erlaubt, verboten ist nur, dass tausende Sprites am Turmring deckungsgleich
|
||||
liegen und die Soll-Population unlesbar machen. Der Versatz ist auf einen Bruchteil des
|
||||
Bewegungsschritts geklemmt und kann den radialen Anlauf deshalb nie umkehren. Die Nachbarschaft
|
||||
kommt aus dem `SpatialGrid`, das einmal pro Frame neu gebaut wird und außerdem Feature 4, das
|
||||
Auslöse-System und die Projektil-Kollision bedient.
|
||||
|
||||
**Akzeptanz**
|
||||
- Bei laufender Spawn-Phase pendelt die Zahl lebender Gegner um `target_population(wave)`, mit einer
|
||||
Abweichung von höchstens ‹±10 %› über ein 5-Sekunden-Fenster.
|
||||
@@ -129,6 +141,12 @@ auf den Turm zu und greifen ihn im Nahbereich an.
|
||||
Sprung-zu-Welle auf die höchste im Debug-Panel erreichbare Welle.
|
||||
- Bei 10 000 gleichzeitigen Gegnern bleibt die Frametime unter 16,67 ms (Nachmessung mit dem Aufbau
|
||||
aus `examples/perf_spike.rs`, nach dem Wechsel auf echte Sprites zu wiederholen).
|
||||
- Der Rebuild des `SpatialGrid` kostet bei 10 000 Gegnern **nicht mehr als `move_enemies` im selben
|
||||
Frame** (ADR-0004 §3 — die Entscheidung gegen ein inkrementelles Update steht auf dieser Annahme;
|
||||
reißt sie, ist die ADR fällig, nicht die Zahl).
|
||||
- Kein Gegner bewegt sich in einem Frame vom Turm **weg**, solange ihn keine Fähigkeit dorthin
|
||||
drückt — die Separationsklemmung macht das konstruktiv unmöglich, und der Turmring pulsiert
|
||||
sichtbar nicht.
|
||||
- Jeder Archetyp ist an Sprite-Farbe oder -Form ohne Text unterscheidbar.
|
||||
|
||||
### 4. Turm-Dauerfeuer und geteilter Reichweiten-Scan
|
||||
@@ -138,23 +156,37 @@ den Reichweiten-Zustand; `tower_fire` und **alle** Auslöse-Bedingungen (Feature
|
||||
Ergebnis. Das ist keine Optimierung für später, sondern die Bedingung, unter der die
|
||||
Auslöse-Entscheidung aus #12 tragfähig ist.
|
||||
|
||||
Der Reichweiten-Zustand und die Zielauswahl sind **Abfragen an das `SpatialGrid`**, kein linearer
|
||||
Durchlauf über die Gegner (ADR-0004). #12 hat die siebenfache Ausführung desselben Scans beseitigt;
|
||||
ADR-0004 beseitigt, dass der eine verbleibende Scan noch O(n) ist — die Zielauswahl läuft
|
||||
zellenweise von der Turmmitte nach außen und bricht beim ersten Treffer ab. Damit gilt eine
|
||||
schärfere Regel als bisher: **Genau ein System durchläuft die Gegnermenge, und das ist der
|
||||
Grid-Rebuild.**
|
||||
|
||||
**Akzeptanz**
|
||||
- Bei mindestens einem Gegner in Reichweite feuert der Turm ohne jede Eingabe innerhalb von
|
||||
`EffectiveStats.AttackInterval` Sekunden.
|
||||
- Ohne Gegner in Reichweite feuert er nicht.
|
||||
- Es existiert genau ein System, das die Gegnermenge in Turm-Reichweite bestimmt; ein `grep` nach
|
||||
einem zweiten Reichweiten-Scan über die Gegner-Query findet keinen.
|
||||
- Es existiert genau ein System, das die Gegnermenge in Turm-Reichweite bestimmt, und es fragt das
|
||||
`SpatialGrid`; ein `grep` nach einem zweiten Reichweiten-Scan über die Gegner-Query findet keinen.
|
||||
- **Außer `rebuild_spatial_grid` iteriert kein System die Gegner-Query, um Nachbarn zu finden** —
|
||||
weder die Separation, noch `tower_fire`, noch das Auslöse-System, noch die Projektil-Kollision
|
||||
(ADR-0004 §6).
|
||||
|
||||
### 5. Stat- und Modifier-Pipeline
|
||||
|
||||
Vollständig nach [ADR-0002](adr/0002-stat-und-modifier-pipeline.md): drei Akkumulatoren (`flat`,
|
||||
`points`, `mult`), ein `Direct`/`Interval`-Bit je Stat, Clamp einmal auf die Summe, `EffectiveStats`
|
||||
als `Component` an der Turm-Entity, Neuberechnung bei Änderung. `type Stat = f32`. Alle Zahlen aus
|
||||
`Res<Balance>` (ADR-0001).
|
||||
`points`, `mult`), ein Modus-Feld je Stat mit den drei Varianten `Direct` / `Interval` /
|
||||
`Fraction`, Clamp einmal auf die Prozentpunkt-Summe, `EffectiveStats` als `Component` an der
|
||||
Turm-Entity, Neuberechnung bei Änderung. `type Stat = f32`. Alle Zahlen aus `Res<Balance>`
|
||||
(ADR-0001).
|
||||
|
||||
**Akzeptanz**
|
||||
- Das durchgerechnete Beispiel aus ADR-0002 („Durchgerechnetes Beispiel") ist als Test hinterlegt
|
||||
und grün — mit den dort genannten Platzhalterwerten, nicht mit den späteren echten.
|
||||
und grün — mit den dort genannten Platzhalterwerten, nicht mit den späteren echten. Das schließt
|
||||
den **Crit-Chance-Fall** ein: Drei Quellen mit zusammen 37 pp ergeben 37 %, nicht 0.
|
||||
- Kein Stat im Modus `Direct` hat `base = 0` und `points` als einzige erwartete Quelle
|
||||
(ADR-0002 §1, Prüfregel 3) — prüfbar an der Stat-Tabelle, ohne das Spiel zu starten.
|
||||
- Nach einer Änderung an `Workshop`, `EquippedCards` oder `RunUpgrades` läuft die Neuberechnung
|
||||
genau einmal; ohne Änderung läuft sie nicht (nachweisbar über einen Zähler im Debug-Panel).
|
||||
- `sync_tower_abilities` ist der einzige Schreiber von Fähigkeits-Components; sein `debug_assert`
|
||||
@@ -171,6 +203,28 @@ kauft der Spieler In-Run-Upgrades in drei Tabs (Attack / Defence / Utility), jed
|
||||
(Buy x1). Alle verfallen am Run-Ende, weil sie als `RunUpgrades`-Component an der Turm-Entity hängen
|
||||
(ADR-0002 §6).
|
||||
|
||||
**Der Utility-Tab trägt Ökonomie-Upgrades, keine Kampf-Stats.** Das ist keine Verlegenheitslösung,
|
||||
sondern das, was Utility im Referenzspiel ist: ein Ökonomie-Multiplikator (Kalibrierungsbericht in
|
||||
#3; `docs/WikiData.md`, Workshop-Abschnitt, listet dort Cash Bonus, Cash/Wave, Coins/Kill Bonus und
|
||||
Free Upgrades). Vier Zeilen, jede mit ihrem Grund:
|
||||
|
||||
| Zeile | Stat | Warum sie da ist |
|
||||
|---|---|---|
|
||||
| Coin-Ertrag pro Kill | `CoinGain` | der Grundkanal — Einkommen skaliert linear mit Kills und damit mit der Soll-Population; ohne ihn hat der Tab keinen Anker |
|
||||
| Coins am Wellenende | `CoinsPerWave` | der einzige Ertrag, der **nicht** mit der Gegnerdichte wächst. Die Cap-Analyse (#1) verlangt, die Economy gegen *Kills pro Welle* zu normieren statt gegen Wellen — ein wellengebundener Sockel ist der Gegenpol dazu und trägt früh, wenn die Population noch klein ist |
|
||||
| Coin-Bonus auf Crit-Kills | `CritCoinGain` | koppelt Utility an Attack: Er ist wertlos, solange `CritChance` bei 0 steht, und wird stark, sobald der Attack-Tab bedient wurde. Genau das macht die Kaufreihenfolge zu einer Entscheidung statt zu einer Sortierung (#8, siehe Akzeptanz unten) |
|
||||
| Chance auf ein kostenloses Upgrade | `FreeUpgradeChance` | der einzige Utility-Effekt, der in die anderen Tabs zurückwirkt: Er kauft nicht Coins, sondern **Zeit**, und wirkt damit direkt auf die Tuning-Zielgröße „Zeit zwischen zwei bezahlbaren Käufen". Eine Auswertung je Wellenende, ein kostenloses Level in einem zufällig gewählten Tab — das Original hat drei getrennte Stats dafür, #3 empfiehlt für Utility ausdrücklich „stark vereinfachen" |
|
||||
|
||||
Die vier Stats stehen in ADR-0002 §3 (Nachtrag). **`MetaGain` gehört ausdrücklich nicht in diesen
|
||||
Tab**: Ein aus `Coins` gekaufter Multiplikator auf die Meta-Währung wäre ein Konvertierungspfad
|
||||
zwischen den beiden Währungen, und den schließt Issue #1 aus. `MetaGain` ist ein Workshop-Upgrade
|
||||
(Feature 10).
|
||||
|
||||
Damit stehen im Panel 5 Attack-, 4 Defence- und 4 Utility-Zeilen — **13 von den ~24 Zeilen, die das
|
||||
Layout hergibt.** Die Folgerung des HUD-Kommentars „der Spieler kann in einem Run nicht alles
|
||||
kaufen" trägt deshalb nicht mehr aus dem Layout; sie muss aus den Kosten kommen oder gar nicht
|
||||
(siehe „Widersprüche", Punkt 5).
|
||||
|
||||
**Akzeptanz**
|
||||
- Ein Kauf ist zu jedem Zeitpunkt eines laufenden Runs möglich, auch mitten in der Spawn-Phase, ohne
|
||||
dass die Simulation anhält.
|
||||
@@ -182,6 +236,10 @@ kauft der Spieler In-Run-Upgrades in drei Tabs (Attack / Defence / Utility), jed
|
||||
- Kosten und Wirkung unterscheiden sich zwischen den drei Tabs merklich genug, dass die
|
||||
Telemetrie über zehn Runs **nicht** dieselbe Kaufreihenfolge zeigt (#8: sonst ist die
|
||||
Kaufreihenfolge eine Sortierung, keine Entscheidung).
|
||||
- Der Utility-Tab enthält **keinen** Kauf, der die Meta-Währung, ihre Drop-Chance oder ihre Menge
|
||||
verändert — kein Pfad im Run wandelt `Coins` in Meta-Fortschritt.
|
||||
- Jede der vier Utility-Zeilen hat die Sichtbarkeitsanforderung aus ADR-0002 §11 durchlaufen; für
|
||||
`CritCoinGain` liegt die dort zu nennende Fortschritts-Stelle **hinter** dem ersten Crit-Kauf.
|
||||
|
||||
### 7. Auslöse-System für Fähigkeiten
|
||||
|
||||
@@ -197,7 +255,8 @@ Priorität.
|
||||
- Sind zwei Fähigkeiten im selben Frame auslösebereit, feuern beide im selben Frame.
|
||||
- Die Bedingungswerte stehen in `Balance` und sind über das Debug-Panel zur Laufzeit änderbar; keine
|
||||
Schwelle steht als Literal im Gameplay-Code (ADR-0001 §4).
|
||||
- Das System liest den Reichweiten-Zustand aus Feature 4 und führt keinen eigenen Scan aus.
|
||||
- Das System liest den Reichweiten-Zustand aus Feature 4 und führt keinen eigenen Scan aus — weder
|
||||
über die Gegner-Query noch als eigene Abfrage am `SpatialGrid` (ADR-0004 §6).
|
||||
|
||||
### 8. Ultimate: Death Wave
|
||||
|
||||
@@ -221,6 +280,13 @@ kaufbar und haben keine eigene Währung. Eine Card ist entweder ein Stat-Modifik
|
||||
**Fähigkeit** (`CardEffect::Modifier` / `CardEffect::Ability`, ADR-0002 §8) — Fähigkeits-Cards feuern
|
||||
über dasselbe System wie die Ultimate. Drei Seltenheiten, Slots von 1 auf 5.
|
||||
|
||||
**Slots werden im Workshop aus der Meta-Währung gekauft** (Feature 10) — sie stehen dort neben den
|
||||
Stat-Upgrades, mit derselben exponentiellen Kostenform. Es gibt keinen zweiten Freischalt-Weg: keine
|
||||
Wellen-Meilensteine, keine Boss-Zahl, keinen Drop. Cards selbst bleiben unverkäuflich und fallen
|
||||
weiter als Drop; gekauft wird nur die **Breite** des Loadouts. Damit ist die eigentliche
|
||||
Meta-Entscheidung des Slice ausgesprochen: Breite (ein Slot mehr) gegen Stärke (ein Stat-Level
|
||||
mehr), aus demselben Topf.
|
||||
|
||||
Das **Loadout steht vor dem Run fest**. Im laufenden Run sind Cards über den Pause-Button nur
|
||||
einsehbar, nicht wechselbar (Issue #1). Damit wird im laufenden Run nie eine Fähigkeits-Component
|
||||
entfernt (ADR-0002 §10, Nachtrag zu #6).
|
||||
@@ -233,14 +299,28 @@ entfernt (ADR-0002 §10, Nachtrag zu #6).
|
||||
eine abgelegte erzeugt keine.
|
||||
- Während eines Runs ändert sich `EquippedCards` nicht — kein Pfad in der UI erlaubt es.
|
||||
- Der Card-Pool enthält mindestens zwei Epics, und Slot 2 ist innerhalb der ersten ‹drei› Runs
|
||||
erreichbar (#11; beide Bedingungen sind an das Abnahmekriterium des Slice gebunden).
|
||||
**bezahlbar** (#11; beide Bedingungen sind an das Abnahmekriterium des Slice gebunden).
|
||||
- Es gibt genau einen Pfad, der `card_slots` erhöht, und der ist ein Workshop-Kauf; kein Boss-Kill,
|
||||
kein Wellen-Rekord und kein Drop verändert die Slot-Zahl.
|
||||
|
||||
### 10. Meta-Währung und Workshop
|
||||
|
||||
Die zweite Währung fällt aus denselben Kill-Events wie `Coins`, ist aber nicht in sie konvertierbar.
|
||||
Drop-Chance je Normalgegner, garantiert je Boss, Menge wellenabhängig. Gutschrift beim Tod des
|
||||
Gegners, kein Pickup. Der `Workshop` kauft davon permanente Stat-Upgrades mit exponentiell
|
||||
wachsenden Kosten.
|
||||
wachsenden Kosten. Unter den Stats liegt auch `MetaGain` — der Multiplikator auf die gedroppte
|
||||
Meta-Menge, der aus demselben Grund **nicht** im In-Run-Shop steht (Feature 6).
|
||||
|
||||
**Der Workshop verkauft außerdem Card-Slots.** Sie stehen als eigene Zeile neben den Stat-Upgrades,
|
||||
in derselben Währung, mit derselben exponentiellen Kostenform — vier Käufe insgesamt, von Slot 1 auf
|
||||
Slot 5. Der Spieler entscheidet damit selbst zwischen Breite und Stärke; das ist die eine
|
||||
Meta-Entscheidung, die der Slice zu zeigen hat. Ein zusätzliches persistiertes Feld braucht es
|
||||
nicht: `card_slots: u8` aus ADR-0003 §5 ist zugleich Zustand und Kaufstufe.
|
||||
|
||||
**Der erste Slot-Preis ist keine freie Zahl.** #11 bindet Slot 2 an das Abnahmekriterium — er muss
|
||||
innerhalb der ersten paar Runs fallen. Die Kosten für Slot 2 sind damit an den Meta-Ertrag der
|
||||
ersten ‹drei› Runs gebunden, nicht an die Kostenkurve der Stat-Upgrades; erst ab Slot 3 ist der
|
||||
Exponent frei. Beide Werte bleiben ‹Platzhalter› und leben in `Balance`.
|
||||
|
||||
**Akzeptanz**
|
||||
- Eine Ausgabe von `Coins` im Run verringert den Meta-Währungs-Stand nicht, und umgekehrt.
|
||||
@@ -249,6 +329,9 @@ wachsenden Kosten.
|
||||
- Ein Workshop-Kauf erhöht den `flat`- bzw. `mult`-Beitrag des betroffenen Stats sofort und
|
||||
überlebt ein Run-Ende sowie einen Programm-Neustart.
|
||||
- Über die ersten zehn Runs trägt jeder Run mindestens ein Workshop-Level ein (#8, Prüfkriterium 2).
|
||||
- Slot 2 ist im Workshop nach höchstens ‹drei› Runs bezahlbar, ohne dass der Spieler auf
|
||||
Stat-Upgrades verzichtet hat — die Prüfung ist ein gespielter Durchlauf, keine Rechnung.
|
||||
- Ein gekaufter Slot erhöht `card_slots` um genau 1 und überlebt einen Programm-Neustart.
|
||||
|
||||
### 11. Run-Ende und Meta-Übergang
|
||||
|
||||
@@ -270,8 +353,10 @@ ihr, ohne Aufräum-Code.
|
||||
### 12. In-Run-HUD und Pause
|
||||
|
||||
Links das Gameplay-Fenster, rechts ein vertikales Panel über die volle Höhe. Das Panel trägt oben
|
||||
den Namen des aktiven Tabs, darunter ~8 Zeilen im Schema `<Stat Name>` / `<Stat Value>` links und
|
||||
`Buy x1` / `<Cost>` rechts. Unten vier Tabs: **Attack Shop · Defence Shop · Utility Shop ·
|
||||
den Namen des aktiven Tabs, darunter bis zu ~8 Zeilen im Schema `<Stat Name>` / `<Stat Value>` links
|
||||
und `Buy x1` / `<Cost>` rechts. Belegt sind davon 5 (Attack), 4 (Defence) und 4 (Utility) — das
|
||||
Panel füllt seine Zeilen also **nicht** aus, und das ist eine Folge der Stat-Liste, kein
|
||||
Zwischenstand (Feature 6). Unten vier Tabs: **Attack Shop · Defence Shop · Utility Shop ·
|
||||
Ultimates**. Der Ultimates-Tab trägt die Cooldown-Anzeige (#12). Ein Pause-Button friert die
|
||||
**gesamte** Simulation ein und gibt Einsicht in die ausgerüsteten Cards.
|
||||
|
||||
@@ -294,9 +379,14 @@ Der Zustand zwischen zwei Runs. Er trägt Workshop-Käufe, das Card-Loadout, den
|
||||
den Start-Knopf für den nächsten Run. **Sein Aufbau ist offen** (siehe „Offen"); was hier steht, ist
|
||||
seine Funktion, nicht sein Layout.
|
||||
|
||||
Der Slot-Fortschritt ist dabei **kein eigener Bildschirmteil**: Slots werden im Workshop gekauft
|
||||
(Feature 10) und sind dort eine Zeile neben den Stat-Upgrades. Der Meta-Screen zeigt sie im
|
||||
Card-Bereich nur an, er verkauft sie nicht an zweiter Stelle.
|
||||
|
||||
**Akzeptanz**
|
||||
- Ein neuer Run ist nur von hier aus startbar.
|
||||
- Workshop-Käufe, Card-Loadout und Slot-Stand sind von hier aus erreichbar und änderbar.
|
||||
- Der Slot-Kauf ist genau einmal erreichbar, nämlich im Workshop.
|
||||
- Beim Betreten nach einem Run zeigt der Screen, was dieser Run eingebracht hat: erreichte Welle,
|
||||
verdiente Meta-Währung, gedroppte Cards.
|
||||
- Steht `version` nach dem Laden auf `0`, erscheint hier die Meldung aus ADR-0003 §8 — und bis zur
|
||||
@@ -402,7 +492,8 @@ Für keinen dieser Punkte wird hier eine Antwort erfunden.
|
||||
| **`MaxHealth` mitten im Run erhöht** — wächst die aktuelle HP mit, behält sie ihren Anteil, oder bleibt sie unverändert? | Das Health-System, nicht die Pipeline (ADR-0002, „Offene Punkte") | **Vor dem ersten Defence-Shop-Upgrade.** Die ADR-0002-Stat-Tabelle weist `MaxHealth` ausdrücklich `flat` aus In-Run-Upgrades zu — der Fall tritt bei jedem Health-Kauf ein, nicht theoretisch |
|
||||
| **`SlowAura`** — modifiziert Gegner statt den Turm und ist deshalb kein Stat | Fällt mit der Card-Liste; ADR-0002 §9 legt die Form fest (Component am Turm, das das Gegner-Bewegungssystem liest), nicht den Inhalt | Mit der Card-Liste |
|
||||
| **Zusammensetzung der Card-Liste**: Anzahl, Wirkungen, Verteilung auf die drei Seltenheiten, Drop-Wahrscheinlichkeiten je Stufe, Stufenzahl je Card | Ein Card-Inhalts-Ticket, gebunden an #8 (Zahlen) und #11 (Randbedingungen) | Vor Feature 9. **Zwei Randbedingungen sind bereits verbindlich**: Slot 2 muss früh fallen, und es braucht mindestens zwei Epics — sonst ist die Epic-Stufe eine Behauptung statt einer Mechanik |
|
||||
| **Slot-Kurve**: wodurch ein Card-Slot freigeschaltet wird | Niemand — siehe „Lücken", Punkt 2 | offen |
|
||||
| **Slot-Preise**: was ein Card-Slot kostet | Der Entwickler beim Tunen. Die **Mechanik** ist entschieden — Kauf aus der Meta-Währung im Workshop, siehe Feature 10 und „Widersprüche", Punkt 2. Offen ist nur noch der Preis, und der ist für Slot 2 **nicht frei**: er ist an den Meta-Ertrag der ersten ‹drei› Runs gebunden | Zusammen mit den vier freien Zahlen, nach Feature 15 |
|
||||
| **Zellgröße, Separationsradius, Nachbar-Budget ‹k› und Klemmfaktor ‹f›** | Der Entwickler beim Tunen; Form und Revisions-Auslöser stehen in ADR-0004 | Mit Feature 3. Der Beleg ist ein Blick auf den Turmring, keine Zahl |
|
||||
|
||||
---
|
||||
|
||||
@@ -411,6 +502,10 @@ Für keinen dieser Punkte wird hier eine Antwort erfunden.
|
||||
Beim Zusammentragen aller Entscheidungen sind Stellen aufgefallen, an denen zwei Quellen sich
|
||||
widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt geglättet zu werden.
|
||||
|
||||
Aufgelöste Punkte werden **nicht gelöscht**, sondern als *entschieden, siehe X* markiert und
|
||||
behalten ihren Befund. Der Weg zu einer Entscheidung ist so lange wertvoll, wie jemand sie in Frage
|
||||
stellen könnte. Aufgelöst sind bisher die Punkte **2**, **5**, **9** und **14**.
|
||||
|
||||
### Widersprüche
|
||||
|
||||
1. **Card-Drops überqueren die Run-Grenze, aber ADR-0003 kennt sie nicht.** ADR-0003 §6 nennt
|
||||
@@ -423,14 +518,19 @@ widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt
|
||||
zuerst die Ausnahmeliste in ADR-0003 §6 erweitern — nicht stillschweigend ein zweites System
|
||||
schreiben lassen.
|
||||
|
||||
2. **Die Slot-Kurve gehört niemandem, ist aber Abnahmebedingung.** #11 entscheidet „Start bei 1,
|
||||
wächst auf 5, die Slot-Zahl ist selbst Progression" und bindet Slot 2 ausdrücklich ans
|
||||
Abnahmekriterium des Slice. **Wodurch** ein Slot freigeschaltet wird, sagt niemand: nicht #11
|
||||
(schiebt es an #8/#10), nicht #8 (die vier freien Zahlen enthalten keine Slot-Kurve), nicht die
|
||||
Karte (der Fog nennt nur den Meta-Screen-Aufbau). `card_slots: u8` ist in ADR-0003 persistiert,
|
||||
aber es gibt keinen Mechanismus, der ihn erhöht. Das ist keine Zahl, die man beim Tunen findet —
|
||||
es ist eine unentschiedene Mechanik: Kauf aus Meta-Währung? Wellen-Meilenstein? Boss-Zahl? Sie
|
||||
blockiert das Abnahmekriterium und muss vor Feature 9 entschieden werden.
|
||||
2. **Die Slot-Kurve gehört niemandem, ist aber Abnahmebedingung.** — **Entschieden, siehe Feature 10
|
||||
und Feature 9.** *Der Befund bleibt stehen, weil er zeigt, wo die Lücke herkam.* #11 entscheidet
|
||||
„Start bei 1, wächst auf 5, die Slot-Zahl ist selbst Progression" und bindet Slot 2 ausdrücklich
|
||||
ans Abnahmekriterium des Slice. **Wodurch** ein Slot freigeschaltet wird, sagte niemand: nicht
|
||||
#11 (schiebt es an #8/#10), nicht #8 (die vier freien Zahlen enthalten keine Slot-Kurve), nicht
|
||||
die Karte (der Fog nennt nur den Meta-Screen-Aufbau). `card_slots: u8` ist in ADR-0003
|
||||
persistiert, aber es gab keinen Mechanismus, der ihn erhöht.
|
||||
**Auflösung:** Slots werden **aus der Meta-Währung im Workshop gekauft**, neben den
|
||||
Stat-Upgrades, mit derselben exponentiellen Kostenform. Kein zweiter Freischalt-Mechanismus,
|
||||
keine Meilenstein-Schwelle. Der Grund ist nicht Sparsamkeit, sondern dass daraus die
|
||||
Meta-Entscheidung des Slice wird: Breite gegen Stärke aus einem Topf. Die Randbedingung aus #11
|
||||
gilt unverändert weiter und macht den ersten Slot-Preis zu einer gebundenen, nicht zu einer
|
||||
freien Zahl — siehe „Offen". Was diese Auflösung neu aufwirft, steht unten als Punkt 16.
|
||||
|
||||
3. **Die Ticket-Überschrift von #8 verspricht 10–20 Minuten, die Entscheidung liefert 6–9.** #8
|
||||
heißt „Wellen- und Economy-Kurve für einen **10–20-Minuten-Run**", sein erster Kommentar
|
||||
@@ -449,9 +549,10 @@ widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt
|
||||
Event-Cap (Boss). Die Regel bleibt richtig, ihr Anwendungsbereich ist ein Viertel so groß wie
|
||||
beschrieben — wer sie liest, baut sonst eine Klassifizierung für Klassen, die es nicht gibt.
|
||||
|
||||
5. **~24 Shop-Zeilen stehen gegen 12 Stats.** Der HUD-Kommentar in #10 leitet aus 8 Zeilen × 3 Tabs
|
||||
5. **~24 Shop-Zeilen stehen gegen 12 Stats.** — **Entschieden, siehe Feature 6 und den Nachtrag zu
|
||||
ADR-0002 §3.** *Der Befund bleibt stehen.* Der HUD-Kommentar in #10 leitet aus 8 Zeilen × 3 Tabs
|
||||
„etwa 24 In-Run-Upgrades" ab und macht daraus eine Design-Aussage („der Spieler kann in einem Run
|
||||
nicht alles kaufen"). ADR-0002 §3 kennt aber insgesamt **12** Stats, und davon gehören
|
||||
nicht alles kaufen"). ADR-0002 §3 kannte damals aber insgesamt **12** Stats, und davon gehören
|
||||
`UltimateCooldown` und `WaveCooldown` nicht in die drei Shop-Tabs. Die Aufteilung ergibt grob
|
||||
Attack 5 (`Damage`, `AttackInterval`, `Range`, `CritChance`, `CritFactor`), Defence 4
|
||||
(`MaxHealth`, `DefensePercent`, `DefenseFlat`, `HealthRegen`) und **Utility 1** (`CoinGain`). Ein
|
||||
@@ -460,8 +561,18 @@ widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt
|
||||
die keine Stats aus ADR-0002 sind, und dann ist ADR-0002 §3 unvollständig. Beides ist eine
|
||||
Entscheidung, keine Detailfrage.
|
||||
Verschärfend: #3 empfiehlt für Utility ausdrücklich „stark vereinfachen", weil das Utility-System
|
||||
des Originals an Labs und Perks hängt — beides im Nebel. Der Utility-Tab ist damit der schwächste
|
||||
des Originals an Labs und Perks hängt — beides im Nebel. Der Utility-Tab war damit der schwächste
|
||||
Teil der HUD-Struktur.
|
||||
**Auflösung:** Der zweite Ast wird gewählt — ADR-0002 §3 **war** unvollständig und ist um vier
|
||||
Utility-Stats gewachsen (`CoinsPerWave`, `CritCoinGain`, `FreeUpgradeChance`, `MetaGain`; der
|
||||
Nachtrag ist in der ADR als solcher markiert). Utility ist damit das, was #3 im Referenzspiel
|
||||
gefunden hat: ein Ökonomie-Multiplikator, kein Kampf-Stat. Der erste Ast trägt trotzdem mit:
|
||||
Bei 5 + 4 + 4 = 13 belegten von ~24 möglichen Zeilen füllt das Panel seine Zeilen nicht aus, und
|
||||
**die Folgerung „der Spieler kann in einem Run nicht alles kaufen" folgt nicht mehr aus dem
|
||||
Layout.** Sie muss aus der Kostenkurve kommen (#8, Tuning-Zielgröße „Zeit zwischen zwei
|
||||
bezahlbaren Käufen") oder fallen. Punkt 6 unten hatte für dieselbe Kette schon festgehalten, dass
|
||||
von der HUD-Rechnung nur noch die Zahl 24 übrig ist — jetzt ist auch die keine Design-Aussage
|
||||
mehr, sondern eine Layout-Obergrenze.
|
||||
|
||||
6. **Die „12–17 Kaufmomente" sind zweimal überholt, stehen aber noch in der Kette.** Der
|
||||
HUD-Kommentar (13:38) rechnet mit 12–17 Kaufmomenten aus einer 20-Minuten-Session, #8 (13:51)
|
||||
@@ -491,14 +602,20 @@ widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt
|
||||
**eine** Boss-Kill pro Run in der Frühphase der einzige garantierte Drop überhaupt — er trägt
|
||||
Meta-Währung und Card-Chance gleichzeitig.
|
||||
|
||||
9. **Gegner-gegen-Gegner-Kollision ist seit #4 offen und steht auf keiner Liste.** #4 und die
|
||||
Cap-Analyse nennen sie als „offene Architekturfrage": Stapeln zulassen oder Spatial Grid mit
|
||||
weicher Separation. Bei tausenden radial konvergierenden Körpern kommen O(n²) und ein Stau am
|
||||
Turmring zusammen, den keine DPS-Menge auflöst. Sie steht **nicht** im Fog der Karte, in keiner
|
||||
ADR und in keinem der offenen Punkte, die diese Spec zugewiesen bekommen hat. Sie entscheidet
|
||||
aber, ob 10 000 Gegner überhaupt spielbar sind, und sie ist teuer nachzurüsten.
|
||||
*Vorschlag zur Auflösung, nicht Entscheidung:* Stapeln zulassen — bei Programmer-Art in 2D
|
||||
vertretbar, und der Spatial Grid ist der teure Weg, der jederzeit nachrüstbar bleibt.
|
||||
9. **Gegner-gegen-Gegner-Kollision ist seit #4 offen und steht auf keiner Liste.** —
|
||||
**Entschieden, siehe [ADR-0004](adr/0004-spatial-grid-fuer-gegner-nachbarschaft.md).** *Der
|
||||
Befund bleibt stehen.* #4 und die Cap-Analyse nannten sie als „offene Architekturfrage": Stapeln
|
||||
zulassen oder Spatial Grid mit weicher Separation. Bei tausenden radial konvergierenden Körpern
|
||||
kommen O(n²) und ein Stau am Turmring zusammen, den keine DPS-Menge auflöst. Sie stand **nicht**
|
||||
im Fog der Karte, in keiner ADR und in keinem der offenen Punkte, die diese Spec zugewiesen
|
||||
bekommen hat.
|
||||
*Der Vorschlag dieser Spec war „Stapeln zulassen" — er ist verworfen worden.* Nicht wegen der
|
||||
Separation, sondern weil das Grid **drei weitere Konsumenten** hat, die bisher jeder für sich
|
||||
über die Gegnermenge laufen wollten: die Zielauswahl in `tower_fire` (laut #4 der nächste Hotspot
|
||||
nach dem Rendering), der geteilte Reichweiten-Scan aus #12 und die Projektil-Kollision. Genau der
|
||||
Scan, dessen Siebenfach-Ausführung #12 als Bruchstelle benannt hat, wird damit zu einer
|
||||
Grid-Abfrage. Der Rebuild ist gegen die Messungen aus #4 gerechnet, nicht geschätzt: ≤0,10 ms bei
|
||||
`HARD_ENEMY_CAP`, also ≤0,6 % des Frame-Budgets.
|
||||
|
||||
10. **Ziel-Limit für Flächeneffekte und gebatchter Massentod haben keine ADR.** Die Cap-Analyse
|
||||
ordnet beides ausdrücklich „der Architektur" zu, aber ADR-0002 regelt Stats und
|
||||
@@ -523,3 +640,49 @@ widersprechen oder an denen eine Frage niemandem gehört. Sie stehen hier, statt
|
||||
Slice hat nur das In-Run-HUD (entworfen) und den Meta-Screen (offen). Diese Spec hängt die
|
||||
Meldung an den Meta-Screen — womit der offene Meta-Screen-Entwurf eine Anforderung erbt, die
|
||||
aus einer ganz anderen Ecke kommt.
|
||||
|
||||
### Neu aufgefallen beim Einarbeiten der drei Entscheidungen (2026-08-10)
|
||||
|
||||
14. **Die `points`-Stats mit Basis 0 rechnen sich in ADR-0002 auf null.** — **Behoben, siehe
|
||||
ADR-0002 §1.** *Der Befund bleibt stehen, weil er ein ausgelieferter Defekt gewesen wäre, kein
|
||||
Beobachtungsposten.* Die `Direct`-Formel aus ADR-0002 §1 lautete
|
||||
`(base + flat) × (1 + clamp(points)) × mult`. Die Stat-Tabelle in §3 wies `CritChance` und
|
||||
`DefensePercent` aber `base = 0` **und** `points` als einzigen erwarteten Akkumulator zu.
|
||||
Eingesetzt: `(0 + 0) × (1 + 0,30) × 1 = 0`. Crit Chance hätte im Spiel **nie über 0 % steigen
|
||||
können**, egal wie viele Workshop-Level, Cards und In-Run-Upgrades zusammenkommen — und weder
|
||||
Compiler noch ein Formeltest hätten es angezeigt. Es ist exakt dieselbe Falle, die die ADR zwei
|
||||
Absätze weiter unten für `HealthRegen` und `DefenseFlat` benennt und begründet, nur dass sie dort
|
||||
für `mult` gezogen wurde und für `points` nicht. Aufgefallen ist sie beim Einordnen des neuen
|
||||
`FreeUpgradeChance`, der sich korrekt an die Form von `CritChance` gehalten und den Fehler
|
||||
deshalb geerbt hat.
|
||||
**Behebung:** ADR-0002 §1 hat einen dritten Anwendungsmodus **`Fraction`** bekommen —
|
||||
`clamp((base + flat + points) × mult)` — für Stats, die selbst ein Anteil sind. `CritChance`,
|
||||
`DefensePercent` und `FreeUpgradeChance` stehen jetzt dort; an ihren `base`-, „Erwartet"- und
|
||||
`Clamp`-Spalten hat sich nichts geändert. Es ist ein dritter Wert desselben Feldes, kein zweites
|
||||
Bit; drei billigere Wege sind in der ADR geprüft und mit Begründung verworfen. Eine Prüfregel und
|
||||
ein fünfter Revisions-Auslöser verhindern die Wiederkehr, das durchgerechnete Beispiel der ADR
|
||||
trägt den Fall jetzt als Rechnung, und `Interval` ist nicht betroffen.
|
||||
|
||||
15. **Nicht-Konvertierbarkeit ist bisher nur in eine Richtung ausgesprochen.** Issue #1 und #11
|
||||
begründen die zwei Währungen damit, „dass eine In-Run-Ausgabe keinen Meta-Fortschritt kostet" —
|
||||
also `Meta → Coins`. Die Gegenrichtung hat nie jemand benannt: Ein aus `Coins` gekauftes
|
||||
In-Run-Upgrade, das die Meta-Drop-Chance oder die Meta-Menge erhöht, wandelt `Coins` in
|
||||
Meta-Fortschritt und hebelt die Trennung genauso aus, nur unauffälliger. Der Fall wird real,
|
||||
sobald der Utility-Tab Ökonomie-Upgrades trägt (Feature 6) — er ist genau der Tab, in den so ein
|
||||
Upgrade thematisch gehören *würde*. Diese Spec zieht die Konsequenz oben ein (`MetaGain` ist
|
||||
Workshop-only, mit einer Akzeptanzzeile in Feature 6 und einer Zeilen-Anmerkung in ADR-0002 §3),
|
||||
aber die **Regel selbst** steht damit an einer Stat-Tabelle statt in der Entscheidung, aus der
|
||||
sie folgt. Wer die Zwei-Währungs-Entscheidung liest, findet die zweite Richtung dort nicht.
|
||||
|
||||
16. **Slots aus der Meta-Währung erzeugen genau die Konkurrenz, die #11 für Cards ausgeschlossen
|
||||
hat.** #11 verwirft eine gemeinsame Währung für Cards mit dem Argument: „beide Achsen
|
||||
konkurrieren dann linear um denselben Topf, und niemand kauft Cards, bis der Workshop ausgereizt
|
||||
ist — das Original verhindert das ausschließlich über Nicht-Fungibilität, nicht über Preise."
|
||||
Die Slot-Entscheidung (Punkt 2) tut fast das: Sie stellt die Card-Achse — nicht die Karten,
|
||||
aber ihre Breite — in dieselbe Kaufwarteschlange wie die Stat-Upgrades. Zwei Unterschiede halten
|
||||
sie tragfähig: Cards selbst fallen weiterhin gratis, die Achse ist also nie hinter dem Shop
|
||||
verschlossen; und Slot 2 muss laut #11 früh bezahlbar sein, was das Versagensmuster „niemand
|
||||
kauft, bis der Workshop ausgereizt ist" für den einen Kauf ausschließt, der im Abnahmekriterium
|
||||
steht. Für Slot 3 bis 5 gilt dieser Schutz **nicht** — dort ist das Argument aus #11 unverändert
|
||||
gültig, und ob die Slots 3–5 im Slice je gekauft werden, ist eine offene Frage an die
|
||||
Kostenkurve, keine an die Mechanik.
|
||||
|
||||
Reference in New Issue
Block a user