Vertical-Slice-Spec schreiben #10

Closed
opened 2026-08-10 07:58:36 +00:00 by RDietermann · 2 comments
Owner

Part of #1
Blocked by: #6, #7, #8, #12

Das Ziel der Reise. Alles davor läuft hier zusammen.

Inhalt

  • Der Loop in einem Absatz: Run starten, sterben, aufwerten, stärker starten.
  • Was im Slice ist, Feature für Feature, mit Akzeptanzkriterien je Feature.
  • Was ausdrücklich nicht drin ist, mit Begründung.
  • Die Zahlen aus dem Grilling: Wellenkurve, Upgrade-Kosten, Meta-Ertrag.
  • Verweise auf die ADRs statt Wiederholung ihrer Argumente.
  • Ein Abnahmekriterium für den Slice als Ganzes: woran erkennen wir, dass er fertig ist?

Fertig, wenn ein Kontext, der nur diese Spec und die ADRs liest, mit dem Bauen anfangen kann.

Part of #1 Blocked by: #6, #7, #8, #12 Das Ziel der Reise. Alles davor läuft hier zusammen. **Inhalt** - Der Loop in einem Absatz: Run starten, sterben, aufwerten, stärker starten. - Was im Slice ist, Feature für Feature, mit Akzeptanzkriterien je Feature. - Was ausdrücklich nicht drin ist, mit Begründung. - Die Zahlen aus dem Grilling: Wellenkurve, Upgrade-Kosten, Meta-Ertrag. - Verweise auf die ADRs statt Wiederholung ihrer Argumente. - Ein Abnahmekriterium für den Slice als Ganzes: woran erkennen wir, dass er fertig ist? **Fertig, wenn** ein Kontext, der nur diese Spec und die ADRs liest, mit dem Bauen anfangen kann.
RDietermann added the wayfinder:task label 2026-08-10 07:58:36 +00:00
Author
Owner

In-Run-HUD: Layout steht

Mockup liegt im Repo unter docs/design/hud-in-run.png.

Aufbau: links das Gameplay-Fenster mit der Arena, rechts ein vertikales Panel über die volle Höhe. Das Panel trägt oben den Namen des aktiven Tabs, darunter etwa acht Zeilen im Schema <Stat Name> / <Stat Value> links und Buy x1 / <Cost> rechts. Ganz unten vier Tabs:

Attack Shop · Defence Shop · Utility Shop · Ultimates

Was das festlegt

  • Die drei Stat-Kategorien der Kalibrierung sind die In-Run-Shop-Struktur. Attack, Defence und Utility — dieselbe Gliederung wie im Referenzspiel, aber hier für die In-Run-Upgrades, nicht für den Workshop.
  • Ultimates bekommen einen gleichrangigen vierten Tab, keinen Sonderplatz. Dort liegt auch die Cooldown-Anzeige aus #12.
  • Kauf ist einzeln (Buy x1) und zeigt Kosten pro Kauf. Das Schema lässt Platz für Buy x10 oder Buy Max später, ohne das Layout zu ändern — im Slice nicht nötig.
  • Workshop und Cards sind nicht in diesem HUD. Sie sind Meta-Progression zwischen Runs und leben auf einem eigenen Screen. Dessen Aufbau ist offen.

Zwei Konsequenzen, die woanders wirken

Für #4 / das Perf-Budget, in die günstige Richtung: Der Perf-Spike hat mit einem 1920×1080-Fenster gemessen, in dem die Arena vollständig sichtbar war und nichts frustum-gecullt wurde. Im echten HUD belegt das Gameplay-Fenster nur etwa zwei Drittel der Breite. Weniger Pixel pro Sprite heißt weniger Fill-Rate, und Rendering war mit 96–98 % der dominierende Posten. Die gemessene Obergrenze ist damit eher konservativ als knapp. Das ersetzt keine neue Messung, aber es entlastet die Zahl.

Für #8 / die Economy-Kurve: Acht sichtbare Zeilen mal drei Shop-Tabs ergeben eine Größenordnung von etwa 24 In-Run-Upgrades, wenn nicht gescrollt wird. Das ist eine Design-Zahl, keine Messung — aber sie grenzt ein, wie fein die Kostenstaffelung sein muss und wie viele Kaufmomente pro Run überhaupt sinnvoll sind. Zur Erinnerung aus #3: eine 20-Minuten-Session hat ~34 Wellen, bei einer Kaufentscheidung alle zwei bis drei Wellen also 12–17 Kaufmomente. Bei 24 verfügbaren Upgrades heißt das: der Spieler kann in einem Run nicht alles kaufen — das ist eine Entscheidung, kein Zufall, und sie macht die Kaufreihenfolge zum eigentlichen In-Run-Spiel.

Offen

Der Aufbau des Meta-Screens (Workshop, Cards, Slot-Fortschritt), was beim Tod passiert, und ob der HUD-Tab-Zustand über Runs hinweg erhalten bleibt.

## In-Run-HUD: Layout steht Mockup liegt im Repo unter `docs/design/hud-in-run.png`. **Aufbau**: links das Gameplay-Fenster mit der Arena, rechts ein vertikales Panel über die volle Höhe. Das Panel trägt oben den Namen des aktiven Tabs, darunter etwa acht Zeilen im Schema `<Stat Name>` / `<Stat Value>` links und `Buy x1` / `<Cost>` rechts. Ganz unten vier Tabs: **Attack Shop · Defence Shop · Utility Shop · Ultimates** ## Was das festlegt - **Die drei Stat-Kategorien der Kalibrierung sind die In-Run-Shop-Struktur.** Attack, Defence und Utility — dieselbe Gliederung wie im Referenzspiel, aber hier für die *In-Run*-Upgrades, nicht für den Workshop. - **Ultimates bekommen einen gleichrangigen vierten Tab**, keinen Sonderplatz. Dort liegt auch die Cooldown-Anzeige aus #12. - **Kauf ist einzeln** (`Buy x1`) und zeigt Kosten pro Kauf. Das Schema lässt Platz für `Buy x10` oder `Buy Max` später, ohne das Layout zu ändern — im Slice nicht nötig. - **Workshop und Cards sind nicht in diesem HUD.** Sie sind Meta-Progression zwischen Runs und leben auf einem eigenen Screen. Dessen Aufbau ist offen. ## Zwei Konsequenzen, die woanders wirken **Für #4 / das Perf-Budget, in die günstige Richtung**: Der Perf-Spike hat mit einem 1920×1080-Fenster gemessen, in dem die Arena vollständig sichtbar war und nichts frustum-gecullt wurde. Im echten HUD belegt das Gameplay-Fenster nur etwa zwei Drittel der Breite. Weniger Pixel pro Sprite heißt weniger Fill-Rate, und Rendering war mit 96–98 % der dominierende Posten. Die gemessene Obergrenze ist damit eher konservativ als knapp. Das ersetzt keine neue Messung, aber es entlastet die Zahl. **Für #8 / die Economy-Kurve**: Acht sichtbare Zeilen mal drei Shop-Tabs ergeben eine Größenordnung von etwa **24 In-Run-Upgrades**, wenn nicht gescrollt wird. Das ist eine Design-Zahl, keine Messung — aber sie grenzt ein, wie fein die Kostenstaffelung sein muss und wie viele Kaufmomente pro Run überhaupt sinnvoll sind. Zur Erinnerung aus #3: eine 20-Minuten-Session hat ~34 Wellen, bei einer Kaufentscheidung alle zwei bis drei Wellen also 12–17 Kaufmomente. Bei 24 verfügbaren Upgrades heißt das: **der Spieler kann in einem Run nicht alles kaufen** — das ist eine Entscheidung, kein Zufall, und sie macht die Kaufreihenfolge zum eigentlichen In-Run-Spiel. ## Offen Der Aufbau des Meta-Screens (Workshop, Cards, Slot-Fortschritt), was beim Tod passiert, und ob der HUD-Tab-Zustand über Runs hinweg erhalten bleibt.
Author
Owner

Die Spec steht. docs/spec-vertical-slice.md — 15 Features mit Akzeptanzkriterien, dazu docs/adr/0004-spatial-grid-fuer-gegner-nachbarschaft.md und ein Nachtrag zu ADR-0002 §3.

Abnahmekriterium für den Slice

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.

Es prüft alle vier Takte des Loops in einer Beobachtung und bindet die Randbedingung aus #11 ein, dass der Slice das Card-System nicht nur enthalten, sondern zeigen muss. Der Neustart am Ende prüft Save/Load dort, wo es zählt.

Was die Spec zutage gefördert hat

Sechzehn Widersprüche und herrenlose Lücken — gefunden, weil hier zum ersten Mal jemand alle Quellen gleichzeitig gelesen hat. Der Widersprüche-Abschnitt bleibt in der Spec stehen; er ist kein Mangel, sondern ihr ehrlichstes Kapitel.

Ein echter Defekt, behoben: ADR-0002 rechnete CritChance und DefensePercent auf null. Beide haben base = 0 und beziehen ihre Wirkung nur aus points — (0 + 0) × (1 + 0,37) × 1 = 0. Zwanzig Workshop-Level, eine Card und ein gekauftes Upgrade zusammen wirkungslos. Dieselbe Basis-null-Falle, wegen der es den flat-Akkumulator gibt; sie wurde dort für mult gezogen und für points übersehen.

Korrigiert durch eine dritte Modus-Variante statt eines zweiten Bits: Fraction für Stats, die selbst ein Anteil sind — clamp((base + flat + points) × mult). Dort tragen alle drei Akkumulatoren dieselbe Einheit und werden addiert statt gegeneinander skaliert. Drei billigere Wege wurden geprüft und verworfen. Die vollständige Stat-Tabelle ist einzeln nachgerechnet, das Rechenbeispiel um einen Prozent-Stat erweitert, damit der Fall nicht nochmal durchrutscht. Interval war nicht betroffen.

Drei Lücken geschlossen (Entscheidungen von Marvin):

  • Card-Slots werden aus der Meta-Währung im Workshop gekauft, neben den Stat-Upgrades. Vorher erhöhte kein Mechanismus card_slots, obwohl das Feld persistiert wird und Slot 2 im Abnahmekriterium steht.
  • Der Utility-Tab trägt Ökonomie-Upgrades statt einer einzigen Zeile: CoinGain, CoinsPerWave, CritCoinGain, FreeUpgradeChance. MetaGain bleibt ausdrücklich außerhalb des In-Run-Tabs, weil er sonst ein Coins-zu-Meta-Konvertierungspfad wäre.
  • Gegner-gegen-Gegner-Kollision: Spatial Grid mit weicher Separation, eigene ADR.

Ein Fund, der Fortschritt zerstört hätte: Das Debug-Panel springt zu Welle N, und das Run-Ende schreibt highest_wave plus Meta-Währung in den Spielstand. Ein Sprung auf Welle 500 hätte den Slice mit einem Griff trivialisiert. Akzeptanzkriterium jetzt: ein Run mit benutztem Debug-Panel schreibt nichts nach progress.toml. Wer das Panel baut, baut die Schreibsperre zuerst.

Card-Drops überqueren die Run-Grenze, ADR-0003 §6 kannte sie nicht — dort standen nur highest_wave und die Meta-Währung. Aufgelöst nach ADR-0003 statt gegen sie: Drops im Run puffern, am Run-Ende gemeinsam überführen. Wer es anders bauen will, erweitert zuerst §6, statt still ein zweites schreibendes System einzuführen.

ADR-0004: das Grid ist geteilte Infrastruktur

Drei Systeme brauchen dieselbe Nachbarschaftsabfrage und wollten bisher jedes für sich scannen — die weiche Separation, tower_fires Zielauswahl und der geteilte Reichweiten-Scan des Auslöse-Systems. Genau der Scan, dessen Siebenfach-Ausführung pro Frame in #12 als Bruchstelle benannt wurde.

  • Zellgröße folgt dem Separationsradius, nicht der Turm-Reichweite — maßgeblich ist die Häufigkeit, nicht der Radius: die Separation läuft bis zu 10 000-mal pro Frame, der Reichweiten-Scan bei einem Turm genau einmal.
  • Rebuild pro Frame, gegen die Messungen aus #4 gerechnet statt geschätzt: ein Durchlauf mit weniger Arithmetik als move_enemies, also ≤ 0,10 ms bei 10 000 Gegnern. Die Logik gesamt steigt von 0,114 auf ≤ 0,22 ms von 16,67 ms.
  • Die Projektil-Kollision wandert mit aufs Grid — entgegen der Empfehlung aus #4. Begründung: 10 000 Gegner mal ~50 Projektile sind genau die dort gemessene Grenze von 5·10⁵ Paartests, und beide Faktoren wachsen entlang der Schwierigkeitskurve — n mit der Soll-Population, m weil AttackInterval sinkt. Das Produkt wächst quadratisch gegen ein festes Budget.
  • Die weiche Separation ist ein geklemmter Positionsversatz. Die Klemmung ist die Antwort auf den Turmring, wo die Dichte am höchsten ist und der Rest-Vektor nach außen zeigt — ohne sie pulsiert der Ring.

Was offen bleibt, und das ist Absicht

Die vier freien Zahlen der Kurve · der Name der Meta-Währung · der Meta-Screen · MaxHealth mitten im Run (fällig vor dem ersten Defence-Shop-Upgrade, nicht als Fernfrage) · SlowAura · die Zusammensetzung der Card-Liste · und zwei stehengelassene Widersprüche: die Nicht-Konvertierbarkeit ist nur in eine Richtung ausgesprochen, und Slots aus der Meta-Währung erzeugen für Slot 3–5 genau die Konkurrenz, die #11 für Cards verworfen hat.

Damit ist die Destination der Karte erreicht: Spec plus die tragenden Architektur-Entscheidungen für einen spielbaren Vertical Slice. Vier ADRs, eine Spec, ein HUD-Entwurf.

**Die Spec steht.** `docs/spec-vertical-slice.md` — 15 Features mit Akzeptanzkriterien, dazu `docs/adr/0004-spatial-grid-fuer-gegner-nachbarschaft.md` und ein Nachtrag zu ADR-0002 §3. ## Abnahmekriterium für den Slice > 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. Es prüft alle vier Takte des Loops in einer Beobachtung und bindet die Randbedingung aus #11 ein, dass der Slice das Card-System nicht nur enthalten, sondern **zeigen** muss. Der Neustart am Ende prüft Save/Load dort, wo es zählt. ## Was die Spec zutage gefördert hat Sechzehn Widersprüche und herrenlose Lücken — gefunden, weil hier zum ersten Mal jemand alle Quellen gleichzeitig gelesen hat. Der Widersprüche-Abschnitt bleibt in der Spec stehen; er ist kein Mangel, sondern ihr ehrlichstes Kapitel. **Ein echter Defekt, behoben**: ADR-0002 rechnete `CritChance` und `DefensePercent` **auf null**. Beide haben `base = 0` und beziehen ihre Wirkung nur aus `points` — `(0 + 0) × (1 + 0,37) × 1 = 0`. Zwanzig Workshop-Level, eine Card und ein gekauftes Upgrade zusammen wirkungslos. Dieselbe Basis-null-Falle, wegen der es den `flat`-Akkumulator gibt; sie wurde dort für `mult` gezogen und für `points` übersehen. Korrigiert durch eine **dritte Modus-Variante** statt eines zweiten Bits: `Fraction` für Stats, die selbst ein Anteil sind — `clamp((base + flat + points) × mult)`. Dort tragen alle drei Akkumulatoren dieselbe Einheit und werden addiert statt gegeneinander skaliert. Drei billigere Wege wurden geprüft und verworfen. Die vollständige Stat-Tabelle ist einzeln nachgerechnet, das Rechenbeispiel um einen Prozent-Stat erweitert, damit der Fall nicht nochmal durchrutscht. `Interval` war nicht betroffen. **Drei Lücken geschlossen** (Entscheidungen von Marvin): - **Card-Slots** werden aus der Meta-Währung im Workshop gekauft, neben den Stat-Upgrades. Vorher erhöhte *kein Mechanismus* `card_slots`, obwohl das Feld persistiert wird und Slot 2 im Abnahmekriterium steht. - **Der Utility-Tab** trägt Ökonomie-Upgrades statt einer einzigen Zeile: `CoinGain`, `CoinsPerWave`, `CritCoinGain`, `FreeUpgradeChance`. `MetaGain` bleibt ausdrücklich *außerhalb* des In-Run-Tabs, weil er sonst ein Coins-zu-Meta-Konvertierungspfad wäre. - **Gegner-gegen-Gegner-Kollision**: Spatial Grid mit weicher Separation, eigene ADR. **Ein Fund, der Fortschritt zerstört hätte**: Das Debug-Panel springt zu Welle N, und das Run-Ende schreibt `highest_wave` plus Meta-Währung in den Spielstand. Ein Sprung auf Welle 500 hätte den Slice mit einem Griff trivialisiert. Akzeptanzkriterium jetzt: **ein Run mit benutztem Debug-Panel schreibt nichts nach `progress.toml`.** Wer das Panel baut, baut die Schreibsperre zuerst. **Card-Drops überqueren die Run-Grenze**, ADR-0003 §6 kannte sie nicht — dort standen nur `highest_wave` und die Meta-Währung. Aufgelöst nach ADR-0003 statt gegen sie: Drops im Run puffern, am Run-Ende gemeinsam überführen. Wer es anders bauen will, erweitert zuerst §6, statt still ein zweites schreibendes System einzuführen. ## ADR-0004: das Grid ist geteilte Infrastruktur Drei Systeme brauchen dieselbe Nachbarschaftsabfrage und wollten bisher jedes für sich scannen — die weiche Separation, `tower_fire`s Zielauswahl und der geteilte Reichweiten-Scan des Auslöse-Systems. Genau der Scan, dessen Siebenfach-Ausführung pro Frame in #12 als Bruchstelle benannt wurde. - **Zellgröße** folgt dem Separationsradius, nicht der Turm-Reichweite — maßgeblich ist die Häufigkeit, nicht der Radius: die Separation läuft bis zu 10 000-mal pro Frame, der Reichweiten-Scan bei einem Turm genau einmal. - **Rebuild pro Frame**, gegen die Messungen aus #4 gerechnet statt geschätzt: ein Durchlauf mit weniger Arithmetik als `move_enemies`, also ≤ 0,10 ms bei 10 000 Gegnern. Die Logik gesamt steigt von 0,114 auf ≤ 0,22 ms von 16,67 ms. - **Die Projektil-Kollision wandert mit aufs Grid** — entgegen der Empfehlung aus #4. Begründung: 10 000 Gegner mal ~50 Projektile sind genau die dort gemessene Grenze von 5·10⁵ Paartests, und **beide** Faktoren wachsen entlang der Schwierigkeitskurve — `n` mit der Soll-Population, `m` weil `AttackInterval` sinkt. Das Produkt wächst quadratisch gegen ein festes Budget. - **Die weiche Separation** ist ein geklemmter Positionsversatz. Die Klemmung ist die Antwort auf den Turmring, wo die Dichte am höchsten ist und der Rest-Vektor nach außen zeigt — ohne sie pulsiert der Ring. ## Was offen bleibt, und das ist Absicht Die vier freien Zahlen der Kurve · der Name der Meta-Währung · der Meta-Screen · `MaxHealth` mitten im Run (fällig **vor** dem ersten Defence-Shop-Upgrade, nicht als Fernfrage) · `SlowAura` · die Zusammensetzung der Card-Liste · und zwei stehengelassene Widersprüche: die Nicht-Konvertierbarkeit ist nur in eine Richtung ausgesprochen, und Slots aus der Meta-Währung erzeugen für Slot 3–5 genau die Konkurrenz, die #11 für Cards verworfen hat. Damit ist die Destination der Karte erreicht: **Spec plus die tragenden Architektur-Entscheidungen für einen spielbaren Vertical Slice.** Vier ADRs, eine Spec, ein HUD-Entwurf.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RDietermann/InfiniTower#10