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>
This commit is contained in:
@@ -173,10 +173,16 @@ internal sealed class SessionBattleEngine
|
||||
SeedDeck(mgr, seatADeck, isPlayer: true);
|
||||
SeedDeck(mgr, seatBDeck, isPlayer: false);
|
||||
|
||||
WireMulliganPhase(mgr); // wire OperateReceive.OnReceiveDeal -> StartDeal (deal seats the hand)
|
||||
|
||||
// Publish the mgr on the per-session ambient BEFORE wiring the mulligan phase: that ctor
|
||||
// chains into MulliganInfoControl.InitMulliganInfo, which reads BattleManagerBase.GetIns()
|
||||
// (MulliganInfoControl.cs:259). With the fallback gone (Task 8), an unset ambient.Mgr would
|
||||
// resolve to null and NRE on the very next field read. Set ambient.Mgr here so the wiring
|
||||
// resolves the per-session mgr cleanly.
|
||||
_mgr = mgr;
|
||||
_ctx.Mgr = _mgr;
|
||||
|
||||
WireMulliganPhase(mgr); // wire OperateReceive.OnReceiveDeal -> StartDeal (deal seats the hand)
|
||||
|
||||
// Use the mgr's OWN receiver — the ctor already wired it to the mgr's OperateReceive +
|
||||
// NetworkBattleData (NetworkBattleManagerBase.cs:266, non-recovery branch). This is the same
|
||||
// receiver the engine's RecoveryDataHandler drives when replaying recorded frames.
|
||||
|
||||
Reference in New Issue
Block a user