Commit Graph

128 Commits

Author SHA1 Message Date
gamer147
b54e79f1fb cull(engine-cleanup): pass-9 cascade round 3 after DialogBase stub 2026-07-03 23:25:54 -04:00
gamer147
6eb7d51d53 cull(engine-cleanup): pass-9 cascade round 2 after DialogBase stub 2026-07-03 23:24:59 -04:00
gamer147
4e3bb6f88f cull(engine-cleanup): pass-9 cascade round 1 after DialogBase stub 2026-07-03 23:23:59 -04:00
gamer147
6de5f03956 cull(engine-cleanup): pass-9 — stub DialogBase to live surface 2026-07-03 23:22:43 -04:00
gamer147
840ac27027 chore(engine-cleanup): pass-8 phase-2 — sync stub headers with post-cascade state 2026-07-03 22:38:17 -04:00
gamer147
0ee97cdd93 cull(engine-cleanup): pass-8 phase-2 cascade round 5 after CardDetailUI stub 2026-07-03 22:37:13 -04:00
gamer147
4950a57b11 cull(engine-cleanup): pass-8 phase-2 cascade round 4 after CardDetailUI stub 2026-07-03 22:36:16 -04:00
gamer147
0bf981ce4d cull(engine-cleanup): pass-8 phase-2 cascade round 3 after CardDetailUI stub 2026-07-03 22:35:21 -04:00
gamer147
99120ec858 cull(engine-cleanup): pass-8 phase-2 cascade round 2 after CardDetailUI stub 2026-07-03 22:34:23 -04:00
gamer147
3d641e9e35 cull(engine-cleanup): pass-8 phase-2 cascade round 1 after CardDetailUI stub 2026-07-03 22:33:26 -04:00
gamer147
8e6dbad56b cull(engine-cleanup): pass-8 phase-2 — stub CardDetailUI to live surface 2026-07-03 22:32:22 -04:00
gamer147
f26e8ceaec cull(engine-cleanup): pass-8 phase-2 cascade round 4 after GachaUI stub 2026-07-03 22:28:42 -04:00
gamer147
4e49a1236d cull(engine-cleanup): pass-8 phase-2 cascade round 3 after GachaUI stub 2026-07-03 22:27:45 -04:00
gamer147
78971adc46 cull(engine-cleanup): pass-8 phase-2 cascade round 2 after GachaUI stub 2026-07-03 22:26:45 -04:00
gamer147
e3b8b8dc0c cull(engine-cleanup): pass-8 phase-2 cascade round 1 after GachaUI stub 2026-07-03 22:25:44 -04:00
gamer147
a0533bf2e3 cull(engine-cleanup): pass-8 phase-2 — stub GachaUI to live surface 2026-07-03 22:24:38 -04:00
gamer147
59de7a8b86 cull(engine-cleanup): pass-8 phase-2 cascade round 5 after AreaSelectUI stub 2026-07-03 22:22:31 -04:00
gamer147
80abda90bf cull(engine-cleanup): pass-8 phase-2 cascade round 4 after AreaSelectUI stub 2026-07-03 22:21:26 -04:00
gamer147
9d4d5ff1ec cull(engine-cleanup): pass-8 phase-2 cascade round 3 after AreaSelectUI stub 2026-07-03 22:20:18 -04:00
gamer147
b148eb2968 cull(engine-cleanup): pass-8 phase-2 cascade round 2 after AreaSelectUI stub 2026-07-03 22:19:20 -04:00
gamer147
ad525456be cull(engine-cleanup): pass-8 phase-2 cascade round 1 after AreaSelectUI stub 2026-07-03 22:18:12 -04:00
gamer147
7aabb6a405 cull(engine-cleanup): pass-8 phase-2 — stub AreaSelectUI to live surface 2026-07-03 22:17:04 -04:00
gamer147
41ddba8fda cull(engine-cleanup): pass-8 phase-2 cascade round 7 after MyPageItemHome stub 2026-07-03 22:05:22 -04:00
gamer147
7938c6198c cull(engine-cleanup): pass-8 phase-2 cascade round 6 after MyPageItemHome stub 2026-07-03 22:04:24 -04:00
gamer147
4aa0ccaea7 cull(engine-cleanup): pass-8 phase-2 cascade round 5 after MyPageItemHome stub 2026-07-03 22:03:27 -04:00
gamer147
e07cacc55e cull(engine-cleanup): pass-8 phase-2 cascade round 4 after MyPageItemHome stub 2026-07-03 22:02:30 -04:00
gamer147
17b436d33d cull(engine-cleanup): pass-8 phase-2 cascade round 3 after MyPageItemHome stub 2026-07-03 22:01:31 -04:00
gamer147
e9b112d083 cull(engine-cleanup): pass-8 phase-2 cascade round 2 after MyPageItemHome stub 2026-07-03 22:00:30 -04:00
gamer147
6cf95bcfd6 cull(engine-cleanup): pass-8 phase-2 cascade round 1 after MyPageItemHome stub 2026-07-03 21:59:29 -04:00
gamer147
d89e7d9634 cull(engine-cleanup): pass-8 phase-2 — stub MyPageItemHome to live surface 2026-07-03 21:58:31 -04:00
gamer147
57312b64be cull(engine-cleanup): pass-8 phase-2 cascade round 7 after MyPageItemBattle stub 2026-07-03 21:56:59 -04:00
gamer147
200b865728 cull(engine-cleanup): pass-8 phase-2 cascade round 6 after MyPageItemBattle stub 2026-07-03 21:55:58 -04:00
gamer147
b404ff40c0 cull(engine-cleanup): pass-8 phase-2 cascade round 5 after MyPageItemBattle stub 2026-07-03 21:54:57 -04:00
gamer147
8e7fc8b15a cull(engine-cleanup): pass-8 phase-2 cascade round 4 after MyPageItemBattle stub 2026-07-03 21:54:00 -04:00
gamer147
d1f56e6dda cull(engine-cleanup): pass-8 phase-2 cascade round 3 after MyPageItemBattle stub 2026-07-03 21:53:04 -04:00
gamer147
22ef593593 cull(engine-cleanup): pass-8 phase-2 cascade round 2 after MyPageItemBattle stub 2026-07-03 21:52:04 -04:00
gamer147
006a6ae7ab cull(engine-cleanup): pass-8 phase-2 cascade round 1 after MyPageItemBattle stub 2026-07-03 21:51:02 -04:00
gamer147
57dee92570 cull(engine-cleanup): pass-8 phase-2 — stub MyPageItemBattle to live surface 2026-07-03 21:49:55 -04:00
gamer147
3a652479f6 cull(engine-cleanup): pass-8 phase-2 cascade round 6
[trim] fully-unreachable files deleted: 1
[trim] files edited: 1, files deleted: 0, nodes removed: 1
[type-trim] files edited: 0, types removed: 0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:23:50 -04:00
gamer147
7d1ea2b38d cull(engine-cleanup): pass-8 phase-2 cascade round 5
[trim] fully-unreachable files deleted: 1
[trim] files edited: 4, files deleted: 0, nodes removed: 6
[type-trim] files edited: 0, types removed: 0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:22:48 -04:00
gamer147
8b07f6a0b2 cull(engine-cleanup): pass-8 phase-2 cascade round 4
[trim] fully-unreachable files deleted: 0
[trim] files edited: 5, files deleted: 0, nodes removed: 12
[type-trim] files edited: 0, types removed: 0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:21:46 -04:00
gamer147
c88b8df409 cull(engine-cleanup): pass-8 phase-2 cascade round 3
[trim] fully-unreachable files deleted: 3
[trim] files edited: 6, files deleted: 0, nodes removed: 23
[type-trim] files edited: 0, types removed: 0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:20:40 -04:00
gamer147
e3e0ba7a72 cull(engine-cleanup): pass-8 phase-2 cascade round 2
[trim] fully-unreachable files deleted: 3
[trim] files edited: 21, files deleted: 0, nodes removed: 38
[type-trim] files edited: 3, types removed: 3

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:19:36 -04:00
gamer147
c9628dee01 cull(engine-cleanup): pass-8 phase-2 cascade round 1
[trim] fully-unreachable files deleted: 6
[trim] files edited: 55, files deleted: 0, nodes removed: 244
[type-trim] files edited: 1, types removed: 1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 21:18:18 -04:00
gamer147
2d9a6eea4b engine cleanup passes 4-7 + multi-instancing ambient rip
Squashes 146 commits from battle-engine-extraction. Net: 2,045 files changed,
+11,896 / -158,687 lines. Ships engine passes 4-7 (dead-code cull, view-layer
stub, receive-path shrink) plus the Phase-5 AsyncLocal ambient deletion that
turns concurrent battles into a type-system property rather than a scope
contract.

## What landed

**Passes 4-7 (chunks 1-34):** Extended the Phase-4 const-false collapse into a
cascading cull across the skill graph, view layer, and receive-path periphery.
Six mode flags (IsWatchBattle/IsReplayBattle/IsAdmin/IsAdminWatch/IsPuzzleQuest/
IsAINetwork) became `const false`, every guarded block deleted. Field*.cs
subclass ctors + BackGroundBase + ObjectChecker culled to no-ops. Mulligan
family reworked to take a mgr param through IMulliganMgr.InitMulligan.
Emotion/Recovery/Resource clusters null-stubbed. Prediction/OperationSimulator/
skill filters converted from static ambient reads to per-mgr reads via
SkillPrm.ownerCard.SelfBattlePlayer.BattleMgr / ins.BattleMgr / this.BattleMgr.

**Phase-5 ambient rip (chunks 35-47):** Deleted BattleAmbient / BattleAmbient-
Context / TestBattleScope in full. Every per-battle mutable slot now lives on
the mgr instance itself:
  mgr.InstanceIsForecast / InstanceIsRandomDraw / InstanceRecoveryInfo /
  InstanceViewerId / InstanceNetworkAgent / GameMgr
BattleManagerBase.GetIns() returns null unconditionally; the residual static
flags + 3 façades (Certification.ViewerId, Data.BattleRecoveryInfo,
ToolboxGame.RealTimeNetworkAgent) are null-tolerant defaults kept for the
handful of engine-internal readers that still reference their types. Zero
BattleAmbient references anywhere in engine + node + tests.

Added pre-seeded GameMgr ctor overload threaded through the mgr chain
(BattleManagerBase → SingleBattleMgr / NetworkBattleManagerBase → NetworkStandard-
BattleMgr → HeadlessBattleMgr / HeadlessNetworkBattleMgr). Fixtures build a
GameMgr, seed it via HeadlessEngineEnv.SeedCharaIds/SeedNetUser, and pass it
to the mgr's ctor — no ambient reach.

Node side (SVSim.BattleNode/SessionBattleEngine): _ctx replaced with a plain
GameMgr field; 34 `using var _ambient = BattleAmbient.Enter(_ctx)` scope wraps
ripped from every accessor and mutator; EngineGlobalInit.WirePerSessionGameMgr
takes GameMgr as a param and runs from SessionBattleEngine.SetupInternal
BEFORE mgr construction.

Test side: TestBattleScope deleted; 18 fixture [SetUp]s migrated to
`HeadlessEngineEnv.EnsureProcessGlobals()`; MultiInstanceEngineTests rewritten
around per-mgr construction (GetIns() → null is the pinned invariant).

## Regression fixes

- **chunk-48** (MulliganCtrl): chunk-35's `= null` stubs on card lookups broke
  the live receive-driven Deal path (BattlePlayerBase.DrawCard NRE'd downstream
  of NetworkPlayerMulliganCtrl.StartMulliganVfx). Restored the three lookups
  via `_battlePlayer.BattleMgr.GetBattleCardIdx`. Engine tests were satisfied
  by the WireMulliganPhase seam; unit tests exposed the live-path gap.

## Ship state

- SVSim.BattleEngine.Tests: 56/56 pass, 2 skip
- SVSim.UnitTests: 1554/1554 pass (was 1523/31-fail before chunk 48)
- Solution build: 0 source warnings (40 pre-existing NU1902 MessagePack CVEs
  in SVSim.EmulatedEntrypoint, unrelated)
- Sequential PVP smoke: verified live (two back-to-back battles, no regression
  on cleanup/spinup)
- Concurrent PVP smoke: verified live

Adds tools/engine-port/ClosureAnalyzer/ — the Roslyn transitive-type-closure
analyzer needed to make future cascade cleanup safe (per feedback memory
"Engine cleanup needs closure tool" from the 2026-06-28 pass-3 failure).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 19:18:54 -04:00
gamer147
5a23f93152 docs(engine-ambient): explain why _components GetOrAdd factory is contention-safe
Reviewer noted the factory may be invoked more than once under contention.
Document the analysis inline so a future reader doesn't have to redo it:
the discarded instance's mutations land on private fields of a soon-unreachable
object, and the only shared sentinel (_noopViewMaterial) is read-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-08 08:25:34 -04:00
gamer147
fbac66fd0b chore(engine-ambient): harden shim + LocalLog statics for fixture parallelism
Follow-up to the multi-instancing migration. Wraps the process-shared engine
statics that aren't ambient-fronted but race between concurrent battles:

- UnityEngine.Resources._loaded: Dictionary -> ConcurrentDictionary.GetOrAdd
  (the shared prefab cache keyed by path; concurrent first-misses produced
  duplicate GameObjects + Dictionary corruption)
- UnityEngine.GameObject._components: Dictionary -> ConcurrentDictionary with
  Interlocked.CompareExchange init (Resources.Load returns SHARED prefab
  GameObjects, so two engines' Setup() can race on the same _components map
  — surfaced as "Operations that change non-concurrent collections" crashes
  during BattleManagerBase ctor's GetComponent<T>() chain)
- Wizard.LocalLog: single static lock around all mutating entry points
  (StringBuilder _lastTraceLogStringBuilder + ~12 mutable string/bool/int
  scratch fields; serializing the trace-log surface is cheap since logging
  is not the hot path)

Flips SVSim.BattleEngine.Tests assembly Parallelizable scope from Self to
Fixtures and restructures MultiInstanceEngineTests.StressN_BaselineMatches so
Setup runs INSIDE Task.Run (was previously serialized as a workaround for the
LocalLog races). The fixture is also lifted to ParallelScope.All so the
two-engines and stress tests can run alongside each other.

Suite fully green under fixture parallelism (59/0/2 across 3 consecutive runs);
SVSim.UnitTests still 1054/0/0 — true multi-instance correctness is now proved
end-to-end in tests rather than gated behind a serial workaround.

Manifest sha refresh + new patch artifact for the LocalLog edit (decomp-origin);
the two shim files are authored, so no metadata update is needed for them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-08 08:02:49 -04:00
gamer147
c789d836f1 feat(engine-ambient): delete static fallbacks; add MultiInstanceEngineTests
Step 8 (final) of multi-instancing migration. All per-battle statics now
require a BattleAmbient scope — unwrapped writes throw InvalidOperationException
(fail-fast forcing function). MultiInstanceEngineTests proves correctness:
two parallel battles resolve independently, N=4/8/16 stress matches sequential
baseline, GameMgr.GetIns throws without scope.

Migration complete. EngineSessionGate gone. Suite fully green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-07 23:19:37 -04:00
gamer147
1ba75c565a refactor(engine-ambient): GameMgr.GetIns throws Require; wrap SessionBattleEngine entry points
Step 5 of multi-instancing migration. GameMgr.GetIns() now resolves through
BattleAmbient.Require() (throws when no scope active — fail-fast since engine
callers unconditionally dereference). SessionBattleEngine now owns a single
BattleAmbientContext, pushed via BattleAmbient.Enter at Setup/Receive/all
~30 read accessors and Debug* seams.

EngineGlobalInit.WirePerSessionGameMgr extracted out of the _done-gated block:
GameMgr is now per-session (ctx.GameMgr is a fresh `new()` per SessionBattleEngine),
so the DataMgr chara ids + NetworkUserInfoData seeding must run every Setup, not
process-once. The wiring itself is already idempotent. Without this, second-or-
later sessions in a process NRE in NetworkBattleManagerBase.CreateBackgroundId.

Expected state: SVSim.BattleEngine.Tests have known-failing tests that don't
go through SessionBattleEngine (Task 6 wraps HeadlessFixture). SVSim.UnitTests
mostly recover; residual failures (deal-frame Accepted:false in conductor
integration tests) are captured in
data_dumps/task5-test-output/failing-tests-after-task5-node-postwrap.txt for
Task 7.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-07 21:56:34 -04:00
gamer147
fe146fde50 refactor(engine-ambient): ViewerId/RealTimeNetworkAgent/BattleRecoveryInfo read ambient first
Step 4 of multi-instancing migration. Three additional per-battle statics
front-fronted by BattleAmbient.Current, each with a static fallback for
unwrapped callers. ViewerId's SavedataManager-persisting setter is preserved
on the fallback path; inside a scope, the setter is a no-op (the per-battle
perspective is fixed at scope entry).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-07 21:37:58 -04:00