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; } }