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;
