Files
SVSimServer/SVSim.BattleEngine/Patches/Certification.ambient-viewerid.patch
gamer147 fe146fde50 refactor(engine-ambient): ViewerId/RealTimeNetworkAgent/BattleRecoveryInfo read ambient first
Step 4 of multi-instancing migration. Three additional per-battle statics
front-fronted by BattleAmbient.Current, each with a static fallback for
unwrapped callers. ViewerId's SavedataManager-persisting setter is preserved
on the fallback path; inside a scope, the setter is a no-op (the per-battle
perspective is fixed at scope entry).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-07 21:37:58 -04:00

62 lines
2.5 KiB
Diff

Multi-instancing migration (Step 4): convert Cute.Certification.ViewerId — the per-battle
"who is the local seat" identity — to resolve through BattleAmbient.Current when a scope is
active, falling back to the legacy SavedataManager-backed static when not. The old `viewer_id`
backing field is renamed to `_viewerIdFallback` so unwrapped callers (real client, in-process
unit tests without a BattleAmbient scope) keep the original lazy-load-from-savedata + write-
through-savedata behavior bit-for-bit; scoped callers get a per-AsyncLocal id without writing
to savedata (design 2026-06-07-engine-multi-instancing, Task 4).
Inside a scope the setter is a NO-OP: ViewerId is an init-time identity (it's set at scope
entry via `new BattleAmbientContext { ViewerId = ... }`'s init-only property), and swallowing
the write avoids any in-battle setter from mutating sibling-battle perspective. The fallback
setter preserves the original sequence exactly: SetInt + Save + assign backing field.
In-file references (3 total) handled as follows:
- line 19 declaration → renamed to `_viewerIdFallback`
- line 41 ViewerId property → ambient-first getter; setter swallows when scoped
- line 147 InitializeFileds → resets the renamed `_viewerIdFallback`
External reflection follow-up (NOT in this patch — separate edit, same commit):
SVSim.BattleNode/Sessions/Engine/EngineGlobalInit.cs (~line 154) reads the private field
by name to seed the headless "who am I" perspective. Renamed there from "viewer_id" to
"_viewerIdFallback" to match.
--- Engine/Cute/Certification.cs (~line 19)
- private static int viewer_id;
+ private static int _viewerIdFallback;
--- Engine/Cute/Certification.cs (~lines 41-57)
public static int ViewerId
{
get
{
- if (viewer_id == 0)
+ var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current;
+ if (c != null) return c.ViewerId;
+ if (_viewerIdFallback == 0)
{
- viewer_id = Toolbox.SavedataManager.GetInt("VIEWER_ID");
+ _viewerIdFallback = Toolbox.SavedataManager.GetInt("VIEWER_ID");
}
- return 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();
- viewer_id = value;
+ _viewerIdFallback = value;
}
}
--- Engine/Cute/Certification.cs (~line 147, InitializeFileds)
- viewer_id = 0;
+ _viewerIdFallback = 0;