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;
