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>
74 lines
3.2 KiB
Diff
74 lines
3.2 KiB
Diff
Multi-instancing migration (Step 8 — forcing function): delete the static viewer-id fallback the
|
|
earlier .ambient-viewerid patch added as a coexistence shim. ViewerId is now strictly per-session
|
|
ambient (BattleAmbient.Require().ViewerId). Supersedes the intermediate .ambient-viewerid patch
|
|
(kept for the audit trail).
|
|
|
|
Semantics:
|
|
- get : BattleAmbient.Require().ViewerId — strict (throws when no scope is active)
|
|
- set : NO-OP. The historical caller (SavedataManager.SetInt + Save) is the client process's
|
|
persistent-storage path; in the headless multi-instance world the viewer id flows from the
|
|
session ctx (BattleAmbientContext.ViewerId, init-only at scope entry — see
|
|
SessionBattleEngine's field initializer, which seeds it from EngineGlobalInit.ThisViewerId).
|
|
Making the setter strict (Require()) would also work but degrades to a write that can't land
|
|
(init-only) — a comment-documented no-op is clearer about why the setter went dead.
|
|
|
|
Related (SVSim.BattleNode/Sessions/Engine/EngineGlobalInit.cs): the reflection write that seeded
|
|
`Certification._viewerIdFallback` is now dead — the static is deleted. Replaced with a comment-
|
|
only marker so the design intent (ThisViewerId defines the engine's "player" perspective for the
|
|
IsRecovery target parse) stays discoverable from the global init path.
|
|
|
|
InitializeFileds(): the now-dead `_viewerIdFallback = 0;` line is also deleted (the line above and
|
|
below — SavedataManager.SetInt("VIEWER_ID", 0) — stay).
|
|
|
|
In-file edits:
|
|
- line ~19 declaration `private static int _viewerIdFallback;` DELETED
|
|
- lines ~41-65 the ambient+fallback get/set body REPLACED with strict get + no-op set
|
|
- line ~155 `_viewerIdFallback = 0;` inside InitializeFileds DELETED
|
|
|
|
--- Engine/Cute/Certification.cs (~line 19)
|
|
private static string udid;
|
|
-
|
|
- private static int _viewerIdFallback;
|
|
-
|
|
private static int short_udid;
|
|
|
|
--- Engine/Cute/Certification.cs (~lines 41-65)
|
|
public static int ViewerId
|
|
{
|
|
- get
|
|
- {
|
|
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
|
|
- if (c != null) return c.ViewerId;
|
|
- if (_viewerIdFallback == 0)
|
|
- {
|
|
- _viewerIdFallback = Toolbox.SavedataManager.GetInt("VIEWER_ID");
|
|
- }
|
|
- return _viewerIdFallback;
|
|
- }
|
|
- set
|
|
- {
|
|
- var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
|
|
- if (c != null)
|
|
- {
|
|
- // Inside a scope, ViewerId is fixed at scope entry — swallow the write.
|
|
- return;
|
|
- }
|
|
- Toolbox.SavedataManager.SetInt("VIEWER_ID", value);
|
|
- Toolbox.SavedataManager.Save();
|
|
- _viewerIdFallback = value;
|
|
- }
|
|
+ // Post-Task-8: strictly ambient. The historical SavedataManager-backed lazy decode was the
|
|
+ // client process's single-viewer-id source; in the headless multi-instance world the viewer
|
|
+ // id MUST come from the per-session ambient context. Setter is a no-op (BattleAmbientContext
|
|
+ // .ViewerId is `init`-only — fixed at scope entry per design — and the historical caller
|
|
+ // (SavedataManager.SetInt + Save) is dead in the server world).
|
|
+ get => SVSim.BattleEngine.Ambient.BattleAmbient.Require().ViewerId;
|
|
+ set { /* ambient ViewerId is init-only; SavedataManager path is dead headless */ }
|
|
}
|
|
|
|
--- Engine/Cute/Certification.cs (~line 155)
|
|
sessionId = null;
|
|
udid = null;
|
|
- _viewerIdFallback = 0;
|
|
short_udid = 0;
|