From 1938705ff9d71df94e862f511c50729b47dc7c61 Mon Sep 17 00:00:00 2001 From: Dennis Westermann Date: Mon, 17 Aug 2026 22:21:29 +0200 Subject: [PATCH] =?UTF-8?q?docs(sprint):=20Sprint=2021=20festplanen=20und?= =?UTF-8?q?=20als=20Gro=C3=9Fauftrag=20erteilen=20(D-108,=20D-109)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aus dem Vorschlag zu den Verknappungsfolgen (Testbericht T-01, #85-#94) wird nach zwei Inhaberentscheidungen ein festgeplanter Sprint. Reine Dokumentation, kein Spielcode berührt. D-108: Territorium wächst kriechend an jedem eigenen Bauanker. Die Regel steht so im Code (BuildInfluenceRadiusCells misst ab einem Bauanker, nicht ab dem HQ), wurde aber nie ausgesprochen. Sie bleibt und ist ab jetzt gewollte Mechanik. Die gemeldete Enge wird an MinimumBuildingDistanceCells gemessen, bevor ein Wert fällt. D-109: Die Kartenmitte wird ein Gebiet mit schmalen Zufahrten, mit der verbindlichen Auflage, dass Begehbarkeit und Optik aus einer einzigen Struktur stammen. Heute tun sie das nicht: CostField kann unbegehbare Zellen, aber es schreibt niemand hinein ausser ConstructionSystem, während GlutrinneBlockoutView begehbare Deko-Felsen streut. Neu: - 21_Sprint_Verknappungsfolgen.md — sieben Pakete, nach Abhängigkeit sortiert - AUFTRAG_Verknappungsfolgen.md — Sprint 21, danach Sprint 18 Berichtigt: AUFTRAG_Grossblock.md behauptete, dotnet test laufe lokal nicht. Es läuft mit dem im Repo mitgelieferten .dotnet/ (8.0.318, exakt die in global.json gepinnte Version). Ebenso im Index: Lager und Radar sind seit Sprint 16.4/16.5 keine Attrappen mehr, und Sprint 17 Paket A war Block 3, nicht Block 4. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 36 ++ docs/production/DecisionLog.md | 110 ++++- .../hashkrieg/21_Sprint_Verknappungsfolgen.md | 395 ++++++++++++++++++ .../hashkrieg/AUFTRAG_Grossblock.md | 15 +- .../hashkrieg/AUFTRAG_Verknappungsfolgen.md | 276 ++++++++++++ docs/production/hashkrieg/README.md | 60 ++- 6 files changed, 865 insertions(+), 27 deletions(-) create mode 100644 docs/production/hashkrieg/21_Sprint_Verknappungsfolgen.md create mode 100644 docs/production/hashkrieg/AUFTRAG_Verknappungsfolgen.md diff --git a/CHANGELOG.md b/CHANGELOG.md index c0c7b7d..2aab35a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,32 @@ die Versionierung folgt (in der aktuellen Doku-Phase) dem Dokumentationsstand de > erzeugt; MS-0 und MS-1 bleiben offen. ### Entschieden +- **D-108: Territorium wächst kriechend an jedem eigenen Bauanker.** Die Frage + aus Testbericht T-01 (#92) — erweitert ein zweites HQ den Baubereich? — war im + Code längst beantwortet und nie ausgesprochen: + `ConstructionSystem.BuildInfluenceRadiusCells = 8` misst ab **einem eigenen + Bauanker**, nicht ab dem HQ, also erweitert jedes fertige Gebäude die Zone um + seinen eigenen Radius. Das bleibt so und ist ab jetzt gewollte Mechanik: es ist + das klassische C&C-Verhalten und koppelt Expansion genau so an die Wirtschaft, + wie die Verknappung aus D-102 es verlangt. Die gemeldete Enge wird + **nicht** über den Radius beantwortet, sondern zuerst gemessen — Sprint 21 + Paket 21.1 liefert als Test, wie viele Gebäude bei + `MinimumBuildingDistanceCells` 2 gegen 1 gegen 0 in die Startzone passen, weil + dieser Wert Zellen *innerhalb* der Zone sperrt und die plausiblere Ursache ist +- **D-109: Die Kartenmitte wird ein Gebiet mit schmalen Zufahrten.** Feld 5 liegt + bei (62, 62) und trägt mit 15.000 AE zwei Drittel mehr als jedes andere — die + Absicht „die Mitte ist wertvoll" war getroffen, nur nicht ausgespielt. Aus dem + einen Feld werden vier bis sechs, und das Gelände formt die Zufahrten. + Verbindliche Auflage: **Begehbarkeit und Optik stammen aus einer einzigen + Struktur.** Heute tun sie das nicht — `CostField` kann unbegehbare Zellen + (`ImpassableCost = 255`), aber es schreibt niemand hinein ausser + `ConstructionSystem` für Gebäude-Footprints, während `GlutrinneBlockoutView` + rund 84 Felsen streut und im eigenen Docstring zusichert, nie in den + Simulationszustand zu schreiben — die Felsen sind Deko und begehbar. Zwei + Quellen ergäben Einheiten, die durch Felsen laufen und an unsichtbaren Wänden + hängenbleiben. Die Umsetzung bleibt beim Maintainer-Strang: + `CostField.SetCost` ist bereits öffentlich und wird aus `Gameplay/Match/` + aufgerufen, `Simulation/Pathfinding/` wird nicht angefasst - **D-105: Dennis Westermann (`@cubetribe`) führt das Projekt allein.** Er ist alleiniger Projektinhaber, Maintainer, Tier-Entscheider und Mergeberechtigter; Michael Falk (`@travelhawk`) bleibt historischer Autor und @@ -30,6 +56,16 @@ die Versionierung folgt (in der aktuellen Doku-Phase) dem Dokumentationsstand de spielerisch abgenommen und kein Meilenstein-Nachweis ### Hinzugefügt +- **Sprint 21 festgeplant und als Großauftrag erteilt.** Aus dem Vorschlag zu den + Verknappungsfolgen wird nach den Inhaberentscheidungen D-108 und D-109 die + Sprintdatei `docs/production/hashkrieg/21_Sprint_Verknappungsfolgen.md` mit + sieben Paketen (Restbestand sichtbar, Baubereich sichtbar, Auswahl ehrlich, + Startmenge gerechnet, Kartendichte, zentrale Zone) und der gebündelte Auftrag + `AUFTRAG_Verknappungsfolgen.md`, der Sprint 21 und danach Sprint 18 in eine + verbindliche Reihenfolge bringt. Beide sind gegen `main` @ `3e10c48` geprüft. + Nebenbei berichtigt: `AUFTRAG_Grossblock.md` behauptete, `dotnet test` laufe + lokal nicht — es läuft mit dem im Repo mitgelieferten `.dotnet/` (8.0.318, + exakt die in `global.json` gepinnte Version) in rund 14 Sekunden - **Testbericht T-01 vom 10.08.2026 (Build `4053c15`) zerlegt — zehn Issues (#85–#94) und ein Sprintvorschlag.** Der Bericht bewertet die mit #80 eingeführte AE-Verknappung und zeigt, dass diese eine Änderung acht weitere diff --git a/docs/production/DecisionLog.md b/docs/production/DecisionLog.md index 01d9e11..95f08f7 100644 --- a/docs/production/DecisionLog.md +++ b/docs/production/DecisionLog.md @@ -1,6 +1,6 @@ # Decision Log -**Version:** 1.39.0 | **Status:** aktiv (laufend) | **Verantwortungsbereich:** Game Director / Lead Technical Director / Project Owner | **Sprint:** 16 +**Version:** 1.40.0 | **Status:** aktiv (laufend) | **Verantwortungsbereich:** Game Director / Lead Technical Director / Project Owner | **Sprint:** 21 ## Zweck @@ -3429,6 +3429,113 @@ selbst. und Befehlsschemata bleiben unverändert. D-102 bleibt für Feldanzahl, Koordinaten, Reserven, Reihenfolge und Ernterate vollständig verbindlich. +### D-108 | verbindlich | Sprint 21 (Territorium wächst kriechend an jedem Bauanker) + +**Status:** Inhaberentscheidung vom 2026-08-17. + +**Kontext:** Testbericht T-01 (#92) fragt, wie der Spieler sein Territorium +erweitert — ob ein zweites HQ die Bauzone vergrößert, ob es später eigene +Erweiterungsgebäude gibt, ob Bauzonen sich überschneiden dürfen. Der Code +beantwortet die Frage bereits, ausgesprochen wurde sie nie: +`ConstructionSystem.BuildInfluenceRadiusCells = 8` misst die maximale +footprint-bewusste Chebyshev-Distanz **von einem eigenen Bauanker**, nicht vom +HQ. Damit erweitert jedes fertiggestellte Gebäude das erlaubte Feld um seinen +eigenen Radius; die Zone kriecht mit der Basis mit, statt sprunghaft an einem +zweiten HQ zu wachsen. Der Bericht meldet zugleich, der Platz sei „nach einigen +Kraftwerken relativ schnell ausgeschöpft" — wofür `MinimumBuildingDistanceCells = 2` +die wahrscheinlichere Ursache ist als der Radius, weil dieser Wert Zellen +*innerhalb* der Zone sperrt. + +**Alternativen:** + +1. Die bestehende Regel festschreiben: jedes eigene Gebäude bleibt Bauanker. +2. Nur ausgewiesene Gebäude (HQ, Raffinerie, ein künftiger Expansionsposten) + werden Anker; alle übrigen erweitern die Zone nicht. +3. Die Regel beibehalten und den Radius über 8 anheben. + +**Entscheidung:** Alternative 1. **Jedes eigene Gebäude bleibt Bauanker**, das +Kriechen ist gewollt und ab sofort ausgesprochene Mechanik. Die gemeldete Enge +wird **nicht** über den Radius beantwortet, sondern zuerst gemessen: Sprint 21 +Paket 21.1 liefert als Test, wie viele Gebäude welcher Footprintgröße bei +`MinimumBuildingDistanceCells` 2 gegen 1 gegen 0 in die Startzone passen. Erst +gegen diese Zahl wird über den Wert entschieden. + +**Begründung:** Das kriechende Wachstum ist das klassische C&C-Verhalten und +koppelt Expansion genau so an die Wirtschaft, wie die Verknappung aus D-102 es +verlangt: Wer ein entferntes Feld erschließen will, muss sich baulich dorthin +arbeiten. Alternative 2 wäre eine echte Designerweiterung mit eigenem +Gebäudetyp und gehört nicht in einen Sprint, der Bestehendes lesbar macht. +Alternative 3 behebt möglicherweise das falsche Problem — der Radius ist nicht +belegt als Ursache, die Mindestdistanz ist es plausibel. + +**Konsequenzen:** Der Docstring an `BuildInfluenceRadiusCells` wird so +umgeschrieben, dass die Ankerregel nicht mehr nur ein Nebensatz ist. Das +Baubereichs-Overlay (#91, Paket 21.4) färbt die **tatsächlich baubaren Zellen** +für den gewählten Footprint ein, nicht einen Radius-Ring — ein Ring wäre +unehrlich, weil er die innerhalb gesperrten Zellen verschweigt. Fällt +`MinimumBuildingDistanceCells` später nach der Messung, ist das ein eigener PR +mit eigener D-ID und bewegt `RulesHash64`. Die Kartendichte (#93, Paket 21.6) +hängt an dieser Festlegung und läuft danach. + +### D-109 | verbindlich | Sprint 21 (Die Kartenmitte wird ein Gebiet mit Chokepoints) + +**Status:** Inhaberentscheidung vom 2026-08-17. + +**Kontext:** Testbericht T-01 (#94) schlägt vor, im Zentrum eine größere +abgeschlossene Zone mit vier bis sechs Aetheriumvorkommen anzulegen, von allen +vier Seiten erreichbar, aber jeweils über schmale Zufahrten. Wer die Mitte +kontrolliert, erhält einen wirtschaftlichen Vorteil und kann die Position +befestigen — die Karte erzeugt damit einen Konfliktpunkt, ohne ihn +vorzuschreiben. Die Absicht ist bereits getroffen und nur nicht ausgespielt: +Feld 5 liegt bei (62, 62) und trägt mit 15.000 AE zwei Drittel mehr als jedes +andere Feld. Ein einzelnes Feld ist aber kein Gebiet, und ohne Chokepoints ist +es auch keine haltbare Position. + +Am Code geprüft (`main` @ `3e10c48`): `CostField` unterstützt unbegehbares +Gelände vollständig (`OpenCost = 1`, `ImpassableCost = 255`, Zwischenwerte für +schweren Grund), aber der Konstruktor füllt alles mit `OpenCost` und es schreibt +**niemand** hinein außer `ConstructionSystem` für Gebäude-Footprints. Die Optik +weiß davon nichts: `GlutrinneBlockoutView` streut rund 84 Felsen mit festem Seed +und sichert im eigenen Docstring zu, nie in den Simulationszustand zu schreiben — +die Felsen sind Deko und begehbar. + +**Alternativen:** + +1. Zone und Chokepoints bauen, mit einer autoritativen Geländequelle für + Simulation und Optik. +2. Nur die Kartenlage ändern (vier bis sechs Felder gruppieren), auf Gelände + verzichten. +3. Zurückstellen, bis die KI ein Gebiet bestreiten kann. + +**Entscheidung:** Alternative 1. Die Mitte wird ein Gebiet mit schmalen +Zufahrten. Verbindliche Auflage: **Begehbarkeit und Optik stammen aus einer +einzigen Struktur** — die kanonische Kartenlage in `MatchBootstrap` hält das +Gelände so, wie sie heute schon die fünf Aetheriumfelder hält; die Simulation +schreibt es über die bestehende öffentliche `CostField.SetCost`, die +Blockout-View baut sich daraus. Zwei getrennte Quellen sind ausdrücklich +untersagt. + +**Begründung:** Zwei Quellen ergeben Einheiten, die durch sichtbare Felsen +laufen und an unsichtbaren Wänden hängenbleiben — ein Fehlerbild, das später +niemand mehr der Kartenarbeit zuordnet. Alternative 2 nimmt dem Vorschlag genau +das, was ihn trägt: ohne Chokepoints ist eine reiche Mitte kein Halteproblem, +sondern nur ein größerer Wettlauf. Alternative 3 verschiebt die Kartenarbeit +hinter fremde Sprintplanung, obwohl die Karte auch ohne kluge KI zwischen zwei +Menschen gespielt wird. + +**Konsequenzen:** Die Umsetzung bleibt in der Schreibhoheit des +Maintainer-Strangs: `Gameplay/Match/` und `Presentation/Maps/` werden +bearbeitet, `Simulation/Pathfinding/` **nicht** — `CostField.SetCost` ist +bereits öffentlich und wird von `Gameplay/Match/` aus aufgerufen, wie +`PathfindingTestBootstrap` es vorführt. Die Symmetrieauflage aus D-107 gilt +unverändert. Ein Erreichbarkeitstest über das `FlowField` gehört in +`tools/Nova.SimRunner.Tests/`, damit eine spätere Kartenänderung keine Basis +unbemerkt einsperrt. Die Änderung bewegt die Determinismus-Baselines **und** den +gepinnten Ausgang der kanonischen KI-Partie, der dem Einheitenstrang gehört — +sie braucht deshalb ein eigenes, mit dem Einheitenstrang abgestimmtes +Merge-Fenster. Verteidigungsbalance an den Zufahrten und KI-Verhalten in der +Mitte sind ausdrücklich nicht Teil dieser Entscheidung. + ## Offene Punkte - Alle Sprint-4-Review-Befunde (105, davon 9 kritisch): 7 entscheidungsbedürftige kritische Befunde sind durch D-043–D-052 entschieden. @@ -3509,6 +3616,7 @@ Koordinaten, Reserven, Reihenfolge und Ernterate vollständig verbindlich. | Version | Datum | Änderung | Autor | |---|---|---|---| +| 1.40.0 | 2026-08-17 | D-108 und D-109 aufgenommen (Sprint 21, aus Testbericht T-01): Territorium wächst **kriechend an jedem eigenen Bauanker** — die bestehende Regel wird festgeschrieben statt geändert, und die gemeldete Enge wird an `MinimumBuildingDistanceCells` gemessen, bevor ein Wert fällt. Die Kartenmitte wird ein Gebiet mit schmalen Zufahrten, mit der verbindlichen Auflage, dass Begehbarkeit und Optik aus **einer** Struktur stammen — heute streut `GlutrinneBlockoutView` begehbare Deko-Felsen, während niemand ausser `ConstructionSystem` in das `CostField` schreibt | Dennis Westermann / Orchestrator | | 1.39.0 | 2026-08-10 | D-107 aufgenommen: Die bestehende Glutrinne-Layoutachse spiegelt Punkte um 124 und 3×3-Footprint-Ursprünge abgeleitet um 122; der zweite HQ-Ursprung wird von `(120,120)` auf `(118,118)` korrigiert | Agent (unter Delegation) / Dennis Westermann | | 1.38.0 | 2026-08-10 | D-104 aufgenommen: footprintbasierte Chebyshev-Platzierung mit Einfluss-, Feld-, Gelände- und Gebäudeabständen, zustandslose kumulative Reparaturkosten von 30 Prozent, kanonisch dichte Reparaturreihenfolge und Rules-Revision V3 | Project Owner / Agent (unter Delegation) | | 1.37.0 | 2026-08-10 | D-103 aufgenommen: Bauvoraussetzungen werden eine fraktionsgleiche All-of-Maske über unveränderte `UnitRole`-Wirewerte; Hash-, Fail-Closed-, Plattformmodul- und KI-Handoff-Folgen festgeschrieben | Agent (unter Delegation) / Dennis Westermann | diff --git a/docs/production/hashkrieg/21_Sprint_Verknappungsfolgen.md b/docs/production/hashkrieg/21_Sprint_Verknappungsfolgen.md new file mode 100644 index 0000000..bb2f8ff --- /dev/null +++ b/docs/production/hashkrieg/21_Sprint_Verknappungsfolgen.md @@ -0,0 +1,395 @@ +# Sprint 21: Die Folgen der Verknappung — endliche Felder werden lesbar und bespielbar + +**Version:** 1.0.0 | **Status:** geplant | **Verantwortungsbereich:** Maintainer-Strang | **Sprint:** 21 | **Vorgänger:** [16_Sprint_Wirtschaft.md](16_Sprint_Wirtschaft.md) | **Parallel zu:** [13B](13B_Sprint_Einheitenverhalten.md) | **Regelwerk:** [13-15_Parallelbetrieb.md](13-15_Parallelbetrieb.md) | **UX-Gate:** human | **Leitsatz:** endliche Felder sind kein Wert, sondern ein Systemwechsel + +## Zweck + +Mit [#80](https://github.com/VibecodingGermany/HashKrieg/pull/80) bekamen die +Aetheriumfelder eine endliche Reserve. Der Testbericht T-01 vom 10.08.2026 +zeigt, dass diese eine Änderung acht weitere Systeme betrifft, die noch auf der +alten Annahme unendlicher Vorkommen stehen. Dieser Sprint zieht sie nach. + +Er tut dabei **drei verschiedene Dinge**, und die Unterscheidung ist wichtig: + +1. Er macht **sichtbar**, was die Simulation längst exakt weiß (Restbestand, + Baubereich, Auswahlinhalt). Kein neues Verhalten, nur der Weg nach außen. +2. Er **spricht aus**, was der Code bereits entscheidet, ohne dass es je + festgelegt wurde (Territoriumswachstum). Eine Festlegung, keine Umsetzung. +3. Er **ändert die Karte** — Felddichte und die Mitte als Gebiet. Das ist die + einzige echte Verhaltensänderung des Sprints und die teuerste. + +## Herkunft dieser Datei + +Aus dem [Vorschlag zur Sprintbildung](20_Vorschlag_Verknappungsfolgen.md), +geschnitten aus [Testbericht T-01](Testberichte/2026-08-10_4053c15_T-01.md) +(Build `4053c15`). Der Vorschlag war ausdrücklich kein Sprint; diese Datei ist +die Festplanung nach den Inhaberentscheidungen vom 2026-08-17 +(**D-108** Territorium, **D-109** zentrale Zone). + +Ein Befund des Vorschlags ist bereits erledigt: **#85** (KI-Livelock auf dem +leeren Feld) wurde vom Einheitenstrang in +[#97](https://github.com/VibecodingGermany/HashKrieg/pull/97) behoben und ist +geschlossen. Die Vertragsflächen **#89** und **#90** (Patrouille, Bewachen) +bleiben ausdrücklich draußen — Begründung unter „Bewusst nicht in diesem Sprint". + +## Ausgangslage — am Code geprüft + +Alles hier ist gegen `main` @ `3e10c48` verifiziert. + +**Der Restbestand existiert exakt und kommt nirgends an.** `AetheriumField.RemainingAE` +ist monoton fallend, `IsExhausted` ist definiert, `EconomySystem` führt beides +sauber über den Snapshot. Die einzige Stelle, die ihn für einen Menschen liest, +ist `Presentation/UI/DebugHud.cs` — und das Debug-HUD ist kein Spiel-UI. Im +Match sind Felder nur *Ziel* eines Harvest-Befehls (`RtsDeviceInput`), kein +anklickbares Objekt mit eigenem Zustand. + +**`AetheriumField` kennt keine Anfangsreserve.** Eine Anzeige „6.420 / 9.000" +braucht den Sollwert. Ihn als Feld in den Zustand zu legen wäre eine +Layoutänderung an `Simulation/State/` — **eingefroren**, D-ID-pflichtig, und für +diesen Zweck unnötig: die Anfangsreserve steht in der kanonischen Kartenlage und +ist von dort ableitbar. Siehe Paket 21.2. + +**Die Baubereichsregel ist scharf und unsichtbar.** In +`Simulation/Construction/ConstructionSystem.cs` gilt seit D-104: + +```csharp +public const int BuildInfluenceRadiusCells = 8; // ab JEDEM eigenen Bauanker +public const int MinimumBuildingDistanceCells = 2; // sperrt Zellen INNERHALB der Zone +``` + +Der Spieler erfährt beides nur durch Ablehnung. Seit #83 bekommt er immerhin den +Grund genannt — aber erst nach dem Fehlversuch und ohne zu sehen, wo es ginge. + +**Die Befehlskarte liest nur die Führungseinheit.** `CommandCardHud.BuildModel` +nimmt `selected[0]`, fragt `GetUnitCommands(faction, leadRole)` und hängt +`(+N weitere)` an den Titel. Die angebotenen Befehle hängen damit von der +*Reihenfolge* der Auswahl ab, nicht von ihrem Inhalt. + +**Die Karte kennt kein natürliches Gelände.** `CostField` unterstützt es +vollständig — `OpenCost = 1`, `ImpassableCost = 255`, Zwischenwerte 2..254 für +schweren Grund. Aber es schreibt **niemand** hinein außer +`ConstructionSystem` (Gebäude-Footprints) und einem Test-Bootstrap. Der +`CostField`-Konstruktor füllt alles mit `OpenCost`. + +Und die Optik weiß davon nichts: `Presentation/Maps/GlutrinneBlockoutView` +streut ~84 Felsen mit festem Seed und schreibt laut eigener Zusicherung +*„never writes into simulation state"* — die Felsen sind Deko und begehbar. +**Wer Chokepoints baut, muss beide Seiten aus derselben Quelle speisen**, sonst +laufen Einheiten durch Felsen und bleiben an unsichtbaren Wänden stehen. Das ist +der eigentliche Inhalt von Paket 21.7. + +**Die Feldlage steht viermal literal im Repo** (siehe „Risiken"). + +## Schreibhoheit + +Dieser Sprint gehört dem **Maintainer-Strang**. Er fasst keine Datei des +Einheitenstrangs an. + +**Erlaubt:** + +``` +Assets/_Project/Scripts/Gameplay/Match/ MatchBootstrap, Kartenlage, Gelände +Assets/_Project/Scripts/Gameplay/UI/ SelectionManager +Assets/_Project/Scripts/Simulation/Economy/ nur lesend erweitern, kein Layout +Assets/_Project/Scripts/Simulation/Construction/ nur Konstanten, siehe 21.1 +Assets/_Project/Scripts/Presentation/ Maps, UI, Overlays +tools/Nova.SimRunner/ Determinismus-Drehbuch +tools/Nova.SimRunner.Tests/ eigene neue Tests +``` + +**Verboten — gehört dem Einheitenstrang (13B):** + +``` +Assets/_Project/Scripts/Simulation/Combat/ +Assets/_Project/Scripts/Simulation/Movement/ +Assets/_Project/Scripts/Simulation/Factions/ +Assets/_Project/Scripts/Simulation/Pathfinding/ +Assets/_Project/Scripts/AI/ Assets/_Project/Scripts/AI.Data/ +Assets/_Project/Scripts/Presentation/UI/DebugHud.cs +tools/Nova.AiLab/ tools/Nova.AiLab.Tests/ +``` + +> **Die eine Feinheit, die Paket 21.7 möglich macht:** Gelände wird über die +> **bestehende öffentliche** `CostField.SetCost` aus `Gameplay/Match/` +> geschrieben — genau so, wie es `PathfindingTestBootstrap` heute schon tut. +> `Simulation/Pathfinding/` selbst wird **nicht angefasst**. Die Schreibhoheit +> bleibt damit gewahrt. Was 21.7 trotzdem auslöst, ist eine *Wirkung* auf den +> Einheitenstrang — die KI läuft danach über eine andere Karte, ihr gepinnter +> Ausgang bewegt sich. Das ist eine Absprache- und Merge-Fenster-Frage, keine +> Hoheitsfrage. Siehe „Risiken". + +**Eingefroren, D-ID-pflichtig, in diesem Sprint nicht angefasst:** + +``` +Simulation/CommandsV1/ kein neuer CommandKind +Simulation/Snapshots/ Simulation/Replays/ Simulation/Systems/ +Simulation/State/ Layout und Serialisierung +``` + +## Pakete + +Die Reihenfolge ist nach Abhängigkeit sortiert, nicht nach Aufwand. Jedes Paket +ist ein eigener PR und für sich abnehmbar. + +### 21.1 · Die Territoriumsregel wird ausgesprochen und gemessen (#92 → D-108) + +**Kein Overlay, keine Regeländerung — erst eine Festlegung und eine Zahl.** + +Die Entscheidung ist getroffen (D-108): **jedes eigene Gebäude bleibt Bauanker**, +die Zone kriecht mit der Basis mit. Das ist klassisches C&C und koppelt Expansion +genau so an die Wirtschaft, wie die Verknappung es will. Was fehlt, ist, dass es +irgendwo steht. + +Zu liefern: + +1. Den Docstring an `BuildInfluenceRadiusCells` so umschreiben, dass die Regel + *„ab jedem eigenen Bauanker"* nicht mehr nur ein Nebensatz ist, mit Verweis + auf D-108. +2. **Die Enge messen, bevor irgendetwas gedreht wird.** Der Bericht sagt, der + Platz sei „nach einigen Kraftwerken relativ schnell ausgeschöpft". Die + Vermutung aus #91 ist, dass nicht der Radius 8 die Ursache ist, sondern + `MinimumBuildingDistanceCells = 2`, das Zellen *innerhalb* der Zone sperrt. + Liefere eine Zahl, kein Gefühl: **wie viele Gebäude welcher Footprintgrößen + passen in die Startzone**, bei `MinimumBuildingDistanceCells` 2 gegen 1 + gegen 0? Als Test in `tools/Nova.SimRunner.Tests/`, damit die Zahl nicht + verfällt. +3. **Erst dann** entscheiden, ob der Wert fällt. Fällt er, ist das eine + Simulationsänderung mit eigenem PR und eigener Baseline-Bewegung — und der + Grund steht in der PR-Beschreibung mit alter und neuer Zahl. + +**Fertig wenn:** die Regel dokumentiert ist, die Kapazitätszahl als Test +existiert, und die Entscheidung über `MinimumBuildingDistanceCells` mit Zahl +begründet ist. + +### 21.2 · Der Restbestand wird sichtbar (#86) — **kritisch** + +Der wichtigste Punkt des Sprints. Ohne ihn bleibt die Verknappung eine +unsichtbare technische Mechanik. + +Zwei Dinge, die zusammengehören: + +**a) Das Vorkommen wird anklickbar und zeigt seine Zahl.** Auswahl eines Feldes +in `RtsDeviceInput`, Anzeige in der Befehlskarte im Format des Berichts: +`Aetherium-Vorkommen — 6.420 / 9.000 AE`. + +> **Den Sollwert nicht in den Zustand legen.** `AetheriumField` bekommt **kein** +> neues Feld — das wäre `Simulation/State/`-Layout und damit eingefroren. Die +> Anfangsreserve steht in der kanonischen Kartenlage (`MatchBootstrap.FieldLayouts`) +> und wird von dort gelesen. Ein Feld, das der Präsentation gehört, ist die +> richtige Ablage für eine Zahl, die die Präsentation braucht. + +**b) Die Karte liest sich ohne Klick.** Ein volles Vorkommen besteht heute aus +etwa sieben blauen Kristallen (`GlutrinneBlockoutView`). Sie verschwinden +schrittweise mit sinkendem Bestand (7 → 6 → … → leer), und ein erschöpftes Feld +ist eindeutig als erschöpft erkennbar — nicht nur „leer", sondern sichtbar +verbraucht. + +> Die Stufung ist reine Präsentation und **darf keine Simulationsabfrage pro +> Frame** werden. Der Kristallstand folgt `RemainingAE` über dieselbe Leseschiene +> wie das übrige HUD. + +**Fertig wenn:** ein Vorkommen anklickbar ist, Rest und Anfangsreserve zeigt, und +sein Kristallstand im laufenden Match sichtbar abnimmt. + +### 21.3 · Die Startmenge wird gerechnet, nicht geraten (#87) + +**Erst nach 21.2**, sonst wird wieder geschätzt. Der Tester lag um fast die +Hälfte daneben (schätzte 5.000, es sind 9.000) — genau weil es keine Anzeige gab. + +Die Frage ist nicht „9.000 oder 10.000", sondern **wie lange soll ein Startfeld +tragen?** Das hängt an `HarvestRateAE` (heute 2 AE/Tick), der Harvesterzahl und +den Baukosten. Rechne es einmal: wie viele Sekunden Spielzeit trägt ein +Startfeld bei einem, bei zwei, bei drei Harvestern? Setze den Wert danach, nicht +davor, und schreib die Rechnung in die PR-Beschreibung. + +> **Vier Spiegel.** Siehe „Risiken" — jede Änderung an der Feldlage geht durch +> alle vier Stellen oder durch keine. + +### 21.4 · Der Baubereich wird sichtbar (#91) + +**Erst nach 21.1**, sonst zeigt das Overlay eine Regel, die sich danach ändert. + +Beim Anklicken des HQ und im Platzierungsmodus wird der erlaubte Bereich +angezeigt. **Nicht als Radius-Ring** — der wäre unehrlich, weil +`MinimumBuildingDistanceCells` Zellen *innerhalb* der Zone sperrt. Einzufärben +sind die **tatsächlich baubaren Zellen** für den gerade gewählten Footprint. +Die Prüfung existiert bereits in `ConstructionSystem`; es geht ausschließlich +darum, die vorhandene Antwort *vor* dem Klick zu zeigen statt danach. + +> Damit beantwortet das Overlay nebenbei die Beschwerde aus 21.1 direkt: der +> Spieler sieht, wie viel Platz noch da ist, statt es zu vermuten. + +**Fertig wenn:** ein Spieler ohne Fehlversuch erkennt, wo das nächste Gebäude +hinpasst — und warum eine Zelle innerhalb des Radius trotzdem gesperrt ist. + +### 21.5 · Die Auswahl sagt die Wahrheit (#88) + +**Abhängigkeitsfrei — jederzeit einzeln machbar.** Der handfeste Teil ist Punkt 3. + +`CommandCardHud.BuildModel` liest heute `selected[0]` und fragt +`GetUnitCommands(faction, leadRole)`. Daraus folgen drei Lücken: + +1. **Keine Typenaufschlüsselung.** „Panzer (+7 weitere)" sagt nicht, ob das + sieben Panzer sind oder ein Harvester und sechs Pioniere. +2. **Kein Zustand.** HP taucht in der Karte nicht auf. +3. **Die Befehle stammen vom Anführer statt von der Schnittmenge.** Steht ein + Harvester zufällig auf Position 0, bietet die Karte „Ernten" an, obwohl es + für die anderen sieben nichts bedeutet — und „Ernten" verschwindet, sobald ein + Panzer die Führung übernimmt, obwohl ein Harvester mitmarkiert ist. Die + angebotenen Befehle hängen an der Reihenfolge der Auswahl. + +Punkt 3 wird zur **Schnittmenge über alle Rollen der Auswahl**. Punkt 1 und 2 +werden zur Aufschlüsselung nach Typ mit Anzahl und Sammel-HP. + +> **Zwei Nachträge pro neuer HUD-Zeile.** `CommandCardHud.EstimateHeight` bildet +> die Höhenrechnung von `OnGUI` Zeile für Zeile nach — der Kommentar dort +> dokumentiert genau diesen Fehler („~40 px short … visible, but not +> clickable"). Und jede neue Trefferfläche gehört in `IsPointerOverHud`, sonst +> schlagen Klicks hinter dem Panel in die Welt durch. + +Alle Daten liegen bereits in `EntityManager`. Kein Simulationseingriff. + +### 21.6 · Die Karte trägt mehr Felder (#93) + +**Erst nach 21.1.** Wie weit eine Basis wachsen darf, bestimmt mit, wie dicht +Felder liegen dürfen. + +Heute: fünf Felder auf 128×128, davon zwei als Startbasis gebunden. Für zwei +Spieler bleiben **drei umkämpfte Felder** — daraus entsteht keine Entscheidung, +sondern ein Wettlauf: jeder nimmt das nächstgelegene freie Feld, die Mitte +entscheidet den Rest. Der Bericht verlangt „mindestens ungefähr doppelt so +viele". + +Kapazitätsseitig ist Luft: `EconomySystem.MaxFields = 64`. Die Zahl ist reine +Kartengestaltung, keine technische Grenze. + +Zu liefern: eine neue Feldlage mit begründeter Anzahl und Verteilung, unter +Wahrung der **bindenden Symmetrie** aus D-107 — Punkte spiegeln als +`(x, y) → (124 - x, 124 - y)`. Asymmetrie ist hier kein Geschmacksfehler, +sondern ein Balancefehler. + +> Die Mitte bleibt in diesem Paket **ein** Feld. Sie wird erst in 21.7 zum Gebiet +> — erst die Gesamtzahl, dann die Verteilung. + +### 21.7 · Die Mitte wird ein Gebiet (#94 → D-109) — **das teuerste Paket** + +**Erst nach 21.6.** Zwei Hälften, und die zweite ist die schwierige. + +**a) Kartenlage.** Vier bis sechs Felder in der Mitte gruppieren, statt des einen +Feldes bei (62, 62) mit 15.000 AE. Symmetrie nach D-107, Gesamtreserve der Zone +begründet gegen die Startfelder. + +**b) Chokepoints — und hier liegt die eigentliche Arbeit.** Schmale Zufahrten +brauchen unbegehbares Gelände. Die Maschinerie existiert (`CostField.ImpassableCost`), +benutzt wird sie nur von `ConstructionSystem`. Zu bauen ist: + +> **Eine einzige autoritative Geländequelle**, aus der *beide* Seiten lesen — +> die Simulation über `CostField.SetCost` und die Optik über +> `GlutrinneBlockoutView`. Genau so, wie die fünf Aetheriumfelder es heute schon +> machen: `MatchBootstrap` hält die kanonische Lage, die Blockout-View baut sich +> daraus. Das Gelände gehört in dieselbe Struktur. +> +> **Das ist die Kernanforderung dieses Pakets.** Zwei getrennte Quellen ergeben +> Einheiten, die durch Felsen laufen und an unsichtbaren Wänden hängenbleiben — +> und das ist ein Fehlerbild, das später niemand mehr der Kartenarbeit zuordnet. + +Zusätzlich zu prüfen und in der PR zu beantworten: + +- Sind die Zufahrten breit genug für die Gruppenbewegung? Ein Chokepoint, durch + den eine Formation nicht passt, ist kein Engpass, sondern eine Blockade. +- Bleibt jedes Feld und jedes HQ von jedem Startpunkt aus erreichbar? Ein + Erreichbarkeitstest über das `FlowField` gehört in + `tools/Nova.SimRunner.Tests/` — sonst sperrt eine spätere Kartenänderung + unbemerkt eine Basis ein. + +**Nicht in diesem Paket:** Verteidigungstürme an den Zufahrten balancieren, und +das Verhalten der KI in der Mitte. Die KI kann heute nicht um ein Gebiet +kämpfen; das ist Sache des Einheitenstrangs und keine Bringschuld dieses Sprints. + +## Bewusst nicht in diesem Sprint + +| Was | Warum | +|---|---| +| **#89 Patrouille, #90 Bewachen** | Beide brauchen einen Eintrag im **eingefrorenen** `CommandKind`-Register (Schema v1, heute 1–17), eine neue Payload und Zustand pro Einheit im Snapshot. Das ist ein API-/Schema-Vorgang: @api-guardian ist Pflicht und die Versionsrelevanz ist eher `major` als `minor`. Wer sie einem Strang still zuschlägt, bricht entweder die Hoheit oder das Schema | +| **KI-Verhalten an den Feldern** | Expansion, Feldsicherung und Eskorten gehören dem Einheitenstrang (13B). Dieser Sprint macht die Karte reicher; sie zu bespielen ist arns Paket | +| **Verteidigungstürme balancieren** | Erst wenn die Mitte steht und einmal gespielt wurde | +| **Doppelte Feldlage auflösen** | Die Verdopplung zwischen `MatchBootstrap` und `Determinism10000Scenario` wäre einen eigenen Aufräum-Issue wert, aber nicht mitten in einer Kartenänderung | + +## Risiken + +**R-1 · Die Feldlage steht viermal literal im Repo.** Verifiziert gegen +`main` @ `3e10c48`: + +``` +Assets/_Project/Scripts/Gameplay/Match/MatchBootstrap.cs:168 +tools/Nova.SimRunner/Determinism10000Scenario.cs:210 +tools/Nova.SimRunner.Tests/CanonicalMatchSetupTests.cs:85 +Assets/Tests/EditMode/Gameplay/CanonicalMatchSetupTests.cs:113 +``` + +Drei von vier ergibt einen roten Test, der wie ein Determinismusfehler aussieht +und keiner ist. Betrifft 21.3, 21.6 und 21.7. + +**R-2 · Verhalten und Baseline nie im selben PR.** Die wichtigste Regel des +Parallelbetriebs. 21.3, 21.6 und 21.7 ändern Simulationsverhalten und lassen +`SnapshotGoldenBytesTests`, `CommandGoldenBytesTests`, `SimRandomGoldenTests` +und `Determinism10000Tests` rot werden. Das ist ihr Zweck. Die Baseline wird in +einem **eigenen** PR neu gesetzt, mit altem und neuem Wert im Text und der +Begründung, warum die Änderung gewollt ist. Das Drehbuch +`Determinism10000Scenario.cs` ist davon **nicht** betroffen und darf im selben +PR nachgezogen werden. + +**R-3 · 21.6 und 21.7 bewegen den gepinnten KI-Ausgang.** Eine andere Karte +heißt eine andere kanonische Partie. `CanonicalAiOutcomeTests` gehört dem +Einheitenstrang. **Vor** dem Merge von 21.6 mit arn abstimmen, in welchem +Merge-Fenster das läuft — „ein Fenster hat einen Strang". Zwei Stränge in einem +Fenster machen einen roten Test nicht zuordenbar. + +**R-4 · Verteilte Testbuilds altern.** Der Fingerprint sperrt Matches zwischen +ungleichen Builds. Nach jedem Fenster: Build für jede Plattform, an der jemand +testet, neuer Build an alle Testenden, alter Build ist ungültig. + +**R-5 · `tools/build/` ist ignoriert.** Der Ordner sieht aus wie der +Packaging-Ordner, ist aber über `.gitignore` ausgeschlossen. Änderungen dort +verschwinden. Der getrackte Weg ist ausschließlich `tools/packaging/`. + +## Fertig wenn + +- [ ] Ein Spieler liest den Restbestand jedes Vorkommens ab, ohne das Debug-HUD + zu öffnen — als Zahl und am Kristallstand auf der Karte (21.2) +- [ ] Der Baubereich ist vor dem Klick sichtbar, inklusive der gesperrten Zellen + innerhalb des Radius (21.4) +- [ ] Die Befehlskarte zeigt bei Mehrfachauswahl Typen, Anzahl und Zustand, und + bietet nur Befehle an, die für **alle** gewählten Einheiten gelten (21.5) +- [ ] Die Startmenge steht auf einem gerechneten Wert, und die Rechnung ist + nachlesbar (21.3) +- [ ] Die Karte trägt genug Felder, dass ein Spieler zwischen Alternativen + wählt statt zu rennen (21.6) +- [ ] Die Mitte ist ein Gebiet mit schmalen Zufahrten, Optik und Begehbarkeit + stammen aus **einer** Quelle, und ein Erreichbarkeitstest sichert, dass + keine Basis eingesperrt ist (21.7) +- [ ] `dotnet test tools/Nova.SimRunner.Tests` grün, Baselines in eigenen PRs + bewegt +- [ ] **Eine gespielte Runde** — dieser Sprint ist überwiegend Oberfläche und + Kartengefühl; die CI kann davon fast nichts belegen + +## Changelog-Notiz + +Je Paket eine Zeile unter `[Unreleased]`. Für 21.6 und 21.7 gehört die alte und +die neue Feldlage in den Eintrag, nicht nur „mehr Felder". + +## Versionsrelevanz + +`minor`. Kein Vertrag bricht: kein neuer `CommandKind`, kein +`StateVersion`-Bump, keine Änderung an `SimDefinitions`. Die Kartenlage bewegt +Determinismus-Baselines, aber keine Schnittstelle. + +> Falls 21.1 zu dem Ergebnis kommt, dass `MinimumBuildingDistanceCells` fällt, +> bewegt das `RulesHash64` — dann ist das ein eigener PR mit eigener D-ID, und +> die Versionsrelevanz dieses Pakets steigt auf die Regelrevision. + +## Änderungsverlauf + +| Version | Datum | Änderung | Autor | +|---|---|---|---| +| 1.0.0 | 2026-08-17 | Erstfassung aus [20_Vorschlag_Verknappungsfolgen.md](20_Vorschlag_Verknappungsfolgen.md) nach den Inhaberentscheidungen D-108 und D-109. #85 als vom Einheitenstrang erledigt ausgetragen, #89/#90 als Vertragsflächen ausgeschlossen | Orchestrator | diff --git a/docs/production/hashkrieg/AUFTRAG_Grossblock.md b/docs/production/hashkrieg/AUFTRAG_Grossblock.md index 486accc..ae18f24 100644 --- a/docs/production/hashkrieg/AUFTRAG_Grossblock.md +++ b/docs/production/hashkrieg/AUFTRAG_Grossblock.md @@ -282,9 +282,18 @@ Es gibt zwei Bedingungen, und **beide** müssen zutreffen: Zwei Dinge, die du dazu wissen musst: -- **Lokal läuft `dotnet test` nicht.** `global.json` pinnt SDK `8.0.318` mit - `rollForward: disable`; auf der Arbeitsmaschine liegt nur `10.0.302`. Der - Nachweis läuft über die CI im PR. Behaupte keinen grünen lokalen Lauf. +- **Lokal läuft `dotnet test` sehr wohl — aber nur mit dem Repo-lokalen SDK.** + *(Berichtigt am 2026-08-17; hier stand vorher das Gegenteil.)* Im Repo-Root + liegt ein mitgeliefertes `.dotnet/` mit exakt der in `global.json` gepinnten + Version `8.0.318`; der vollständige Lauf dauert rund 14 Sekunden: + + ``` + "$PWD/.dotnet/dotnet" test tools/Nova.SimRunner.Tests/Nova.SimRunner.Tests.csproj -c Release + ``` + + Das systemweite `dotnet` (`10.0.302`) scheitert an `rollForward: disable` — + nimm **immer** den Repo-lokalen Pfad. Prüfe lokal, bevor du einen PR + aufmachst, und behaupte weiterhin keinen Lauf, den du nicht gesehen hast. - **Für Block 0, Block 2 und die HUD-Teile von Block 1 führt kein CI-Lauf Gameplay- oder Presentation-Code aus,** und die Unity-EditMode-Tests laufen mangels Lizenz nicht (`505 Unsupported protocol version`). Die Quelltext-Wächter diff --git a/docs/production/hashkrieg/AUFTRAG_Verknappungsfolgen.md b/docs/production/hashkrieg/AUFTRAG_Verknappungsfolgen.md new file mode 100644 index 0000000..99db92d --- /dev/null +++ b/docs/production/hashkrieg/AUFTRAG_Verknappungsfolgen.md @@ -0,0 +1,276 @@ +# Großauftrag: Die Folgen der Verknappung + +**Version:** 1.0.0 | **Status:** verbindlich | **Erteilt:** 2026-08-17 | **Auftraggeber:** Inhaber | **Ausführung:** Kimi (Maintainer-Seite) | **Umfang:** Blöcke 1–2, entspricht Sprint 21 und Sprint 18 | **Grundlage:** `main` @ `3e10c48` | **Leitsatz:** erst sichtbar machen, was die Simulation weiß, dann die Karte anfassen + +## Vorrangregel + +Dieses Dokument ist die **einzige verbindliche Reihenfolge** für die hier +genannten Sprints. Wo es von einer Sprintdatei abweicht, gilt dieses Dokument. +Wo es schweigt, gilt die Sprintdatei. + +Wenn dir etwas widersprüchlich vorkommt: **halte an und frag nach.** Rate nicht. +Ein falsch aufgelöster Widerspruch kostet mehr als eine Rückfrage. + +Der vorige Auftrag [AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md) ist damit +abgeschlossen, soweit er Code betraf: Block 0 (#49) und Block 1 (Sprint 16, +Pakete 16.1–16.10) liegen auf `main`. Sein Block 3 (Sprint 17 Paket A) bleibt +offen und ist **nicht** Teil dieses Auftrags. + +## Der Auftrag in einem Satz + +Aus dem Betatest T-01 vom 10.08.2026 sind zehn Issues entstanden (#85–#94). Einer +davon (#85) ist bereits vom Einheitenstrang behoben. Du erledigst die übrigen +Befunde des Maintainer-Strangs und ziehst den lange geplanten Sprint 18 direkt +hinterher, weil beide dieselben zwei Dateien anfassen — Befehlskarte und +Auswahl. + +## Warum diese Reihenfolge + +Der Bericht sagt es selbst: die endlichen Felder aus #80 waren kein Wert, +sondern ein Systemwechsel. Acht Systeme stehen noch auf der alten Annahme. Zwei +davon sind **unsichtbar geworden** statt falsch — der Restbestand und der +Baubereich existieren exakt und kommen nirgends an. Die macht dieser Auftrag +zuerst sichtbar, weil danach über Zahlen balanciert wird statt über Gefühl. + +Der Beleg dafür steht im Bericht: der Tester schätzte das Startvorkommen auf +5.000 AE, tatsächlich sind es 9.000. Die Fehleinschätzung um fast die Hälfte ist +kein Vorwurf an ihn, sondern die Messgröße für das Problem. + +## Was du nie anfasst + +Diese Pfade gehören dem **externen Beitragenden** (Einheitenstrang 13B). Ein PR, +der sie berührt, wird nicht gemergt, sondern zurückgegeben: + +``` +Assets/_Project/Scripts/Simulation/Combat/ +Assets/_Project/Scripts/Simulation/Movement/ +Assets/_Project/Scripts/Simulation/Factions/ +Assets/_Project/Scripts/Simulation/Pathfinding/ +Assets/_Project/Scripts/AI/ +Assets/_Project/Scripts/AI.Data/ +Assets/_Project/Scripts/Presentation/UI/DebugHud.cs +tools/Nova.AiLab/ tools/Nova.AiLab.Tests/ +tools/Nova.SimRunner.Tests/CanonicalAiOutcomeTests.cs +tools/Nova.SimRunner.Tests/SkirmishAi*.cs +``` + +> **Die eine Ausnahme, die du brauchst und die keine ist:** Block 1 Paket 21.7 +> schreibt Gelände über die **bestehende öffentliche** `CostField.SetCost` aus +> `Gameplay/Match/` — genauso, wie `PathfindingTestBootstrap` es heute schon +> tut. Du fasst `Simulation/Pathfinding/` dabei **nicht** an. Die Hoheit bleibt +> gewahrt. + +Diese sind **eingefroren** und brauchen eine Inhaberentscheidung mit D-ID: + +``` +Assets/_Project/Scripts/Simulation/CommandsV1/ ← kein neuer CommandKind +Assets/_Project/Scripts/Simulation/Replays/ +Assets/_Project/Scripts/Simulation/Snapshots/ +Assets/_Project/Scripts/Simulation/Systems/ +Assets/_Project/Scripts/Simulation/SimulationKernel.cs +Assets/_Project/Scripts/Simulation/State/ — nur Layout und Serialisierung +``` + +`Simulation/State/UnitCommandStateView.cs` darfst du bearbeiten, aber nur die +Befehlsanwendung — *was* ein bestehender `CommandKind` mit dem Zustand tut +(D-095). Kein neues Feld, keine neue Reihenfolge, kein `StateVersion`-Bump. + +Und diese vier Dateien fasst **kein Verhaltens-PR** an: + +``` +tools/Nova.SimRunner.Tests/SnapshotGoldenBytesTests.cs +tools/Nova.SimRunner.Tests/CommandGoldenBytesTests.cs +tools/Nova.SimRunner.Tests/SimRandomGoldenTests.cs +tools/Nova.SimRunner.Tests/Determinism10000Tests.cs +``` + +Ausnahme: ein **eigener** PR, der ausschließlich eine Baseline neu setzt, mit +altem und neuem Wert im Text und der Begründung. Nie zusammen mit einer +Verhaltensänderung. Das Drehbuch `tools/Nova.SimRunner/Determinism10000Scenario.cs` +ist davon **nicht** betroffen und darf im selben PR nachgezogen werden. + +## Die zwei Blöcke + +Arbeite sie **in dieser Reihenfolge** ab. Zwischen den Blöcken liegt ein Gate: +erst wenn der vorige gemergt und gespielt gesehen ist, fängt der nächste an. + +### Block 1 · Sprint 21 — Die Verknappung wird lesbar und bespielbar + +**Binde Sprintdatei:** [21_Sprint_Verknappungsfolgen.md](21_Sprint_Verknappungsfolgen.md) + +Sieben Pakete, 21.1 bis 21.7, in der dort stehenden Reihenfolge. Sie ist nach +Abhängigkeit sortiert, nicht nach Aufwand: + +| | Paket | Issue | Hängt an | +|---|---|---|---| +| 21.1 | Territoriumsregel aussprechen und Enge messen | #92 → D-108 | — | +| 21.2 | **Restbestand sichtbar machen** (kritisch) | #86 | — | +| 21.3 | Startmenge rechnen statt raten | #87 | 21.2 | +| 21.4 | Baubereich sichtbar machen | #91 | 21.1 | +| 21.5 | Auswahl sagt die Wahrheit | #88 | — | +| 21.6 | Karte trägt mehr Felder | #93 | 21.1 | +| 21.7 | **Die Mitte wird ein Gebiet** (teuerstes) | #94 → D-109 | 21.6 | + +**21.5 ist abhängigkeitsfrei.** Zieh es vor, wenn du an einer Stelle wartest. + +**Die Abwurfliste, falls die Zeit nicht reicht:** erst 21.7, dann 21.6, dann +21.3. **21.1, 21.2, 21.4 und 21.5 fallen nicht** — sie sind der Grund, warum +dieser Sprint existiert. Was fällt, kommt mit Begründung in den +[ScopeLedger](../ScopeLedger.md). + +**Zwei Dinge, die du aus der Sprintdatei allein nicht siehst:** + +- **21.6 und 21.7 bewegen den gepinnten Ausgang der kanonischen KI-Partie.** Eine + andere Karte heißt eine andere Partie. `CanonicalAiOutcomeTests` gehört dem + Einheitenstrang. Beide Pakete brauchen ein eigenes Merge-Fenster, abgestimmt + mit @arn-c0de — „ein Fenster hat einen Strang". Sag Bescheid, bevor du 21.6 + aufmachst, statt danach. +- **21.2 legt kein Feld in den Zustand.** Die Anzeige „6.420 / 9.000" braucht die + Anfangsreserve. Sie kommt aus der kanonischen Kartenlage, **nicht** aus einem + neuen Feld in `AetheriumField` — das wäre `Simulation/State/`-Layout und damit + eingefroren. + +### Block 2 · Sprint 18 — Befehl und Auswahl werden lesbar + +**Binde Sprintdatei:** [18_Sprint_Befehl_und_Auswahl.md](18_Sprint_Befehl_und_Auswahl.md) + +Drei Pakete, die Issues #50, #51 und #52. Fasst **keine** Simulationsdatei an +außer der Zielverteilung in `ApplyMove`. 18.3 (Formationsausrichtung) ist die +erste Abwurfkandidatin — die Verteilung selbst existiert seit Sprint 11 bereits. + +**Warum dieser Block direkt hinter Sprint 21 kommt und nicht davor:** 21.5 (#88) +und 18.1 (#50) fassen beide `CommandCardHud` und `SelectionManager` an, aus +entgegengesetzten Richtungen — 21.5 *liest* eine bestehende Auswahl, 18.1 +*stellt* eine her. Sie hintereinander zu bauen spart eine Runde Konfliktauflösung +in genau den zwei Dateien, die dieser Auftrag am häufigsten öffnet. + +## Die fünf stillen Fallen + +Diese brechen nichts sofort. Sie brechen später, an einer Stelle, die nicht nach +der Ursache aussieht. + +**1 · Die Feldlage steht viermal literal im Repo.** Verifiziert gegen `3e10c48`: + +``` +Assets/_Project/Scripts/Gameplay/Match/MatchBootstrap.cs:168 +tools/Nova.SimRunner/Determinism10000Scenario.cs:210 +tools/Nova.SimRunner.Tests/CanonicalMatchSetupTests.cs:85 +Assets/Tests/EditMode/Gameplay/CanonicalMatchSetupTests.cs:113 +``` + +Drei von vier ergibt einen roten Test, der wie ein Determinismusfehler aussieht +und keiner ist. Betrifft 21.3, 21.6 und 21.7. + +**2 · Die Symmetrie ist bindend, nicht kosmetisch.** D-107: Punkte spiegeln als +`(x, y) → (124 - x, 124 - y)`, der Ursprung eines 3×3-Footprints als +`(x, y) → (122 - x, 122 - y)`. Eine asymmetrische Feldlage ist kein +Geschmacksfehler, sondern ein Balancefehler, den niemand als solchen meldet — er +sieht aus wie „die KI ist zu stark". + +**3 · Gelände hat heute genau eine Quelle zu viel.** `CostField` kann +unbegehbare Zellen (`ImpassableCost = 255`), aber es schreibt niemand hinein +außer `ConstructionSystem`. Und `GlutrinneBlockoutView` streut ~84 Felsen, die +laut eigener Zusicherung *„never writes into simulation state"* — sie sind +**Deko und begehbar**. Wer in 21.7 Chokepoints baut und beide Seiten getrennt +speist, bekommt Einheiten, die durch Felsen laufen und an unsichtbaren Wänden +hängenbleiben. Optik und Begehbarkeit müssen aus **derselben** Struktur stammen, +so wie die fünf Aetheriumfelder es heute schon tun. + +**4 · Jede neue HUD-Zeile braucht zwei Nachträge.** `CommandCardHud.EstimateHeight` +bildet die Höhenrechnung von `OnGUI` Zeile für Zeile nach — der Kommentar dort +dokumentiert genau diesen Fehler aus der Vergangenheit („~40 px short … visible, +but not clickable"). Und jede neue Trefferfläche gehört in `IsPointerOverHud`, +das heute drei Komponenten kennt; fehlt sie, schlagen Klicks hinter dem Panel in +die Welt durch. Betrifft 21.2, 21.5 und den ganzen Block 2. + +**5 · `tools/build/` ist ignoriert.** Der Ordner sieht aus wie der +Packaging-Ordner und enthält eine fast identische Kopie von `build-mac.sh`, ist +aber über `.gitignore` ausgeschlossen. Änderungen dort verschwinden. Der +getrackte Weg ist ausschließlich `tools/packaging/`. + +## Wie du arbeitest + +| | | +|---|---| +| **Branch** | eigener Topic-Branch je Paket (`feat/`, `fix/`), `main` ist PR-only | +| **PR-Schnitt** | ein PR je Paket. Lieber mehrere kleine als einer, der drei Ordner öffnet | +| **Verhalten und Baseline** | nie im selben PR. Baseline-Neusetzung ist ein eigener PR mit altem und neuem Wert im Text | +| **CHANGELOG** | genau eine Zeile unter `[Unreleased]`, ganz oben im Abschnitt. Keine datierte Versionsüberschrift anlegen | +| **Commit** | Conventional Commit | +| **Push** | **nie ohne ausdrückliche Freigabe des Inhabers** | +| **Deploy** | nie. Weder VPS noch Supabase | + +### Der Nachweis + +Zwei Bedingungen, und **beide** müssen zutreffen: + +1. `dotnet test tools/Nova.SimRunner.Tests` ist grün — bei einem + verhaltensändernden PR **nach** dem unmittelbar folgenden Baseline-PR. Ein + roter Golden-Byte-Test im Verhaltens-PR ist dort erwartet und kein Blocker. +2. Ein Mensch hat die Sache im laufenden Spiel gesehen und es notiert — im PR + oder im [GrayboxLog](../GrayboxLog.md). + +> **Berichtigung gegenüber [AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md):** +> dort steht, lokal laufe `dotnet test` nicht. **Das stimmt nicht (mehr).** Im +> Repo-Root liegt ein mitgeliefertes `.dotnet/` mit exakt der in `global.json` +> gepinnten Version `8.0.318`. Der vollständige Lauf dauert rund 14 Sekunden: +> +> ``` +> "$PWD/.dotnet/dotnet" test tools/Nova.SimRunner.Tests/Nova.SimRunner.Tests.csproj -c Release +> ``` +> +> Das systemweite `dotnet` scheitert an `rollForward: disable` — nimm **immer** +> den Repo-lokalen Pfad. Du kannst und sollst also lokal prüfen, bevor du einen +> PR aufmachst. + +Was die CI trotzdem nicht leistet: `Nova.SimRunner.Tests` linkt nur Core, +Simulation, AI, AI.Data und Networking. **Für alles in `Gameplay/` und +`Presentation/` führt kein CI-Lauf den Code aus**, und die Unity-EditMode-Tests +laufen mangels Lizenz nicht. Das betrifft in diesem Auftrag den größten Teil von +21.2, 21.4, 21.5 und den ganzen Block 2. Die Quelltext-Wächter greifen dort +trotzdem: `PresentationSourceBoundaryTests` scannt auf `GetUnitRef(` und +`.Random`, ebenso der asmdef-Rangcheck. Ein *Verhaltens*nachweis ist dort die +gespielte Runde plus Screenshot. Schreib in den PR, was du gesehen hast — und +wenn du es nicht selbst sehen kannst, sag das, statt es zu behaupten. + +### Was du selbst entscheidest + +Alles Handwerkliche: Benennung, Aufteilung, Reihenfolge innerhalb eines Pakets, +Konstanten ohne Designwirkung, die konkrete Optik eines Overlays. Notier die +Entscheidung kurz im PR. + +### Was du nicht entscheidest + +- Einen neuen `CommandKind` einführen +- `StateVersion`, Schemaversionen oder das Zustandslayout ändern — auch nicht + „nur ein Feld" in `AetheriumField` +- Die Tickreihenfolge in `MatchRunner` ändern oder ein neues System registrieren +- Die Anzahl oder Lage der Aetheriumfelder ohne die Symmetrieprüfung aus D-107 +- `MinimumBuildingDistanceCells` oder `BuildInfluenceRadiusCells` ändern, bevor + die Messung aus 21.1 vorliegt +- Ein Paket streichen, das nicht auf der Abwurfliste steht +- Irgendetwas in fremdem Terrain, auch wenn es „nur eine Zeile" wäre + +In allen Fällen: anhalten, im PR oder in einer Nachricht beschreiben, warum es +nötig wäre, und auf die Entscheidung warten. + +## Was nicht in diesem Auftrag ist + +| | Warum | +|---|---| +| **#89 Patrouille, #90 Bewachen** | Brauchen einen Eintrag im eingefrorenen `CommandKind`-Register, eine neue Payload und Zustand pro Einheit im Snapshot. API-/Schema-Vorgang mit @api-guardian, Versionsrelevanz eher `major` | +| **#85 KI erntet auf leerem Feld** | Bereits behoben, [PR #97](https://github.com/VibecodingGermany/HashKrieg/pull/97), Einheitenstrang | +| **KI-Verhalten an den neuen Feldern** | Expansion, Feldsicherung, Eskorten — Einheitenstrang 13B. Dieser Auftrag macht die Karte reicher, nicht die KI klüger | +| **Sprint 17 Paket A** (Zugangsprotokoll) | Offen aus dem vorigen Auftrag, eigener Block nach diesem | +| **Sprint 13.2, 13.4, 13.5** | 13.2 braucht Zugangsdaten, 13.4/13.5 brauchen zwei Menschen an zwei Rechnern. Kein Codeauftrag | +| **Sprint 15.1–15.4** | Eigener Sprint, nach diesem Auftrag | +| **Sprint 19 / Art** (#57, #58) | Art-Arbeit außerhalb des Repositories | +| **#42 Zittern im Pulk, #66/#67 Halte-Feuer und Strommangel in der Verteidigung** | `Simulation/Movement/` und `Simulation/Combat/` — Einheitenstrang | +| **#55 Reparaturzone, #56 Sanitäter** | Im Fragenkatalog, kein Bauauftrag | +| **Verteidigungstürme an den Chokepoints balancieren** | Erst wenn die Mitte steht und einmal gespielt wurde | + +## Änderungsverlauf + +| Version | Datum | Änderung | Autor | +|---|---|---|---| +| 1.0.0 | 2026-08-17 | Erstfassung: Sprint 21 und Sprint 18 gebündelt, gegen `main` @ `3e10c48` geprüft, Grenzen und stille Fallen benannt. Enthält die Berichtigung zur lokalen Testbarkeit gegenüber dem vorigen Auftrag | Orchestrator | diff --git a/docs/production/hashkrieg/README.md b/docs/production/hashkrieg/README.md index b3a340d..53169bd 100644 --- a/docs/production/hashkrieg/README.md +++ b/docs/production/hashkrieg/README.md @@ -1,6 +1,6 @@ # Übergang Project Nova → Hashkrieg — Planungsmappe -**Version:** 0.8.0 | **Status:** fortgeschriebene Planungsmappe – Sprint 16 technisch umgesetzt, manuelle Spielabnahme offen; Sprint 13.2–13.5 warten weiter auf Zugangsdaten und zwei Menschen an zwei Rechnern | **Verantwortungsbereich:** Project Owner / Orchestrator / Producer | **Sprint:** 16 +**Version:** 0.9.0 | **Status:** fortgeschriebene Planungsmappe – Sprint 16 technisch umgesetzt und Sprint 21 festgeplant, manuelle Spielabnahme beider offen; Sprint 13.2–13.5 warten weiter auf Zugangsdaten und zwei Menschen an zwei Rechnern | **Verantwortungsbereich:** Project Owner / Orchestrator / Producer | **Sprint:** 21 ## Zweck @@ -51,9 +51,12 @@ ausschließlich in [../MVPRecoveryPlan.md](../MVPRecoveryPlan.md) und | [15_Sprint_Netzstabilitaet.md](15_Sprint_Netzstabilitaet.md) | Sprint 15 (Maintainer); Reconnect, Desync-Erstbefund, adaptive Eingabeverzögerung, Dauerbetrieb des Relays | | [16-19_Betatest_Einordnung.md](16-19_Betatest_Einordnung.md) | **Einordnung des ersten Betatest-Berichts** in die Sprintfolge — Issues #43–#58, nach Schreibhoheit geschnitten, mit den offenen Inhaberentscheidungen | | [16_Sprint_Wirtschaft.md](16_Sprint_Wirtschaft.md) | Sprint 16 (Netzstrang, **technisch umgesetzt; manuelle Spielabnahme offen**); Strang C aus Sprint 12 und die **acht** Betatest-Befunde (#43, #44, #45, #46, #47, #48, #53, #54) — Knappheit, Lager, Radar, Low Power, Bauvoraussetzungen, Platzierung, Reparaturkosten und Entscheidungsfeedback | -| [17_Sprint_Zugangsprotokoll.md](17_Sprint_Zugangsprotokoll.md) | Sprint 17 (Maintainer); Zugriffsprotokoll, Sperrliste und Erstmeldung — Paket A läuft im Großauftrag als **Block 4 hinter der Lobby**, weil es die Lobby-Functions aus Sprint 14 voraussetzt; es liegt bis auf den `.partial`-Fix in `RelayServerCore.cs` ausserhalb des Repos | +| [17_Sprint_Zugangsprotokoll.md](17_Sprint_Zugangsprotokoll.md) | Sprint 17 (Maintainer); Zugriffsprotokoll, Sperrliste und Erstmeldung — Paket A war **Block 3** des vorigen Großauftrags und ist als einziger Block daraus **noch offen**; es setzt die Lobby-Functions aus Sprint 14 voraus und liegt bis auf den `.partial`-Fix in `RelayServerCore.cs` ausserhalb des Repos | | [18_Sprint_Befehl_und_Auswahl.md](18_Sprint_Befehl_und_Auswahl.md) | Sprint 18 (Netzstrang); Auswahl nach Rolle, sichtbares Angriffsziel mit Nachsetzen über zwei Intents, Formationsausrichtung — Eingabe und Darstellung, kein neuer `CommandKind` | -| [AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md) | **Der gebündelte Arbeitsauftrag an den ausführenden Agenten, Blöcke 0 bis 4** — Auswahlrahmen, Sprint 16, Sprint 18, Sprint 14, Sprint 17 Paket A. Er ist die verbindliche Reihenfolge; wo er von einer Sprintdatei abweicht, gilt er | +| [20_Vorschlag_Verknappungsfolgen.md](20_Vorschlag_Verknappungsfolgen.md) | Der Vorschlag zur Sprintbildung aus Testbericht T-01 (#85–#94), nach Schreibhoheit geschnitten — **historisch**, seit dem 2026-08-17 durch Sprint 21 festgeplant | +| [21_Sprint_Verknappungsfolgen.md](21_Sprint_Verknappungsfolgen.md) | **Sprint 21 (Maintainer-Strang, geplant); die Folgen der endlichen Felder** — Restbestand und Baubereich sichtbar machen, Auswahl ehrlich machen, Startmenge rechnen, Kartendichte, und die Mitte als Gebiet mit Chokepoints (#86–#88, #91–#94; D-108, D-109) | +| [AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md) | Der vorige Arbeitsauftrag, Blöcke 0 bis 3 — Auswahlrahmen, Sprint 16, Sprint 18, Sprint 17 Paket A. Codeseitig **abgeschlossen bis auf Block 3** (Sprint 17 Paket A) | +| [AUFTRAG_Verknappungsfolgen.md](AUFTRAG_Verknappungsfolgen.md) | **Der aktuelle gebündelte Arbeitsauftrag, Blöcke 1 bis 2** — Sprint 21 und danach Sprint 18. Er ist die verbindliche Reihenfolge; wo er von einer Sprintdatei abweicht, gilt er | | [Testberichte/](Testberichte/) | **Anonymisierte** Fassungen der eingegangenen Betatest-Berichte, je Build und Kennung — Ablauf: [../Nutzerfeedback_Ablauf.md](../Nutzerfeedback_Ablauf.md) | ## Das Wichtigste in fünf Sätzen @@ -67,9 +70,11 @@ ausschließlich in [../MVPRecoveryPlan.md](../MVPRecoveryPlan.md) und einzige echte Blockade zwischen „Sandkasten" und „Spiel" — galt bis zum 2026-08-06 und ist seitdem überholt. Was heute im Weg steht, steht in den Betatest-Befunden, nicht in der Systemregistrierung. -3. **Zwei Gebäude sind Attrappen.** Lager und Radar kosten Geld und Strom und - tun nichts. Das ist die zutreffende Fassung der Vermutung „pro Fraktion - fehlen zwei Gebäude". +3. ~~**Zwei Gebäude sind Attrappen.**~~ **Erledigt seit Sprint 16.** Lager und + Radar kosteten Geld und Strom und taten nichts — das war die zutreffende + Fassung der Vermutung „pro Fraktion fehlen zwei Gebäude". Seit den Paketen + 16.4 (#53, abgeleitete AE-Obergrenze) und 16.5 (#54, Radarabdeckung schaltet + die Minimap frei) wirken beide. 4. **Die halbe fertige Arbeit ist unerreichbar.** Alle 17 Legion-Definitionen und -Assets sind fertig, aber es gibt keine Fraktionswahl — der Mensch kann nur Allianz spielen. @@ -182,29 +187,37 @@ Masterplans grundlegend — sonst nichts. zum Server. 13.4 und 13.5 brauchen zwei Menschen an zwei Rechnern. Sie warten auf den Inhaber, nicht auf Arbeitskraft — und sie halten deshalb nichts auf, was daneben laufen kann. -3. **Als nächstes läuft der Großauftrag** - ([AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md)), fünf Blöcke am Stück: - - **Block 0 — Auswahlrahmen** (#49): eine Konstante in - `GroundMarkerVisuals.cs`, Wirkung sofort sichtbar. - - **Block 1 — [Sprint 16](16_Sprint_Wirtschaft.md): technisch umgesetzt.** - Die Wirtschaft trägt sich selbst; die manuelle Spielabnahme bleibt offen. +3. **Der vorige Großauftrag** ([AUFTRAG_Grossblock.md](AUFTRAG_Grossblock.md)) + ist codeseitig abgearbeitet: Block 0 (Auswahlrahmen, #49) und Block 1 + ([Sprint 16](16_Sprint_Wirtschaft.md), Pakete 16.1–16.10) liegen auf `main`, + Sprint 14 war bereits gebaut. **Offen bleibt allein sein Block 3** — + [Sprint 17](17_Sprint_Zugangsprotokoll.md) Paket A samt dem `.partial`-Leck + in `Assets/_Project/Scripts/Networking/RelayServerCore.cs`: `ResetMatch` + verwirft den Aufzeichnungsstrom und merkt sich den Pfad, löscht die Datei + aber nie. Paket B wartet weiterhin auf Sprint 15. +4. **Als nächstes läuft der Großauftrag Verknappungsfolgen** + ([AUFTRAG_Verknappungsfolgen.md](AUFTRAG_Verknappungsfolgen.md)), zwei Blöcke + am Stück: + - **Block 1 — [Sprint 21](21_Sprint_Verknappungsfolgen.md):** die Folgen der + endlichen Felder aus Testbericht T-01. Restbestand und Baubereich sichtbar, + Auswahl ehrlich, Startmenge gerechnet, mehr Felder auf der Karte, und die + Mitte wird ein Gebiet mit Chokepoints (D-108, D-109). - **Block 2 — [Sprint 18](18_Sprint_Befehl_und_Auswahl.md):** Befehl und - Auswahl werden lesbar. - - **Block 3 — [Sprint 14](14_Sprint_Lobby.md):** Match per Code über - Supabase, Fraktionswahl, Build-Abgleich. - - **Block 4 — [Sprint 17](17_Sprint_Zugangsprotokoll.md) Paket A:** liegt bis - Es läuft als **Block 3 des Großauftrags**, weil es die Lobby-Functions - aus Sprint 14 voraussetzt — die seit `b4e75e5` auf `main` liegen. - `.partial`-Leck in `Assets/_Project/Scripts/Networking/RelayServerCore.cs`. - `ResetMatch` verwirft den Aufzeichnungsstrom und merkt sich den Pfad, - löscht die Datei aber nie. Paket B wartet weiterhin auf Sprint 15. -4. **Die `SimDefinitions`-Pakete wurden vor dem VPS-Rollout integriert.** + Auswahl werden lesbar. Direkt hinter Sprint 21, weil beide dieselben zwei + Dateien anfassen — Befehlskarte und Auswahl. +5. **Der Einheitenstrang läuft parallel und ist eingeholt.** Die KI erntet seit + [#97](https://github.com/VibecodingGermany/HashKrieg/pull/97) nicht mehr + endlos auf dem leeren Feld (#85 geschlossen), und + [#96](https://github.com/VibecodingGermany/HashKrieg/pull/96) hat den + Goal-Katalog samt `DefendHome` gebracht (`r8`). Beides ist gemergt, aber + **nicht gespielt abgenommen**. +6. **Die `SimDefinitions`-Pakete wurden vor dem VPS-Rollout integriert.** Sprint 16.7 (Feldwerte und Feldanzahl) und 16.8 (Bauvoraussetzungs-Bitmaske) sind abgeschlossen. Der Relay vergleicht den Definitions-Hash **serverseitig**; spätere Zahlenänderungen kosten deshalb Serverzugang und Redeploy ([13-15_Parallelbetrieb.md](13-15_Parallelbetrieb.md), §Definitions-Hash). -5. **Sprint 19 bleibt danach und ist kein Codeauftrag.** Die beiden Art-Befunde +7. **Sprint 19 bleibt danach und ist kein Codeauftrag.** Die beiden Art-Befunde #57 (Gebäude durchsichtig und hohl) und #58 (Maßstab des Radarturms) sind Arbeit am Asset; #58 hängt zusätzlich an der offenen Frage #19. Sprint 16 Paket 16.2 macht #57 sichtbarer, behebt es aber ausdrücklich nicht. @@ -219,4 +232,5 @@ Masterplans grundlegend — sonst nichts. | 0.7.0 | 2026-08-09 | Nach der Inhaberentscheidung zum ersten Betatest: **Sprint 16 vorgezogen**, [16_Sprint_Wirtschaft.md](16_Sprint_Wirtschaft.md) und [18_Sprint_Befehl_und_Auswahl.md](18_Sprint_Befehl_und_Auswahl.md) in die Mappe aufgenommen, Regelwerk als Parallelbetrieb 13–18 mit Trennung über Dateihoheit (**D-095**) fortgeschrieben, Großauftrag mit den Blöcken 0 bis 4 eingehängt. „Nächste Schritte" neu geschrieben: Sprint 13 halb gemergt (`e15f5e6`), 13.2–13.5 nicht durch einen Agenten erledigbar, `SimDefinitions`-Pakete vor dem VPS-Rollout. Punkt 2 der Fünf-Sätze-Zusammenfassung nach **D-077** berichtigt — die Skirmish-KI ist registriert und spielt | Orchestrator | | 0.7.1 | 2026-08-09 | Index gegen den Großauftrag und die Sprintdateien nachgezogen: Sprint 17 Paket A ist nicht „sofort vorziehbar", sondern läuft als **Block 3 hinter der Lobby**, die seit `b4e75e5` auf `main` gebaut ist, und es berührt mit dem `.partial`-Fix in `RelayServerCore.cs` genau **eine** Datei unter `Assets/`. Sprint 16 trägt **acht** Betatest-Befunde (#43, #44, #45, #46, #47, #48, #53, #54), nicht sechs. Alle Markdown-Links dieser Datei gegen das Dateisystem geprüft — kein toter Link | Orchestrator | | 0.7.2 | 2026-08-10 | D-105 nachgezogen: alleinige Projektleitung, sichtbare Spielabnahme-Zurückstellung und den historischen Charakter des D-091-Zwei-Maintainer-Rollouts im Index kenntlich gemacht | Project Owner / Orchestrator | +| 0.9.0 | 2026-08-17 | Sprint 21 aus dem Vorschlag zu den Verknappungsfolgen festgeplant und der [Großauftrag Verknappungsfolgen](AUFTRAG_Verknappungsfolgen.md) (Sprint 21 → Sprint 18) eingehängt; **D-108** (Territorium wächst kriechend an jedem Bauanker) und **D-109** (die Mitte wird ein Gebiet mit Chokepoints, Begehbarkeit und Optik aus einer Quelle) getroffen. „Nächste Schritte" neu geschrieben: der vorige Großauftrag ist codeseitig bis auf Sprint 17 Paket A abgearbeitet, der Einheitenstrang ist mit #96 und #97 eingeholt. #85 geschlossen | Project Owner / Orchestrator | | 0.8.0 | 2026-08-10 | Sprint 16 als technisch umgesetzt markiert, Paket 16.10 und die vor dem VPS-Rollout integrierten Definitionsänderungen nachgezogen; manuelle Spielabnahme bleibt ausdrücklich offen | Codex / Dennis Westermann |