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:
@@ -66,8 +66,6 @@ public class UIWidget : UIRect
|
||||
|
||||
public float aspectRatio = 1f;
|
||||
|
||||
public HitCheck hitCheck;
|
||||
|
||||
[NonSerialized]
|
||||
public UIPanel panel;
|
||||
|
||||
@@ -116,31 +114,6 @@ public class UIWidget : UIRect
|
||||
|
||||
private Vector3 mOldV1;
|
||||
|
||||
public UIDrawCall.OnRenderCallback onRender
|
||||
{
|
||||
get
|
||||
{
|
||||
return mOnRender;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mOnRender != value)
|
||||
{
|
||||
if (drawCall != null && drawCall.onRender != null && mOnRender != null)
|
||||
{
|
||||
UIDrawCall uIDrawCall = drawCall;
|
||||
uIDrawCall.onRender = (UIDrawCall.OnRenderCallback)Delegate.Remove(uIDrawCall.onRender, mOnRender);
|
||||
}
|
||||
mOnRender = value;
|
||||
if (drawCall != null)
|
||||
{
|
||||
UIDrawCall uIDrawCall2 = drawCall;
|
||||
uIDrawCall2.onRender = (UIDrawCall.OnRenderCallback)Delegate.Combine(uIDrawCall2.onRender, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4 drawRegion
|
||||
{
|
||||
get
|
||||
@@ -406,22 +379,6 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
public int raycastDepth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (panel == null)
|
||||
{
|
||||
CreatePanel();
|
||||
}
|
||||
if (!(panel != null))
|
||||
{
|
||||
return mDepth;
|
||||
}
|
||||
return mDepth + panel.depth * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3[] localCorners
|
||||
{
|
||||
get
|
||||
@@ -448,15 +405,6 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 localCenter
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3[] array = localCorners;
|
||||
return Vector3.Lerp(array[0], array[2], 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3[] worldCorners
|
||||
{
|
||||
get
|
||||
@@ -475,8 +423,6 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 worldCenter => base.cachedTransform.TransformPoint(localCenter);
|
||||
|
||||
public virtual Vector4 drawingDimensions
|
||||
{
|
||||
get
|
||||
@@ -536,21 +482,6 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("There is no relative scale anymore. Widgets now have width and height instead")]
|
||||
public Vector2 relativeSize => Vector2.one;
|
||||
|
||||
public bool hasBoxCollider
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GetComponent<Collider>() as BoxCollider != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return GetComponent<BoxCollider2D>() != null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int minWidth => 2;
|
||||
|
||||
public virtual int minHeight => 2;
|
||||
@@ -724,18 +655,6 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DebuggerStepThrough]
|
||||
public static int FullCompareFunc(UIWidget left, UIWidget right)
|
||||
{
|
||||
int num = UIPanel.CompareFunc(left.panel, right.panel);
|
||||
if (num != 0)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
return PanelCompareFunc(left, right);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DebuggerStepThrough]
|
||||
public static int PanelCompareFunc(UIWidget left, UIWidget right)
|
||||
@@ -769,11 +688,6 @@ public class UIWidget : UIRect
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Bounds CalculateBounds()
|
||||
{
|
||||
return CalculateBounds(null);
|
||||
}
|
||||
|
||||
public Bounds CalculateBounds(Transform relativeParent)
|
||||
{
|
||||
if (relativeParent == null)
|
||||
@@ -1027,25 +941,12 @@ public class UIWidget : UIRect
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool paused)
|
||||
{
|
||||
if (!paused)
|
||||
{
|
||||
MarkAsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
RemoveFromPanel();
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
RemoveFromPanel();
|
||||
}
|
||||
|
||||
public bool UpdateVisibility(bool visibleByAlpha, bool visibleByPanel)
|
||||
{
|
||||
if (mIsVisibleByAlpha != visibleByAlpha || mIsVisibleByPanel != visibleByPanel)
|
||||
|
||||
Reference in New Issue
Block a user