engine cleanup passes 4-7 + multi-instancing ambient rip

Squashes 146 commits from battle-engine-extraction. Net: 2,045 files changed,
+11,896 / -158,687 lines. Ships engine passes 4-7 (dead-code cull, view-layer
stub, receive-path shrink) plus the Phase-5 AsyncLocal ambient deletion that
turns concurrent battles into a type-system property rather than a scope
contract.

## What landed

**Passes 4-7 (chunks 1-34):** Extended the Phase-4 const-false collapse into a
cascading cull across the skill graph, view layer, and receive-path periphery.
Six mode flags (IsWatchBattle/IsReplayBattle/IsAdmin/IsAdminWatch/IsPuzzleQuest/
IsAINetwork) became `const false`, every guarded block deleted. Field*.cs
subclass ctors + BackGroundBase + ObjectChecker culled to no-ops. Mulligan
family reworked to take a mgr param through IMulliganMgr.InitMulligan.
Emotion/Recovery/Resource clusters null-stubbed. Prediction/OperationSimulator/
skill filters converted from static ambient reads to per-mgr reads via
SkillPrm.ownerCard.SelfBattlePlayer.BattleMgr / ins.BattleMgr / this.BattleMgr.

**Phase-5 ambient rip (chunks 35-47):** Deleted BattleAmbient / BattleAmbient-
Context / TestBattleScope in full. Every per-battle mutable slot now lives on
the mgr instance itself:
  mgr.InstanceIsForecast / InstanceIsRandomDraw / InstanceRecoveryInfo /
  InstanceViewerId / InstanceNetworkAgent / GameMgr
BattleManagerBase.GetIns() returns null unconditionally; the residual static
flags + 3 façades (Certification.ViewerId, Data.BattleRecoveryInfo,
ToolboxGame.RealTimeNetworkAgent) are null-tolerant defaults kept for the
handful of engine-internal readers that still reference their types. Zero
BattleAmbient references anywhere in engine + node + tests.

Added pre-seeded GameMgr ctor overload threaded through the mgr chain
(BattleManagerBase → SingleBattleMgr / NetworkBattleManagerBase → NetworkStandard-
BattleMgr → HeadlessBattleMgr / HeadlessNetworkBattleMgr). Fixtures build a
GameMgr, seed it via HeadlessEngineEnv.SeedCharaIds/SeedNetUser, and pass it
to the mgr's ctor — no ambient reach.

Node side (SVSim.BattleNode/SessionBattleEngine): _ctx replaced with a plain
GameMgr field; 34 `using var _ambient = BattleAmbient.Enter(_ctx)` scope wraps
ripped from every accessor and mutator; EngineGlobalInit.WirePerSessionGameMgr
takes GameMgr as a param and runs from SessionBattleEngine.SetupInternal
BEFORE mgr construction.

Test side: TestBattleScope deleted; 18 fixture [SetUp]s migrated to
`HeadlessEngineEnv.EnsureProcessGlobals()`; MultiInstanceEngineTests rewritten
around per-mgr construction (GetIns() → null is the pinned invariant).

## Regression fixes

- **chunk-48** (MulliganCtrl): chunk-35's `= null` stubs on card lookups broke
  the live receive-driven Deal path (BattlePlayerBase.DrawCard NRE'd downstream
  of NetworkPlayerMulliganCtrl.StartMulliganVfx). Restored the three lookups
  via `_battlePlayer.BattleMgr.GetBattleCardIdx`. Engine tests were satisfied
  by the WireMulliganPhase seam; unit tests exposed the live-path gap.

## Ship state

- SVSim.BattleEngine.Tests: 56/56 pass, 2 skip
- SVSim.UnitTests: 1554/1554 pass (was 1523/31-fail before chunk 48)
- Solution build: 0 source warnings (40 pre-existing NU1902 MessagePack CVEs
  in SVSim.EmulatedEntrypoint, unrelated)
- Sequential PVP smoke: verified live (two back-to-back battles, no regression
  on cleanup/spinup)
- Concurrent PVP smoke: verified live

Adds tools/engine-port/ClosureAnalyzer/ — the Roslyn transitive-type-closure
analyzer needed to make future cascade cleanup safe (per feedback memory
"Engine cleanup needs closure tool" from the 2026-06-28 pass-3 failure).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-07-03 19:18:54 -04:00
parent 5c1db83967
commit 2d9a6eea4b
2045 changed files with 11704 additions and 158495 deletions

View File

@@ -11,207 +11,10 @@ namespace Wizard.RoomMatch
public partial class RoomBase
{
public delegate void ChangeScene(UIManager.ViewScene in_NextScene, UIManager.ChangeViewSceneParam in_Param, object sceneParam);
private const float BG_SCALE = 1.25f;
private const int BG_ORIGINAL_WIDTH = 2048;
private const int BG_ORIGINAL_HEIGHT = 1024;
private const float BG_WIDTH_SCALE = 56f;
private const float BG_HEIGHT_SCALE = 68f;
private static RoomBase _main;
public static RoomConnectController ConnectController;
protected static bool _isReturnFromBattle;
protected static Player _saveOpponentData;
private bool _isRoomReady;
private bool _isMatchingStart;
private bool _isReceiveSetupComplete;
private bool _isWaitSetupCancel;
private List<string> _roomResourcePathListForUpdateUI;
private List<string> _loadCardAssetList;
private bool _finishLoadCardAsset;
private RoomDeckList _roomDeckList;
private GameObject _CardDetailPrefab;
private GameObject _DeckViewPrefab;
public RoomFriendTask FriendTaskClass;
public RoomInviteFriend RoomInviteFriendClass;
public GameObject m_commentDialog;
public GameObject _stageSelectPrefab;
private SpriteRenderer _BgSprite;
private GameObject _BgEffect;
private GameObject _readyButtonRoot;
private UISprite m_btnReady;
private UILabel _labelReady;
private UISprite m_btnCancelReady;
private GameObject _firstTurnSelectRoot;
public UIButton _firstTurnChangeButton;
public UIButton _firstTurnChangeButtonBG;
public UILabel _firstTurnLabel;
public UIButton ReturnTournamentButton;
private const float WAIT_CANCEL_READY_TIME = 1f;
private bool _deckViewCloseRequest;
private Coroutine _waitCancelReady;
public UILabel m_labelRoomID;
private GameObject _roomIdRoot;
public GameObject RoomIDBaseObject;
private bool _isEventSetting;
private RoomConnectChecker _roomConnectChecker;
private ConventionInfo _conventionInfo;
private GatheringGetSelfInfoTask _gatheringGetSelfInfoTask;
private GameObject _backEffectObject;
private const string BG_IMAGE_NAME = "bg_mausoleum_1_1";
private const string BG_MATERIAL_NAME = "scn_bg_mausoleum_1";
private float _roomTimeoutReleaseTimer;
private bool _roomTimeoutReleasePossible;
private const float TIMEOUT_RELEASE_TIME = 1800f;
private int _resourceLoadingCounter;
private bool _isUpdateUIRequest;
private bool _isFinishReadyViewScene;
public static bool IsMatchingFinish;
private RoomRoot _roomRoot;
private Coroutine _setupCorutine;
private bool _isExistOppo;
private bool _isReady;
private static Matching _matchingInstance;
public bool IsRoomReadyComplete { get; set; }
public TopBar TopBar { get; set; }
protected DialogBase _deckDialog { get; set; }
public static DialogBase DeckConfirmDialog { get; set; }
public List<string> RoomResourcePathList { get; set; }
public UICardList UICardListInstance { get; set; }
protected bool IsExistLoadCoroutine { get; set; }
public DeckGroupListData DeckGroupListData { get; set; }
protected ConventionDeckList ConventionDeckList { get; set; }
public bool EnableFirstViewLastUseDeck { get; set; }
public List<DeckData> HoFDeckList { get; set; }
public List<DeckData> WindFallDeckList { get; set; }
public List<DeckData> AvatarDeckList { get; set; }
public CardDetailUI CardDetail { get; set; }
protected DialogBase _treasureCpDialog { get; set; }
public DialogBase TreasureCpGradeUpConditionDialog { get; set; }
public bool ReturnTournamentButtonVisible { get; set; }
public bool IsRecoveryRoom { get; set; }
public bool IsConvention { get; set; }
public bool IsGathering { get; set; }
public bool IsTournament { get; set; }
public bool IsTimeoutRelease { get; set; }
protected bool IsDialogLoading { get; set; }
public UIBase UIBase { get; set; }
public bool IsReceiveExitRoom { get; set; }
public bool IsExistOppo { get; set; }
public bool IsReady { get; set; }
public RoomCommonEventHandler CommonEventHandler { get; set; }
public RoomFirstTurnSelect FirstTurnSelect { get; set; }
public RoomRoot RoomRoot { get; set; }
public RoomConnectController.PositionMode OwnRole { get; set; }
public bool IsDeckOpenRule { get; set; }
public BattleParameter BattleParameterInstance { get; set; }
public long SelfSleeveIdForTwoPick { get; set; }
public OpenRoomBattleGetRecoveryParamTask RecoveryTask { get; set; }
public bool IsInitializeDone { get; set; }
public bool IsConnectSuccess { get; set; }
public RoomConnectChecker RoomConnectChecker { get; set; }
protected bool ReadyButtonEnable { get; set; }
public static RoomBase GetInstance() => default!;
public static bool IsConnectControllerActive() => default!;
public static void OnSoftwareReset() { }
public bool IsNeedStopNodeReceive() => default!;
protected List<string> GetResourcePathList() => default!;
protected virtual void UpdateUIBody() { }
protected void LoadResource(List<string> pathList, Action onFinish) { }
private void RunUpdateUIRequest() { }
protected void UpdateUI() { }
private void UpdateReadyButton() { }
protected virtual void OnChangeReady(bool ready) { }
protected virtual void OnChangeExistOwner(bool exist) { }
protected void OnChangeExistOpponent(bool exist, bool beforeValue) { }
public void SetPlayerAliveCheckDisp(bool disp) { }
public void SetOpponentAliveCheckDisp(bool disp) { }
public void OnInviteCancel() { }
public IEnumerator DisplayInviteFriendInfo(RoomVisitor friend) => default!;
public virtual void DisconnectForceExitRoom() { }
protected virtual void CloseDialog() { }
protected virtual void OnMatchingStart() { }
protected IEnumerator SetupOnlyReturnRoom(bool isBattleEnd) => default!;
protected IEnumerator SetupFinish(bool isBattleEnd) => default!;
protected virtual void SetupFinishAfterNodeParse(bool isBattleEnd) { }
protected virtual void SetupFirstOnly() { }
private void SetupReadyButton() { }
private void SetParent(GameObject parent, GameObject child) { }
protected virtual void SetupSoon() { }
protected virtual void SetupRecovery() { }
private IEnumerator Setup() => default!;
private IEnumerator SetupDeckList() => default!;
private IEnumerator StartTimeOutCorutine(int timer, Action onTimeOut = null) => default!;
private bool IsNeedWaitInitWatch() => default!;
private IEnumerator SetupReturnFromBattle(bool isBattleEnd) => default!;
private void UpdateLastGungnirSuccessTime() { }
protected virtual IEnumerator RecoveryRoom() => default!;
protected IEnumerator RecoveryRoomAfterNodeReceive() => default!;
protected virtual void RecoveryEndToEmitData() { }
private void SetupCommentRestore(bool isBattleEnd) { }
private IEnumerator SetupBase() => default!;
private void SetupBG() { }
public static void SetBgSpriteScale(SpriteRenderer spriteRenderer, float bgScale) { }
public static void AdjustBg(Transform bgSpriteRoot, Transform bgEffectRoot, float bgScale) { }
protected void OnPlayerEventOwnReady() { }
protected void OnPlayerEventOwnReadyCancel() { }
protected void OnPlayerEventOwnKick() { }
protected void OnPlayerEventOpponentEnterRoom() { }
protected void OnPlayerEventOpponentExit() { }
protected void OnPlayerEventOpponentReady() { }
protected void OnPlayerEventOpponentReadyCancel() { }
protected void OnPlayerEventOpponentSelectDeckOpen() { }
protected void OnCloseRoom() { }
public void InitializeRoot(RoomRoot root) { }
public virtual void Initialize() { }
public bool IsTournamentRoomEnd() => default!;
private void CopyConnectControllerSetting() { }
private void InitializeDeckConfirm() { }
public bool EnableFlavorVoice(bool isLocalPlayersDeck) => default!;
protected void SettingDialogCloseToGoBackScene(DialogBase dialog) { }
protected void GetBackSceneAndParam(out UIManager.ViewScene scene, out UIManager.ChangeViewSceneParam param) { scene = default!; param = default!; }
private void InitializeTopBarAndSceneChange() { }
public virtual void onClose() { }
private void ReleaseResource() { }
protected DialogBase ReleaseNetworkAndCreateExitDialog(string title, string msg) => default!;
private void ReleaseRealTimeNetwork() { }
protected void ExitOrRelease(ChangeScene in_Change, UIManager.ViewScene in_NextScene, UIManager.ChangeViewSceneParam in_Param, Action onDestroyEnd = null) { }
public static void DestroyMyRoomInfo() { }
public void CloseAllDialog() { }
protected void ForceCloseRoom() { }
private void SetExistOpponent(bool exist, bool enableEventCall) { }
protected void SetReady(bool ready) { }
public void UpdateBackKeyEnable() { }
protected void SetReadyButtonLabel(string text) { }
protected void SetButtonEnable(GameObject inButtonObject, bool inIsEnable) { }
protected void SetReadyButtonGameObjectActive(bool enable) { }
public void DeckViewClose() { }
public void DeckCardListView(DeckData deck, bool isLocalPlayersDeck) { }
private IEnumerator CardLoadCoroutine(DeckData deck, bool isLocalPlayersDeck) => default!;
private void SetupDeckCardList(DeckData deck) { }
protected void SetFooterBackBtnEnable(bool in_Enable) { }
public DialogBase CreateDialog(string title, string msg, GameObject setObject = null) => default!;
public void CreateChangeSceneDialog(UIManager.ViewScene in_NextScene, UIManager.ChangeViewSceneParam in_Param = null, Action in_MoveCallBack = null) { }
protected virtual string GetAlternativeChangeSceneDialogText() => default!;
protected virtual bool SendReady() => default!;
public void OnBtnReady(GameObject g) { }
private void OnClickTournamentExitButton(GameObject obj) { }
private void OnBtnCancelReady(GameObject g) { }
private void SuccessCancelReady() { }
private IEnumerator WaitCancelReadyCoroutine() => default!;
protected virtual void Update() { }
private void CheckMatching() { }
private void OnRoomReady() { }
public static void OnAlreadySetup() { }
public static void SettingOpponentDispData(bool isOwner, string name, long Emblem, int degree, string contry, int rank, bool isOfficialUser, int highFormatRank) { }
public static void ResetOpponentData() { }
private void AttachEvent() { }
private void CloseLoadingScene() { }
public void CreateReleaseRoomDialog() { }
public static void StartDialogLoading() { }
public static void FinishDiloagLoading() { }
public void OnGatheringDeckListIsEmpty() { }
protected void AttachPlayerEvent() { }
public DeckData GetDeckByDeckId(int deckId) => default!;
public void SetBattleDeckData(DeckData deck) { }
public static void ExitFailuredErrorDialog() { }
}
}