fix(construction): sites carry the definition role, not Unit (#44, Sprint 16.3) - #71
Conversation
|
Maintainer-Befund zu den vier roten Tests. Es sind zwei verschiedene Ursachen, und keine davon ist eine verschobene Baseline. Das ist wichtig, weil #70 die Baselines als Erklärung nennt („Golden-Byte-Baselines bewegen sich … die Baseline-Neusetzung kommt als eigener PR"). Würden diese vier Tests über eine Baseline-Neusetzung grün gemacht, friert das eine echte Regression ein — genau das, was die Regel „Verhalten und Baseline nie im selben Zug" verhindern soll. Ursache A — der eigene neue Test ist falsch (behebbar im Netzstrang)
f.SpawnBuilder(0, 19, 20); // nur ein Bauarbeiter
f.Step(1); // kein HQ, kein Kraftwerk
Assert.That(f.Construction.TryPlaceBuilding(0, 4, 20, 20), Is.True); // ← Expected True, But was FalseDefinition 4 ist die Raffinerie mit if (def.PowerRequired > 0 && eco.PowerProvided - eco.PowerRequired < def.PowerRequired)
Behebung: ein HQ in die Fixture (das liefert 30), dann greift die Energieprüfung nicht mehr. Die Implementierung ist an dieser Stelle in Ordnung — der Test prüft nur etwas, das er sich selbst unmöglich gemacht hat. Ursache B — eine Regression in der KI (nicht im Netzstrang behebbar)Die anderen drei Fehler (
if (SimDefinitions.IsBuildingRole(u.Role)) { // Zeile 228
case UnitRole.Refinery when refineryRaw == 0: ...
case UnitRole.Barracks when barracksRaw == 0: ...
case UnitRole.Power: powerCompleted = true;
continue; // ← und hier ist Schluss
}
switch (u.Role) {
case UnitRole.Unit: // Zeile 266
if (_construction.TryGetSite(raw, ...)) // ← SO fand die KI ihre Baustellen
sites.Add(...); // Zeile 271Vor 16.3 trug eine Baustelle
Daher fehlt Die Behebung ist klein, liegt aber in fremdem Terrain. Im Zensus muss zuerst das Baustellen-Register gefragt werden, dann die Rolle. Was daraus folgtDieser PR kann erst gemergt werden, wenn der KI-Zensus nachgezogen ist. Das ist ein dritter Punkt für die Ansage in #70 — und der einzige, der 16.3 blockiert, während der DefensePlatform-Restbefund dort auch später behandelt werden kann. Reihenfolge: Zensus in 13B nachziehen → dann #71 → dann, falls dann noch nötig, die Baseline-Neusetzung als eigener PR. Nicht umgekehrt. |
|
Korrektur zur Baseline-Erwartung im PR-Text: Die vier roten Tests sind keine Golden-Byte-Verschiebungen, sondern eine KI-Regression aus der Rollenänderung (Diagnose vom Inhaber, am Code bestätigt):
Damit steht dieser PR: Sim- und View-Teile wie beschrieben, KI-Regression bekannt und bei 13B eingeordnet. Baseline-Neusetzung bleibt zusätzlich nötig (Baustellen serialisieren die Definitionsrolle), aber sie ist nicht die Ursache der roten Tests. |
Sprint 16.3: SpawnBuildingEntity assigns def.Role to unfinished sites. The generic UnitRole.Unit slot is armed by the weapon-table fallback (15 damage) and D-087 auto-acquisition fires it — every site shot. Unarmed building roles carry AttackDamage 0, so the fallback dies without a line in Combat/. The three readers that resolved a site by its generic role are compensated at the source: - EconomySystem.RecomputePower skips sites through a bound IsActiveSite lookup (Func<EntityId,bool>, wired once by the ConstructionSystem constructor so no host can forget it; null-tolerant for construction-free rigs). A site neither provides nor draws power — otherwise a Power site would power up its own grid mid-build. - UnitViewManager maps sites back to the effective view role UnitRole.Unit: the site keeps its low pad and no art prefab until completion, and the rebind trigger now follows the site-register flip (the role no longer changes at completion). - VictorySystem excludes sites from the HQ scan: a half-built HQ would otherwise mask the D-077 last-HQ elimination. Building classification itself is untouched (sites counted as buildings before, via the site table). SelectionManager.CopyMobileSelection now drops sites from mobile command dispatch (they read as buildings) — intended: sites take no move orders; selection itself is unchanged (player-id only), and the command card resolves sites before the role check. Known remainder, announced to the units track before this PR: a DefensePlatform SITE stays armed (20 damage from the building definition). A site filter in auto-acquisition lives in Simulation/Combat/ and belongs to the units track. Expected: golden-byte baselines move (site entities serialize the definition role now). Baseline reset lands in a SEPARATE PR per the standing rule and needs an SDK-8 environment.
ff6f307 to
5c90d72
Compare
Sprint 16.4, D-024/D-096. The account gains an upper bound DERIVED from
the living building stock on every read - never stored (a stored cap
would be a state field and a format break): a completed HQ provides the
2.000 AE base per HQ, every completed Storage adds 2.000, sites hold
nothing (via the bound site lookup).
- DepositCapped(playerId, amount) is now the only income path: harvest
deposits, production cancel, construction cancel and sell refunds all
clamp at the ceiling - overflow is forfeit ("Ueberschuss verfaellt").
- An existing balance above the ceiling decays by 25% of the excess
once per second (tick % 10, integer floor, minimum 1 AE). The decay
IS the D-024 "25% loss on destruction" carried without an event: a
destroyed or sold storage drops the ceiling and the decay is the
loss. Stateless and restore-safe by construction.
- The destruction-rule wording is an owner decision (decay over a
slot-bound one-time loss): the slot of a destroyed storage is not
reconstructible inside the hard bounds (despawned entity, ownerless
PlacementState, KillUnit in the units track).
This branch also replicates the 16.3 site-lookup mechanism
(BindSiteLookup / IsActiveSite) VERBATIM from PR #71: the capacity scan
must exclude sites once sites carry their definition role. Identical
hunks at identical locations - whichever PR merges first, the other
merges clean.
Expected: golden-byte baselines move (the Determinism10000 opening
starts 1.000 AE over the HQ ceiling and decays; deposits clamp).
Baseline reset lands in a SEPARATE PR per the standing rule and needs
an SDK-8 environment.
…nt 16.4) (#73) * feat(economy): derived storage ceiling caps the AE account (#53) Sprint 16.4, D-024/D-096. The account gains an upper bound DERIVED from the living building stock on every read - never stored (a stored cap would be a state field and a format break): a completed HQ provides the 2.000 AE base per HQ, every completed Storage adds 2.000, sites hold nothing (via the bound site lookup). - DepositCapped(playerId, amount) is now the only income path: harvest deposits, production cancel, construction cancel and sell refunds all clamp at the ceiling - overflow is forfeit ("Ueberschuss verfaellt"). - An existing balance above the ceiling decays by 25% of the excess once per second (tick % 10, integer floor, minimum 1 AE). The decay IS the D-024 "25% loss on destruction" carried without an event: a destroyed or sold storage drops the ceiling and the decay is the loss. Stateless and restore-safe by construction. - The destruction-rule wording is an owner decision (decay over a slot-bound one-time loss): the slot of a destroyed storage is not reconstructible inside the hard bounds (despawned entity, ownerless PlacementState, KillUnit in the units track). This branch also replicates the 16.3 site-lookup mechanism (BindSiteLookup / IsActiveSite) VERBATIM from PR #71: the capacity scan must exclude sites once sites carry their definition role. Identical hunks at identical locations - whichever PR merges first, the other merges clean. Expected: golden-byte baselines move (the Determinism10000 opening starts 1.000 AE over the HQ ceiling and decays; deposits clamp). Baseline reset lands in a SEPARATE PR per the standing rule and needs an SDK-8 environment. * test(economy): cover capped deposits through real call paths
Was
Sprint 16.3 / Issue #44 stellt Baustellen auf ihre Definitionsrolle um. Eine
unfertige Baustelle trägt damit z. B. bereits
Refinery,HQoderDefensePlatform; fertig ist sie weiterhin erst, wenn das Baustellenregisterkeinen aktiven Site-Eintrag mehr enthält.
Die Rollenänderung ist an allen betroffenen Lesern geschlossen:
ConstructionSystembindet den Site-Lookup in die Wirtschaft und normalisiertbeim Abschluss weiterhin die Rolle (kompatibel zu älteren Mid-Build-Snapshots).
EconomySystemzählt Sites weder in der Strombilanz noch alsRaffinerie-Abladepunkt.
CombatSystemerhältConstructionSystemals Pflichtabhängigkeit und schließtaktive Sites als Angreifer und Ziel aus. Auch eine unfertige
Verteidigungsplattform feuert nicht.
SkirmishAiSystemwertet Sites vor Gebäuderollen aus und ignoriert sie beiZielwahl und Bedrohungsanalyse; das kanonische 10.000-Tick-Szenario wählt nur
fertige Produzenten.
Produzentenwahl, Rally- und Reparaturvorprüfung nutzen das Site-/Placement-
Register statt einer Rollenannahme.
D-105-Integrationshinweis
Die beim Main-Merge sichtbar gewordenen AI-/Combat-/UI-Folgen sind eine
gebundene Integrationsreparatur nach D-105: minimaler Diff, im Sprintvertrag
Version 1.1.0 dokumentiert, unabhängiger Read-only-Review durchgeführt. Die
dauerhafte Stranghoheit ändert sich dadurch nicht.
Nachweis
dotnet test tools/Nova.SimRunner.Tests/Nova.SimRunner.Tests.csproj -c Release— 663/663 grün
6000.5.4f1, vollständige EditMode-Suite — 547/547 grünpython3 .github/scripts/check_docs.py— 181 Markdown-Dateien und 5Quality-JSONs grün
git diff --check— grünAiBehaviorIdbleibtr6Manuelle Spielsicht
Nicht gespielt / nach D-105 ausdrücklich zurückgestellt. Grund: Der Kollege
steht für die Runde derzeit nicht zur Verfügung. Ersatznachweis sind die
vollständigen .NET- und Unity-Suiten einschließlich gespiegelter Bau-, Kampf-,
Wirtschafts- und Siegtests. Restrisiko: Baustellenoptik, Marker/Builder-Warnung
und das sichtbare Ausbleiben des Schusses wurden nicht in einer laufenden Runde
beobachtet. Dieser PR ist damit integrierbar, aber nicht spielerisch
abgenommen und kein Meilenstein-Nachweis.
Changelog
Ein Eintrag unter
[Unreleased]: „#44: Baustellen schiessen nicht mehr“.