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>
58 lines
2.8 KiB
Diff
58 lines
2.8 KiB
Diff
Multi-instancing migration (Step 8 — forcing function): delete the static RealTimeNetworkAgent
|
|
fallback the earlier .ambient-rtna patch added as a coexistence shim. RealTimeNetworkAgent is now
|
|
strictly per-session ambient. Supersedes the intermediate .ambient-rtna patch (kept for the audit
|
|
trail).
|
|
|
|
Semantics:
|
|
- RealTimeNetworkAgent (getter) : Current?.NetworkAgent — soft (null when no scope).
|
|
Engine code reads this via `ToolboxGame.RealTimeNetworkAgent?.Foo`-style patterns (network
|
|
send paths gated on a non-null agent), so a null on the unwrapped path is the correct
|
|
degrade — not a throw.
|
|
- SetRealTimeNetworkBattle : BattleAmbient.Require().NetworkAgent = agent — strict (writes must
|
|
land on the per-session ctx; forcing function).
|
|
- DestroyNetworkAgent : reads Current, destroys, nulls the ambient NetworkAgent in-place.
|
|
Outside a scope is a no-op (nothing to destroy in the ambient world).
|
|
|
|
In-file edits:
|
|
- line ~28 declaration `private static RealTimeNetworkAgent _realTimeNetworkAgentFallback;` DELETED
|
|
- lines ~29-32 getter body no fallback chain
|
|
- lines ~61-66 Set body Require() (strict)
|
|
- lines ~68-78 Destroy body Current-based; no fallback branch
|
|
|
|
--- Engine/Wizard/ToolboxGame.cs (~lines 28-32)
|
|
- private static RealTimeNetworkAgent _realTimeNetworkAgentFallback;
|
|
public static RealTimeNetworkAgent RealTimeNetworkAgent
|
|
{
|
|
- get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.NetworkAgent ?? _realTimeNetworkAgentFallback;
|
|
+ // Soft read: returns null when no scope is active, mirroring GetIns. Engine code reads
|
|
+ // this via `ToolboxGame.RealTimeNetworkAgent?.Foo`-style patterns (network-send paths
|
|
+ // gated on a non-null agent), so a null on the unwrapped path is the correct degrade —
|
|
+ // not a throw.
|
|
+ get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.NetworkAgent;
|
|
}
|
|
|
|
--- Engine/Wizard/ToolboxGame.cs (~lines 61-78)
|
|
public static void SetRealTimeNetworkBattle(RealTimeNetworkAgent agent)
|
|
{
|
|
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
|
|
- if (c != null) c.NetworkAgent = agent;
|
|
- else _realTimeNetworkAgentFallback = agent;
|
|
+ // Strict: must be inside a scope to set the per-session agent. Forcing-function — any
|
|
+ // historical unwrapped caller (no production callsite remains) now fails fast.
|
|
+ SVSim.BattleEngine.Ambient.BattleAmbient.Require().NetworkAgent = agent;
|
|
}
|
|
|
|
public static void DestroyNetworkAgent()
|
|
{
|
|
var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
|
|
- var current = c?.NetworkAgent ?? _realTimeNetworkAgentFallback;
|
|
+ var current = c?.NetworkAgent;
|
|
if (current != null)
|
|
{
|
|
Object.DestroyImmediate(current.gameObject);
|
|
- if (c != null) c.NetworkAgent = null;
|
|
- else _realTimeNetworkAgentFallback = null;
|
|
+ c.NetworkAgent = null;
|
|
}
|
|
}
|