50 KiB
Vertical-Slice-Spec: InfiniTower
- Status: Angenommen
- Datum: 2026-08-10
- Betrifft: Den vollständigen Funktionsumfang des Vertical Slice — was gebaut wird und woran wir erkennen, dass es fertig ist
- Baut auf: ADR-0001 (Balancing-Daten),
ADR-0002 (Stat- und Modifier-Pipeline),
ADR-0003 (Save-Format),
ADR-0004 (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.
Diese Spec sagt, was gebaut wird. Die ADRs sagen, warum es so gebaut wird — ihre Argumente
werden hier nicht wiederholt, sondern verlinkt. Wo eine Zahl noch nicht feststeht, steht sie als
‹Platzhalter›; sie lebt dann in Balance (ADR-0001) und wird durch Spielen gefunden, nicht hier.
Der Loop
Der Spieler startet einen Run. Der Turm steht in der Mitte der Arena und schießt von selbst auf Gegner, die in Wellen radial von außen anlaufen; jeder Kill gibt Coins, und aus Coins kauft der Spieler jederzeit In-Run-Upgrades, die den Turm für diesen Run stärker machen. Die Wellen wachsen schneller als das, was er sich leisten kann — nach sechs bis neun Minuten überrennen sie ihn, der Turm stirbt, und alle In-Run-Upgrades verfallen mit ihm. Was bleibt, ist die Meta-Währung, die die Gegner unterwegs gedroppt haben, und was der Boss auf Welle 10 fallen gelassen hat. Damit kauft er zwischen den Runs permanente Workshop-Upgrades und rüstet gedroppte Cards aus. Der nächste Run beginnt mit einem stärkeren Turm, kommt tiefer, wirft mehr ab — und endet wieder. Das ist das Spiel: sterben ist der Fortschrittsmechanismus, nicht sein Gegenteil.
Zwei Grenzwerte, zwei Begriffe
Die Karte nennt beides „Cap", meint aber zwei verschiedene Dinge. Diese Spec trennt sie, und der Code tut es auch:
| Begriff | Code | Bedeutung |
|---|---|---|
| Harte Obergrenze | HARD_ENEMY_CAP |
10 000 gleichzeitige Gegner. Ein Perf-Grenzwert aus #4, kein Design-Werkzeug. Wird nie überschritten, von nichts. |
| Soll-Population | target_population(wave) |
Die für die aktuelle Welle angestrebte Zahl lebender Gegner. Wächst mit dem Wellenzähler und ist selbst Teil der Schwierigkeitskurve. Bindet ständig — sie ist die Design-Zielgröße. |
Ein Effekt, der „mehr Gegner" verspricht, hebt die Soll-Population an, nie eine Spawn-Zahl (Begründung: Cap-Analyse in Issue #1 — bei bindender Soll-Population wäre ein Spawn-Multiplikator exakt wirkungslos). Die harte Obergrenze bleibt davon unberührt.
Feststehende Zahlen
Alles hier ist entschieden. Alles andere ist ‹Platzhalter› oder steht unter „Offen".
| Größe | Wert | Quelle |
|---|---|---|
| Wellen-Takt | ‹26 s› Spawn-Phase + ‹9 s› Cooldown-Phase = ‹35 s› bei Normalgeschwindigkeit | Primärtext, als Startwert übernommen (#8) |
| Wellen pro Spielzeit | 10 min ≈ 17 Wellen · 20 min ≈ 34 · 30 min ≈ 51 | Folge des Takts (#8) |
| Boss-Welle | jede 10. Welle | Primärtext (#3), übernommen |
| Ziel für Run 1 | Tod zwischen Welle 10 und 15 — genau ein Boss gesehen, kurz danach tot; 6–9 Minuten | #8 |
| Wachstumsform | konstant exponentiell pro Welle, plus ein Multiplikator auf Boss-Wellen | #8 |
| Kosten- vs. HP-Verlauf | Kosten wachsen anfangs langsamer als Gegner-HP, ab ca. zwei Dritteln der Runlänge überholt die HP-Kurve. Entsteht von selbst, wenn der Kosten-Exponent das Einkommenswachstum übersteigt — kein separater Knick | #8 |
| Meta-Ertrag | Drop-basiert: Chance je Normalgegner, garantiert je Boss; gedroppte Menge wellenabhängig | #8 |
| Workshop-Kosten | exponentiell pro Level | #8 |
| Tuning-Zielgröße im Run | Zeit zwischen zwei bezahlbaren Käufen: früh ‹10–20 s›, später seltener | #8 |
| Harte Gegner-Obergrenze | 10 000 gleichzeitig (gemessener Bruch bei ~70 000, ohne Texturen/UI/Audio) | #4, Issue #1 |
| Perf-Budget bei 10 000 | Gameplay-Logik 0,114 ms von 16,67 ms; Rendering 96–98 % | #4 |
| In-Run-Shop-Struktur | vier Tabs: Attack Shop · Defence Shop · Utility Shop · Ultimates | HUD-Mockup, #10 |
| Shop-Kapazität | ~8 Zeilen je Tab ohne Scrollen → Größenordnung ~24 In-Run-Upgrades | HUD-Mockup, #10 |
| Kauf-Modus | Buy x1, Kosten pro Kauf, jederzeit im Run — kein Wellenende, keine Freigabe | Issue #1, #8 |
| Card-Seltenheiten | drei: Common / Rare / Epic | #11 |
| 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 | 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):
- Run 1 endet zwischen Welle 10 und 15.
- Jeder Run trägt mindestens ein Workshop-Level ein.
- Die Run-Tiefe wächst über die ersten zehn Runs monoton, ohne dass ein Run mehr als etwa das Doppelte des vorigen erreicht.
Was im Slice ist
1. Arena, Turm und Kamera
2D, bevy_sprite, orthographische Kamera. Ein Tower fest in der Mitte, Programmer-Art. Kein
Scrollen, kein Zoom, keine Turm-Platzierung.
Akzeptanz
- Nach Programmstart und Run-Start ist der Turm sichtbar in der Bildmitte des Gameplay-Fensters, und die gesamte Spawn-Peripherie liegt innerhalb des sichtbaren Bereichs.
- Die Turm-Entity wird beim Run-Start gespawnt und beim Run-Ende despawnt (ADR-0002 §6); zwischen
zwei Runs existiert keine Entity mit
EffectiveStats.
2. Wellen-Takt
Eine Wave besteht aus zwei separat getakteten Phasen. Die nächste Welle beginnt, wenn beide
Timer abgelaufen sind — nicht wenn alle Gegner tot sind. Eine einzige endlose Kurve, keine Tiers.
Akzeptanz
- Während der Spawn-Phase erscheinen Gegner; nach ‹26 s› hören Spawns auf, während bereits vorhandene Gegner weiter laufen und angreifen; nach weiteren ‹9 s› beginnt Welle N+1.
- Wird Welle N+1 gestartet, während noch Gegner aus Welle N leben, laufen diese unverändert weiter und werden nicht entfernt.
- Der aktuelle Wellenzähler ist im HUD ablesbar und stimmt mit dem Telemetrie-Log überein.
- Auf jeder Welle mit
wave % 10 == 0spawnt genau ein Boss.
3. Gegner und Population
Drei bis vier Normal-Archetypen plus ein Boss (#3): ein Tempo/HP-Tradeoff-Paar, ein Fernkämpfer und eine Sondermechanik, die Ziel-Priorisierung erzwingt (Splitter oder Schutz-Aura). Der Boss ist ein einzelner schwerer, langsamer Meilenstein-Gegner. Keine Elite-Klasse, keine Fleet-Klasse, keine Immunitätsmatrix.
Der Spawner ist cap-getrieben, nicht plan-getrieben: er füllt bis zur target_population(wave)
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. 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. - Die Zahl lebender Gegner überschreitet nie
HARD_ENEMY_CAP— auch nicht bei einem 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
SpatialGridkostet bei 10 000 Gegnern nicht mehr alsmove_enemiesim 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
Der Turm schießt selbstständig auf Gegner in Reichweite. Genau ein System ermittelt pro Frame
den Reichweiten-Zustand; tower_fire und alle Auslöse-Bedingungen (Feature 7) lesen dessen
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.AttackIntervalSekunden. - Ohne Gegner in Reichweite feuert er nicht.
- Es existiert genau ein System, das die Gegnermenge in Turm-Reichweite bestimmt, und es fragt das
SpatialGrid; eingrepnach einem zweiten Reichweiten-Scan über die Gegner-Query findet keinen. - Außer
rebuild_spatial_griditeriert kein System die Gegner-Query, um Nachbarn zu finden — weder die Separation, nochtower_fire, noch das Auslöse-System, noch die Projektil-Kollision (ADR-0004 §6).
5. Stat- und Modifier-Pipeline
Vollständig nach ADR-0002: drei Akkumulatoren (flat,
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. Das schließt den Crit-Chance-Fall ein: Drei Quellen mit zusammen 37 pp ergeben 37 %, nicht 0.
- Kein Stat im Modus
Directhatbase = 0undpointsals 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,EquippedCardsoderRunUpgradesläuft die Neuberechnung genau einmal; ohne Änderung läuft sie nicht (nachweisbar über einen Zähler im Debug-Panel). sync_tower_abilitiesist der einzige Schreiber von Fähigkeits-Components; seindebug_assertam Ende des Abgleichs ist vorhanden und greift im Debug-Build.- Jeder Modifikator, der in den Slice aufgenommen wird, hat die Sichtbarkeitsanforderung aus ADR-0002 §11 vor dem Merge durchlaufen — inklusive Punkt 3 (beobachtbare Folge in der Run-Telemetrie).
6. Coins und In-Run-Upgrades
Coins fallen bei jedem Kill an und werden beim Tod gutgeschrieben — kein einsammelbares Objekt,
keine Entity (Cap-Analyse, Issue #1: bei tausenden Kills pro Welle wäre das ein Entity-Sturm). Damit
kauft der Spieler In-Run-Upgrades in drei Tabs (Attack / Defence / Utility), jederzeit, einzeln
(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.
- Ein Klick auf „Buy x1" zieht genau die angezeigten Kosten ab, erhöht das Upgrade um eine Stufe,
und der betroffene Wert in
EffectiveStatsändert sich im selben Frame ablesbar. - Ist der Coin-Stand kleiner als die Kosten, ist die Zeile nicht klickbar und als solche erkennbar.
- Nach einem Run-Ende und Run-Start stehen alle In-Run-Upgrades wieder auf Stufe 0, ohne dass irgendein System sie zurücksetzt.
- 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
Coinsin Meta-Fortschritt. - Jede der vier Utility-Zeilen hat die Sichtbarkeitsanforderung aus ADR-0002 §11 durchlaufen; für
CritCoinGainliegt die dort zu nennende Fortschritts-Stelle hinter dem ersten Crit-Kauf.
7. Auslöse-System für Fähigkeiten
Ein System wertet die Auslöse-Bedingungen aller aktiven Fähigkeiten aus — der Ultimate und jeder
Fähigkeits-Card. Eine Bedingung ist Cooldown UND ein Weltzustand (z. B. „‹N› Gegner in
Reichweite"), je Fähigkeit fest verdrahtet und nicht vom Spieler einstellbar. Die Werte kommen wie
alle Zahlen aus Balance. Feuern mehrere im selben Frame, feuern alle — keine Sperre, keine
Priorität.
Akzeptanz
- Eine Fähigkeit feuert erst, wenn beide Teile der Bedingung erfüllt sind; ein abgelaufener Cooldown allein löst nachweislich nicht aus (prüfbar, indem man die Arena leerräumt und wartet).
- Sind zwei Fähigkeiten im selben Frame auslösebereit, feuern beide im selben Frame.
- Die Bedingungswerte stehen in
Balanceund 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 — weder
über die Gegner-Query noch als eigene Abfrage am
SpatialGrid(ADR-0004 §6).
8. Ultimate: Death Wave
Ein radialer Sweep von der Turmmitte nach außen, automatisch ausgelöst über Feature 7. Kein Zielsystem, kein Knopf, kein Eingabepfad. Die Systemanforderung, die sie aufdeckt, ist der gebatchte Massentod: ein Sweep kann in einem Tick tausende Gegner treffen.
Akzeptanz
- Bei erfüllter Bedingung startet der Sweep ohne Eingabe; ein sichtbarer Ring wandert von der Turmmitte nach außen und trifft Gegner in der Reihenfolge ihres Abstands.
- Ein Sweep, der ‹5 000› Gegner gleichzeitig tötet, erzeugt keinen Frame über 16,67 ms — der Massentod wird gebatcht, nicht als tausende Einzelereignisse abgearbeitet.
- Der verbleibende Cooldown ist im Ultimates-Tab ablesbar.
- Flächenwirkung ist über ein Ziel-Limit pro Auslösung gedeckelt, nicht über einen schrumpfenden Radius (Cap-Analyse, Issue #1).
9. Cards, Slots und Loadout
Cards fallen als Drop aus Fortschritt: Boss-Kill oder neuer Wellen-Rekord. Sie sind nicht
kaufbar und haben keine eigene Währung. Eine Card ist entweder ein Stat-Modifikator oder eine
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).
Akzeptanz
- Nach einem Boss-Kill oder einem neuen Wellen-Rekord ist die Card-Ausbeute des Runs auf dem Meta-Screen sichtbar, spätestens beim ersten Betreten nach dem Run-Ende.
- Der Spieler kann vor dem Run so viele Cards ausrüsten, wie er Slots hat, und keine mehr.
- Eine ausgerüstete Fähigkeits-Card erzeugt beim Run-Start genau eine Fähigkeits-Component am Turm; eine abgelegte erzeugt keine.
- Während eines Runs ändert sich
EquippedCardsnicht — kein Pfad in der UI erlaubt es. - Der Card-Pool enthält mindestens zwei Epics, und Slot 2 ist innerhalb der ersten ‹drei› Runs bezahlbar (#11; beide Bedingungen sind an das Abnahmekriterium des Slice gebunden).
- Es gibt genau einen Pfad, der
card_slotserhö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. 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
Coinsim Run verringert den Meta-Währungs-Stand nicht, und umgekehrt. - Ein Boss-Kill schreibt garantiert Meta-Währung gut; die gutgeschriebene Menge auf Welle 20 ist höher als auf Welle 10.
- 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_slotsum genau 1 und überlebt einen Programm-Neustart.
11. Run-Ende und Meta-Übergang
Fällt die Turm-HP auf 0, endet der Run. Genau ein System überführt am Run-Ende die aus dem Run
abgeleiteten Meta-Werte (highest_wave, verdiente Meta-Währung, Card-Ausbeute) in die persistierten
Resources (ADR-0003 §6). Danach wird die Turm-Entity despawnt; alles Run-gebundene verschwindet mit
ihr, ohne Aufräum-Code.
Akzeptanz
- Bei HP ≤ 0 endet der Run innerhalb eines Frames; danach existiert keine Entity mit
EffectiveStats,RunUpgradesoder einer Fähigkeits-Component mehr. highest_wavewächst nur, wenn die erreichte Welle den bisherigen Stand übersteigt, und wird genau einmal pro Run geschrieben.- Kein anderes System als dieses eine schreibt aus Run-Zustand in eine persistierte
Resource(prüfbar über die Schreibstellen derSettingsGroup-Resources). - Der Spieler landet nach dem Run-Ende auf dem Meta-Screen, ohne Zwischenschritt und ohne dass ein weiterer Run automatisch startet.
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 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.
Das Mockup (docs/design/hud-in-run.png) legt Panel und Tabs fest, zeigt aber weder Turm-HP,
Wellenzähler, Währungsstände noch den Pause-Button. Diese vier gehören ins Gameplay-Fenster oder
dessen Rand; ihre Platzierung ist frei, ihre Existenz nicht.
Akzeptanz
- Die vier Tabs sind vorhanden und schaltbar; ein Tab-Wechsel hält die Simulation nicht an.
- Turm-HP, aktuelle Welle,
Coins-Stand und Meta-Währungs-Stand sind während des Runs jederzeit ohne Tab-Wechsel ablesbar. - Der Pause-Button friert Gegnerbewegung, Turmfeuer, Wellen-Timer und Fähigkeits-Cooldowns gleichzeitig ein; nach dem Fortsetzen laufen alle vier von genau ihrem Stand weiter.
- Im Pause-Zustand sind die ausgerüsteten Cards einsehbar und nicht wechselbar.
- Es gibt keine „Gespeichert"-Bestätigung — das Programm kann sie nicht belegen (ADR-0003 §8).
13. Meta-Screen zwischen den Runs
Der Zustand zwischen zwei Runs. Er trägt Workshop-Käufe, das Card-Loadout, den Slot-Fortschritt und 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
versionnach dem Laden auf0, erscheint hier die Meldung aus ADR-0003 §8 — und bis zur ersten bewussten Aktion des Spielers wird nicht geschrieben.
14. Save/Load
Vollständig nach ADR-0003: progress.toml über
bevy_settings, version als Sentinel, Feldnamen als Vertrag, namensbasierte Ablage. Persistiert
werden nur Quellen, nie berechnete Werte (ADR-0002 §5). Kein laufender Run, kein Balance, kein
Zeitstempel.
Akzeptanz
- Nach einem Programmneustart stehen Workshop-Level, Card-Bestand, Loadout, Slot-Zahl,
Meta-Währungsstand und
highest_waveunverändert da. - Ein von Hand beschädigtes
progress.tomlführt zur Meldung aus ADR-0003 §8 und nicht zu einem Schreibvorgang, bevor der Spieler etwas tut. Die beschädigte Datei liegt danach unverändert da. - Ein
progress.tomlmitversiongrößer alsCURRENTsperrt alle Schreibvorgänge für die Sitzung und lässt die Datei unangetastet. - Ein Umbenennen eines Feldes lässt den restlichen Spielstand intakt und setzt genau einen Wert auf
Default. - Die Datei ist in einem Texteditor lesbar und von Hand editierbar — Schummeln ist ausdrücklich akzeptiert, nicht übersehen.
15. Debug-Panel und Run-Telemetrie
Kein Nice-to-have. ADR-0001 und #8 benennen dieses Werkzeug als den eigentlichen Hebel, um die
vier freien Zahlen überhaupt finden zu können: ohne Sprung-zu-Welle kostet jeder Datenpunkt einen
Run von Welle 1 an, bei ‹35 s› pro Welle also Minuten. Das Panel mutiert Balance im laufenden
Prozess und nutzt dieselbe Naht wie der spätere Asset-Ladepfad (ADR-0001 §3).
Umfang: Sprung zu einer beliebigen Welle · Live-Mutation der Balance-Werte · Anzeige von
EffectiveStats samt der ungeclampten Summen (ADR-0002 §2) · Herkunfts-Aufschlüsselung pro Stat
(ADR-0002 §6) · Run-Telemetrie: Zeit bis Tod, erreichte Welle, Coins pro Minute, Kills pro Welle,
DPS-Verlauf, Zeit zwischen zwei bezahlbaren Käufen.
Akzeptanz
- Ein Sprung zu Welle N versetzt den laufenden Run in Welle N mit der für N vorgesehenen Soll-Population und Gegner-Skalierung, ohne Programmneustart, in unter ‹2 s›.
- Eine Änderung an einem
Balance-Wert im Panel wirkt ohne Neustart auf die nächste Neuberechnung vonEffectiveStats. - Am Run-Ende liegt ein Telemetrie-Datensatz vor, der alle oben genannten Größen enthält und sich maschinenlesbar exportieren lässt.
- Ein Run, in dem das Debug-Panel benutzt wurde, schreibt nichts in
progress.toml. Wederhighest_wavenoch Meta-Währung noch Card-Drops. Ein Sprung zu Welle 500 darf keinen Wellen-Rekord und keinen Card-Drop erzeugen. - Das Panel ist im Release-Build nicht erreichbar, ohne dass ein Schalter dafür umgelegt wird.
Was ausdrücklich nicht drin ist
| Nicht im Slice | Warum |
|---|---|
| Pfadfindung, Turm-Platzierung, Maze-Building | die Arena ist radial und hat genau einen Turm — es gibt nichts zu platzieren und keinen Pfad zu finden. |
| Tiers | wir haben uns bewusst für eine endlose Kurve entschieden; Tier-Resets sind das Langzeit-Muster des Originals, nicht unser Slice-Problem. |
| Labs, Modules, Perks | dritte, vierte und fünfte Meta-Achse neben Workshop und Cards — der Slice soll zeigen, dass eine Progressionsschleife trägt, nicht dass fünf sich addieren. |
| Offline-Progress | braucht einen Zeitstempel im Save, und ein Feld ohne Leser ist genau der Fehler, den ADR-0002 §5 verbietet. |
| Elite- und Fleet-Klasse | ihre Mechanik im Original ist eine Anti-Cheese-Antwort auf ein Fähigkeiten-Arsenal, das wir gar nicht haben (#3). |
| Immunitätsmatrix | dieselbe Begründung — sie schützt vor Fähigkeiten, die der Slice nicht kennt. |
| Wall als zweiter HP-Pool | ein zweiter HP-Pool verdoppelt die Schadenslogik, ohne eine neue Frage zu beantworten (#3). |
| Coin- und Card-Pickups als Entities | bei tausenden Kills pro Welle ist ein einsammelbares Objekt pro Drop ein Entity-Sturm (Cap-Analyse #1). |
| Coin Decay, Heat-up, Enemy-Mass-Wachstum | Coin Decay und Mass sind dichte-neutral, aber ohne Nutzen im Slice; Heat-up ist bei 13-facher Angreiferzahl schlicht nicht übertragbar und müsste neu erfunden statt übernommen werden (Cap-Analyse #1). |
| Gacha-Kopien, Card-Mastery, Pity-System | das Original kauft Cards mit einer Währung, die es bei uns nicht gibt (Ads, IAP) — Drop-Verteilung ersetzt beides ersatzlos (#11). |
| Manuelle Ultimate-Auslösung | ein Knopf wäre der einzige Moment aktiver Kontrolle im ganzen Spiel und würde das Kern-Gefühl „Idle" brechen statt bestätigen (#9). |
| Einstellbare Auslöse-Bedingungen | die Bedingungen liegen bereits als Daten in Balance; sie einstellbar zu machen ist reine UI-Arbeit und kauft im Slice nichts (#12). |
| Buy x10 / Buy Max | das HUD-Schema lässt Platz dafür, ohne das Layout zu ändern — der Slice braucht es nicht (#10). |
| Spielgeschwindigkeits-Multiplikator | nicht entschieden und nicht im HUD; das Debug-Panel deckt den Zeitraffer-Bedarf beim Tunen ab (siehe „Lücken"). |
| Bots, Wave Skip, Recovery Packages | Systeme, die eine bereits laufende Schleife garnieren — der Slice muss erst zeigen, dass die Schleife läuft. |
| Guilds, Tournaments, Cloud-Saves, Accounts, IAP, Leaderboards | alles Server-seitige ist out of scope; ein Vergleichswert, der das Gerät verlässt, würde außerdem ADR-0003 §1 (Klartext-Save) neu aufmachen. |
| Mobile- und Web-Port | bevy_settings persistiert auf Android und iOS nichts und meldet es nur als warn! — der Port braucht eigene Arbeit (ADR-0003, Revisions-Auslöser 2). |
| Art-Direction, Audio | Programmer-Art ist eine Entscheidung, kein Zwischenstand; ein Art-Strang beantwortet keine der offenen Fragen. |
| Hot-Reload für Balancing-Daten | der Edit-to-see-Loop kostet gemessene ~11 s, und der teure Teil eines Tuning-Zyklus ist das Spielen (ADR-0001). |
| „Gespeichert"-Bestätigung | das Programm kann sie nicht belegen — es gibt in Bevy 0.19 keinen Rückkanal (ADR-0003 §8). |
Abnahmekriterium für den Slice
Genau eines, überprüfbar, ohne Debug-Panel:
In einer ununterbrochenen Sitzung von höchstens 60 Minuten auf einem frisch angelegten Spielstand spielt ein Spieler Runs, bis er einen zweiten Card-Slot besitzt und zwischen mindestens zwei Cards wählen kann, startet danach einen weiteren Run und erreicht darin eine höhere Welle als in Run 1; nach einem Neustart des Programms steht derselbe Meta-Stand wieder da.
Warum genau dieses: Es prüft alle vier Takte des Loops in einer Beobachtung — Run starten, sterben, aufwerten, stärker starten — und bindet zusätzlich die Randbedingung aus #11 ein, dass der Slice das Card-System nicht nur enthalten, sondern zeigen muss. Ein Slice, in dem Slot 2 ein Fernziel bleibt, hat Cards gebaut und nie vorgeführt. Der Neustart am Ende prüft Feature 14 dort, wo es zählt.
Offen — bewusst nicht entschieden
Für keinen dieser Punkte wird hier eine Antwort erfunden.
| Punkt | Wer entscheidet | Wann |
|---|---|---|
| Die vier freien Zahlen: Wachstumsfaktor pro Welle, Boss-Multiplikator, Drop-Chance mal Wellenwert, Kosten-Exponent des Workshops | Der Entwickler beim Tunen. Form und Prüfkriterien stehen in #8, die Werte findet nur Spielen | Nach Feature 15 (Debug-Panel), vor dem Abnahmekriterium |
| Name der Meta-Währung | CONTEXT.md — der Glossar-Eintrag ist der Vertrag, der Save-Feldname folgt ihm |
Bevor der erste Workshop-Preis geschrieben wird. Coins ist an die In-Run-Währung vergeben; ADR-0003 lässt das Feld unbenannt, weil ein vorläufiger Name nach der Migrationsregel (§4) teuer zu korrigieren wäre |
| Aufbau des Meta-Screens (Workshop, Cards, Slot-Fortschritt) | Ein eigenes Design-Ticket, analog zum HUD-Mockup | Vor Feature 13. Nur das In-Run-HUD ist entworfen |
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-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 |
Widersprüche und Lücken
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
-
Card-Drops überqueren die Run-Grenze, aber ADR-0003 kennt sie nicht. ADR-0003 §6 nennt ausdrücklich genau eine Ausnahme von der Regel „während eines Runs ändert sich keine persistierte Quelle":
highest_waveund die verdiente Meta-Währung, überführt genau einmal am Run-Ende.card_levelssteht nicht in dieser Ausnahme — obwohl #11 (entschieden 12:48, also vor ADR-0003 um 13:46) Cards aus Boss-Kills und neuen Wellen-Rekorden droppen lässt, beides Ereignisse im Run. Die Spec löst das oben nach ADR-0003 auf: Card-Drops werden im Run gepuffert und zusammen mit den übrigen Meta-Werten am Run-Ende überführt. Wer das anders bauen will, muss zuerst die Ausnahmeliste in ADR-0003 §6 erweitern — nicht stillschweigend ein zweites System schreiben lassen. -
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: u8ist 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. -
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 verlangt Tod „um Welle 20–40", und die Entscheidung im zweiten Kommentar setzt Run 1 auf Welle 10–15 = 6–9 Minuten. Die Karte hat die letzte Fassung übernommen, die frühere steht unwidersprochen daneben. Wahrscheinlich gemeint: 10–20 Minuten gilt für den eingespielten Run nach einigen Workshop-Leveln, 6–9 Minuten für Run 1. Das steht so aber nirgends, und die Kurve wird gegen die Zahl getunt, die man liest. Diese Spec folgt der Entscheidung (Welle 10–15) und hält fest, dass für Run n keine Ziel-Runlänge existiert.
-
Die Cap-Analyse balanciert Sub-Caps für Gegnerklassen, die #3 abgeschafft hat. Der #1-Kommentar teilt die Sub-Caps sorgfältig in Modifikator-Caps (Protector 8, Elite pro Typ 8) und Event-Caps (Boss 10, Elite gesamt 20). #3 wirft Elite und Fleet aber komplett aus dem Slice. Damit ist die Hälfte der Analyse gegenstandslos: übrig bleiben genau ein mitskalierendes Modifikator-Cap (die eine Sondermechanik-Einheit, Protector-artig) und ein absolutes 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.
-
~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 kannte damals aber insgesamt 12 Stats, und davon gehören
UltimateCooldownundWaveCooldownnicht 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 Utility-Tab mit einer Zeile ist kein Tab. Entweder das Panel füllt nur die Hälfte der Zeilen — dann trägt die Folgerung „kann nicht alles kaufen" nicht mehr —, oder es braucht In-Run-Upgrades, 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 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. -
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) verwirft die Rechnung ausdrücklich („die trägt nicht mehr", weil jederzeit gekauft wird) und verkürzt Run 1 auf 10–15 Wellen. Was aus dem HUD-Kommentar überlebt, ist allein die Zahl 24 — sie kommt aus dem Layout, nicht aus der Session-Rechnung. Die Tuning-Zielgröße ist die Zeit zwischen zwei bezahlbaren Käufen (‹10–20 s› früh), nicht eine Kaufzahl pro Run.
Lücken, die niemandem gehören
-
Das Debug-Panel kann den echten Spielstand zerstören, und niemand hat es benannt. Feature 15 springt zu Welle N. Feature 11 schreibt am Run-Ende
highest_waveund die Meta-Währung in die persistierte Resource, und #11 macht „neuer Wellen-Rekord" zu einer Card-Drop-Quelle. Ein Sprung zu Welle 500 beendet einen Run also mithighest_wave = 500, einem gewaltigen Card-Drop und einem Meta-Währungsstand, der den ganzen Slice trivialisiert. Weder ADR-0001 noch #8 noch ADR-0003 erwähnen das. Diese Spec zieht die Konsequenz oben als Akzeptanzkriterium ein: ein Run mit benutztem Debug-Panel schreibt nichts. Wer das Panel baut, muss die Schreibsperre zuerst bauen. -
Die Card-Nachschubquelle „neuer Wellen-Rekord" versiegt eingebaut. Beide Card-Quellen hängen an Fortschritt: Boss-Kill und neuer Wellen-Rekord. Solange die Run-Tiefe monoton wächst (#8, Prüfkriterium 3, gilt für die ersten zehn Runs), fließt Nachschub. Danach ist unbestimmt, was passiert — ein Spieler, der zehn Runs lang auf derselben Welle hängen bleibt, bekommt keine neue Card mehr und hat gleichzeitig keinen anderen Hebel, tiefer zu kommen als den Workshop. Ob das ein Feature ist (Cards folgen dem Fortschritt) oder eine Sackgasse (Fortschritt braucht Cards), hat niemand entschieden. Bei einem Run 1, der auf Welle 10–15 endet, ist außerdem der eine Boss-Kill pro Run in der Frühphase der einzige garantierte Drop überhaupt — er trägt Meta-Währung und Card-Chance gleichzeitig.
-
Gegner-gegen-Gegner-Kollision ist seit #4 offen und steht auf keiner Liste. — Entschieden, siehe ADR-0004. 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 beiHARD_ENEMY_CAP, also ≤0,6 % des Frame-Budgets. -
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 Fähigkeits-Components, nicht Massenwirkung. Death Wave (#9) trifft beide Punkte sofort. Diese Spec hat sie deshalb als Akzeptanzkriterien in Feature 8 aufgenommen — das ersetzt keine ADR, macht sie aber wenigstens prüfbar.
-
Ein Spielgeschwindigkeits-Multiplikator ist weder entschieden noch verworfen. Die Cap-Analyse wirft ihn auf („ein Idle-Spiel mit 35-Sekunden-Wellen will fast sicher einen") und entschärft ihn nur perf-seitig; das Referenzspiel hat ihn; das HUD-Mockup zeigt ihn nicht. Diese Spec listet ihn oben unter „nicht drin", weil das Debug-Panel den Zeitraffer-Bedarf beim Tunen abdeckt — aber das ist eine Entscheidung, die hier zum ersten Mal getroffen wird und jederzeit umkehrbar ist.
-
WaveCooldownhat einen Cap, aber im Slice keine Quelle. ADR-0002 §3 führt den Stat samtcaps.wave_cooldown_reduction; im Original liefert ihn die Epic-Card „Wave Accelerator". Enthält die noch offene Card-Liste keine entsprechende Card, sind Stat und Cap toter Code. Kein Fehler, aber ein Punkt, der bei der Card-Liste mitentschieden werden sollte. -
Die Fehlermeldung aus ADR-0003 hat keinen Ort. ADR-0003 §3 und §8 verlangen bei
version == 0und beiversion > CURRENTeine Meldung an den Spieler, bevor irgendetwas geschrieben wird. Der 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)
-
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. DieDirect-Formel aus ADR-0002 §1 lautete(base + flat) × (1 + clamp(points)) × mult. Die Stat-Tabelle in §3 wiesCritChanceundDefensePercentaberbase = 0undpointsals 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ürHealthRegenundDefenseFlatbenennt und begründet, nur dass sie dort fürmultgezogen wurde und fürpointsnicht. Aufgefallen ist sie beim Einordnen des neuenFreeUpgradeChance, der sich korrekt an die Form vonCritChancegehalten und den Fehler deshalb geerbt hat. Behebung: ADR-0002 §1 hat einen dritten AnwendungsmodusFractionbekommen —clamp((base + flat + points) × mult)— für Stats, die selbst ein Anteil sind.CritChance,DefensePercentundFreeUpgradeChancestehen jetzt dort; an ihrenbase-, „Erwartet"- undClamp-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, undIntervalist nicht betroffen. -
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 ausCoinsgekauftes In-Run-Upgrade, das die Meta-Drop-Chance oder die Meta-Menge erhöht, wandeltCoinsin 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 (MetaGainist 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. -
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.