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:
@@ -0,0 +1,43 @@
|
||||
Multi-instancing migration (Step 8 — forcing function): delete the static BattleRecoveryInfo
|
||||
fallback the earlier .ambient-recoveryinfo patch added as a coexistence shim. BattleRecoveryInfo
|
||||
is now strictly per-session ambient. Supersedes the intermediate .ambient-recoveryinfo patch
|
||||
(kept for the audit trail).
|
||||
|
||||
Semantics:
|
||||
- BattleRecoveryInfo (getter) : Current?.RecoveryInfo — soft (null when no scope). The
|
||||
MulliganMgrBase.StartDeal call site reads this with a null-tolerant pattern, so a null
|
||||
degrade is the historical fallback. Inside a scope, returns the per-session RecoveryInfo
|
||||
(SessionBattleEngine pre-seeds an uninitialized BattleRecoveryInfo on its ctx field
|
||||
initializer).
|
||||
- BattleRecoveryInfo (setter) : BattleAmbient.Require().RecoveryInfo = value — strict
|
||||
(writes must land on the per-session ctx; forcing function).
|
||||
|
||||
Related (SVSim.BattleNode/Sessions/Engine/EngineGlobalInit.cs): the dead `Data.BattleRecoveryInfo
|
||||
= ...` write inside the `_done` lock block is also deleted (flagged by Task 7 reviewer). The
|
||||
per-session ctx pre-seeds RecoveryInfo, so the process-global write was dead the moment the
|
||||
ambient seam landed.
|
||||
|
||||
In-file edits:
|
||||
- line ~179 declaration `private static BattleRecoveryInfo _battleRecoveryInfoFallback;` DELETED
|
||||
- lines ~180-189 the ambient+fallback get/set body REPLACED with strict semantics
|
||||
|
||||
--- Engine/Wizard/Data.cs (~lines 179-189)
|
||||
- private static BattleRecoveryInfo _battleRecoveryInfoFallback;
|
||||
public static BattleRecoveryInfo BattleRecoveryInfo
|
||||
{
|
||||
- get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.RecoveryInfo ?? _battleRecoveryInfoFallback;
|
||||
- set
|
||||
- {
|
||||
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
|
||||
- if (c != null) c.RecoveryInfo = value;
|
||||
- else _battleRecoveryInfoFallback = value;
|
||||
- }
|
||||
+ // Soft read: returns null when no scope is active. The MulliganMgrBase.StartDeal call site
|
||||
+ // reads this with a null-tolerant ??=-style pattern, so a null degrade is the historical
|
||||
+ // fallback. Inside a scope, returns the per-session RecoveryInfo (SessionBattleEngine
|
||||
+ // pre-seeds an uninitialized BattleRecoveryInfo on its ctx field initializer).
|
||||
+ get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.RecoveryInfo;
|
||||
+ // Strict setter: writes must land on the per-session ctx. No historical production caller
|
||||
+ // writes this outside a scope; an unwrapped write now fails fast (forcing function).
|
||||
+ set => SVSim.BattleEngine.Ambient.BattleAmbient.Require().RecoveryInfo = value;
|
||||
}
|
||||
Reference in New Issue
Block a user