Files
SVSimServer/SVSim.BattleEngine/Patches/BattleManagerBase.ambient-fallback-deletion.patch
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

78 lines
3.6 KiB
Diff

Multi-instancing migration (Step 8 — forcing function): delete the static per-battle fallbacks
the earlier ambient-* patches added as a coexistence shim. With the fallbacks gone, any unwrapped
engine call into IsForecast/IsRandomDraw fails fast (BattleAmbient.Require() throws
InvalidOperationException); GetIns soft-returns null when no scope is active so engine code
that patterns `GetIns()?.Foo ?? default` keeps composing (per design — strict for setters /
load-bearing reads, soft for the GetIns null-tolerant chain). Supersedes the intermediate
.ambient-isforecast-israndomdraw + .ambient-main-getins patches (kept for the audit trail).
Semantics chosen per accessor:
- IsForecast : get/set both BattleAmbient.Require() — strict (must be in a scope)
- IsRandomDraw : get/set both BattleAmbient.Require() — strict
- GetIns() : Current?.Mgr — soft (null when no scope; preserves engine `?.` patterns)
- ctor : `_mainFallback = this` line deleted entirely
- DisposeManager: `_mainFallback = null` line deleted entirely
In-file edits:
- line ~413 declaration `private static BattleManagerBase _mainFallback;` DELETED
- lines ~415-432 the four fallback statics + their if-else fallback branches DELETED,
replaced with strict get/set via BattleAmbient.Require()
- line ~727 GetIns() body -> Current?.Mgr (no fallback)
- line ~732 ctor `_mainFallback = this` DELETED (no longer needed; ambient.Mgr is published
explicitly from SessionBattleEngine.SetupInternal after construction)
- line ~1491 dispose `_mainFallback = null` DELETED (the matching scope drop replaces it)
--- Engine/BattleManagerBase.cs (~lines 413-433)
- private static BattleManagerBase _mainFallback;
-
- private static bool _isRandomDrawFallback = false;
- public static bool IsRandomDraw {
- get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.IsRandomDraw ?? _isRandomDrawFallback;
- set {
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
- if (c != null) c.IsRandomDraw = value;
- else _isRandomDrawFallback = value;
- }
- }
-
- private static bool _isForecastFallback = false;
- public static bool IsForecast {
- get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.IsForecast ?? _isForecastFallback;
- set {
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
- if (c != null) c.IsForecast = value;
- else _isForecastFallback = value;
- }
- }
+ public static bool IsRandomDraw {
+ get => SVSim.BattleEngine.Ambient.BattleAmbient.Require().IsRandomDraw;
+ set => SVSim.BattleEngine.Ambient.BattleAmbient.Require().IsRandomDraw = value;
+ }
+
+ public static bool IsForecast {
+ get => SVSim.BattleEngine.Ambient.BattleAmbient.Require().IsForecast;
+ set => SVSim.BattleEngine.Ambient.BattleAmbient.Require().IsForecast = value;
+ }
--- Engine/BattleManagerBase.cs (~line 727)
public static BattleManagerBase GetIns()
{
- return SVSim.BattleEngine.Ambient.BattleAmbient.Current?.Mgr ?? _mainFallback;
+ // Soft read: returns null when no scope is active, preserving engine call sites that
+ // pattern `GetIns()?.Foo ?? default`. Inside a scope, returns the scope's Mgr (which may
+ // itself be null mid-Setup — see SessionBattleEngine.SetupInternal, which publishes Mgr
+ // before WireMulliganPhase).
+ return SVSim.BattleEngine.Ambient.BattleAmbient.Current?.Mgr;
}
--- Engine/BattleManagerBase.cs (~line 732)
protected BattleManagerBase(IBattleMgrContentsCreator contentsCreator)
{
- _mainFallback = this;
BattleLifeTimeSharedObject = new BattleLifeTimeSharedObject();
--- Engine/BattleManagerBase.cs (~line 1491)
GameMgr.GetIns().GetPrefabMgr().AllUnLoad();
- _mainFallback = null;
}