Multi-instancing migration (Step 3): convert the dominant per-battle singleton seam — the
static `main` backing field and the `GetIns()` accessor — to read through BattleAmbient.Current
first, falling back to a renamed `_mainFallback` static when no scope is active. The legacy
field is kept (renamed) so unwrapped callers (SingleBattleMgr today, in-process tests that
don't yet wrap in BattleAmbient.Enter) keep working with zero behavioral change; scoped
callers get per-AsyncLocal isolation so sibling battles in the same process don't clobber
each other's "current manager" (design 2026-06-07-engine-multi-instancing, Task 3).

GetIns() is the canonical accessor used by ~hundreds of engine call sites; routing it through
ambient is what makes the rest of the migration value-adding. Direct cross-file reads of
`BattleManagerBase.main` were already absent (the field was private; only an in-comment
reference in Shim/BattleAmbientContext.cs exists), so no external callers needed updating.

In-file references (4 total) handled as follows:
  - line 413 declaration         → renamed to `_mainFallback`
  - line 725 GetIns body          → ambient-first via Current?.Mgr ?? _mainFallback
  - line 730 ctor `main = this`   → `_mainFallback = this`
  - line 1491 dispose `main=null` → `_mainFallback = null`

--- Engine/BattleManagerBase.cs  (~line 413)
-	private static BattleManagerBase main;
+	private static BattleManagerBase _mainFallback;

--- Engine/BattleManagerBase.cs  (~line 725)
 	public static BattleManagerBase GetIns()
 	{
-		return main;
+		return SVSim.BattleEngine.Ambient.BattleAmbient.Current?.Mgr ?? _mainFallback;
 	}

--- Engine/BattleManagerBase.cs  (~line 730)
 	protected BattleManagerBase(IBattleMgrContentsCreator contentsCreator)
 	{
-		main = this;
+		_mainFallback = this;

--- Engine/BattleManagerBase.cs  (~line 1491)
-		main = null;
+		_mainFallback = null;
 	}
