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>
202 lines
7.5 KiB
C#
202 lines
7.5 KiB
C#
// AUTHORED SHIM (not copied). No-op member extensions to the UnityEngine value/component
|
|
// shims, added as the M1 compile loop surfaced specific calls from copied engine/view
|
|
// code. Signatures mirror the real UnityEngine API at the call sites (arg counts/types
|
|
// taken from the decomp). None executes headless — all return safe defaults.
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace UnityEngine
|
|
{
|
|
public partial struct Vector4
|
|
{
|
|
public static Vector4 zero => default;
|
|
public static Vector4 operator *(Vector4 a, float s) => new Vector4(a.x * s, a.y * s, a.z * s, a.w * s);
|
|
public static Vector4 operator *(float s, Vector4 a) => new Vector4(a.x * s, a.y * s, a.z * s, a.w * s);
|
|
public static Vector4 operator +(Vector4 a, Vector4 b) => new Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
|
|
public static Vector4 operator -(Vector4 a, Vector4 b) => new Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
|
|
public static bool operator ==(Vector4 a, Vector4 b) => a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
|
|
public static bool operator !=(Vector4 a, Vector4 b) => !(a == b);
|
|
public override bool Equals(object o) => o is Vector4 v && this == v;
|
|
public override int GetHashCode() => x.GetHashCode() ^ (y.GetHashCode() << 2) ^ (z.GetHashCode() << 4) ^ (w.GetHashCode() << 6);
|
|
public Vector4(float x, float y, float z) { this.x = x; this.y = y; this.z = z; this.w = 0f; }
|
|
public Vector4(float x, float y) { this.x = x; this.y = y; this.z = 0f; this.w = 0f; }
|
|
// UnityEngine implicitly promotes/truncates between Vector2/3/4.
|
|
public static implicit operator Vector4(Vector3 v) => new Vector4(v.x, v.y, v.z, 0f);
|
|
public static implicit operator Vector3(Vector4 v) => new Vector3(v.x, v.y, v.z);
|
|
public static implicit operator Vector4(Vector2 v) => new Vector4(v.x, v.y, 0f, 0f);
|
|
public static implicit operator Vector2(Vector4 v) => new Vector2(v.x, v.y);
|
|
}
|
|
|
|
public partial class Transform
|
|
{
|
|
public bool hasChanged { get; set; }
|
|
public Matrix4x4 localToWorldMatrix => default;
|
|
public Matrix4x4 worldToLocalMatrix => default;
|
|
public void Rotate(float x, float y) { }
|
|
public void Translate(Vector3 translation, Space relativeTo) { }
|
|
public void Rotate(Vector3 eulers, Space relativeTo) { }
|
|
}
|
|
|
|
public partial class LODGroup
|
|
{
|
|
public bool enabled { get; set; }
|
|
public LOD[] GetLODs() => Array.Empty<LOD>();
|
|
}
|
|
|
|
public struct LOD
|
|
{
|
|
public float screenRelativeTransitionHeight;
|
|
public Renderer[] renderers;
|
|
public LOD(float height, Renderer[] rends) { screenRelativeTransitionHeight = height; renderers = rends; }
|
|
}
|
|
|
|
public partial class Rigidbody
|
|
{
|
|
public bool isKinematic { get; set; }
|
|
public bool useGravity { get; set; }
|
|
public void MovePosition(Vector3 position) { }
|
|
public void MoveRotation(Quaternion rotation) { }
|
|
}
|
|
|
|
public partial class Material
|
|
{
|
|
public void CopyPropertiesFromMaterial(Material mat) { }
|
|
}
|
|
|
|
public partial class Mesh
|
|
{
|
|
public int vertexCount => 0;
|
|
public Vector3[] normals { get; set; }
|
|
public Vector4[] tangents { get; set; }
|
|
public Vector2[] uv { get; set; }
|
|
public Color32[] colors32 { get; set; }
|
|
public void MarkDynamic() { }
|
|
}
|
|
|
|
public partial class Texture2D
|
|
{
|
|
public byte[] EncodeToPNG() => Array.Empty<byte>();
|
|
public bool LoadImage(byte[] data) => false;
|
|
}
|
|
|
|
public partial class Sprite
|
|
{
|
|
public Rect textureRect => default;
|
|
public Vector2 textureRectOffset => default;
|
|
}
|
|
|
|
public partial class Shader
|
|
{
|
|
public static int PropertyToID(string name) => 0;
|
|
public static void SetGlobalColor(string name, Color value) { }
|
|
}
|
|
|
|
public partial class Animation
|
|
{
|
|
public bool enabled { get; set; }
|
|
public bool IsPlaying(string name) => false;
|
|
public void Sample() { }
|
|
}
|
|
|
|
public partial class AudioSource
|
|
{
|
|
public float pitch { get; set; }
|
|
public bool playOnAwake { get; set; }
|
|
public int priority { get; set; }
|
|
public void PlayOneShot(AudioClip clip) { }
|
|
}
|
|
|
|
public partial class Camera
|
|
{
|
|
public bool enabled { get; set; }
|
|
public static int GetAllCameras(Camera[] cameras) => 0;
|
|
}
|
|
|
|
public partial struct CharacterInfo
|
|
{
|
|
public int advance;
|
|
public int minX, maxX, minY, maxY;
|
|
public Vector2 uvBottomLeft, uvBottomRight, uvTopLeft, uvTopRight;
|
|
}
|
|
|
|
public partial class Font
|
|
{
|
|
public string[] fontNames { get; set; }
|
|
public Material material { get; set; }
|
|
public static event Action<Font> textureRebuilt;
|
|
public bool GetCharacterInfo(char ch, out CharacterInfo info, int size, FontStyle style)
|
|
{ info = default; return false; }
|
|
public void RequestCharactersInTexture(string characters, int size, FontStyle style) { }
|
|
}
|
|
|
|
public partial class Light
|
|
{
|
|
public Color color { get; set; }
|
|
}
|
|
|
|
public partial class Time
|
|
{
|
|
public static float smoothDeltaTime => 0f;
|
|
}
|
|
|
|
public partial class Application
|
|
{
|
|
public static NetworkReachability internetReachability => NetworkReachability.NotReachable;
|
|
public static void OpenURL(string url) { }
|
|
}
|
|
|
|
public enum NetworkReachability { NotReachable}
|
|
|
|
public partial class Screen
|
|
{
|
|
public static int sleepTimeout { get; set; }
|
|
}
|
|
|
|
public enum IMECompositionMode { Auto, On}
|
|
|
|
public partial class Input
|
|
{
|
|
public static Vector2 compositionCursorPos { get; set; }
|
|
public static string compositionString => "";
|
|
public static IMECompositionMode imeCompositionMode { get; set; }
|
|
}
|
|
|
|
public partial class Resources
|
|
{
|
|
public static Object[] FindObjectsOfTypeAll(Type type) => Array.Empty<Object>();
|
|
}
|
|
}
|
|
|
|
namespace UnityEngine.Networking
|
|
{
|
|
public partial class UnityWebRequest
|
|
{
|
|
public UnityWebRequest() { }
|
|
public UnityWebRequest(string url, string method) { }
|
|
public static string EscapeURL(string s) => s;
|
|
public static UnityWebRequest Get(string uri) => new UnityWebRequest();
|
|
public UnityWebRequestAsyncOperation SendWebRequest() => new UnityWebRequestAsyncOperation();
|
|
public void SetRequestHeader(string name, string value) { }
|
|
public Dictionary<string, string> GetResponseHeaders() => new Dictionary<string, string>();
|
|
public bool isDone => true;
|
|
public float downloadProgress => 1f;
|
|
public long responseCode => 200;
|
|
public string error => null;
|
|
public DownloadHandler downloadHandler { get; set; }
|
|
public UploadHandler uploadHandler { get; set; }
|
|
}
|
|
|
|
public class DownloadHandler { public byte[] data => Array.Empty<byte>(); public string text => ""; }
|
|
public class UploadHandler { }
|
|
public class UploadHandlerRaw : UploadHandler { public UploadHandlerRaw(byte[] data) { } }
|
|
public class DownloadHandlerBuffer : DownloadHandler { }
|
|
public class UnityWebRequestAsyncOperation : AsyncOperation { }
|
|
}
|
|
|
|
namespace UnityEngine
|
|
{
|
|
// ---- additional off-battle-path Unity type stubs (CS0246 closure) ----
|
|
public sealed class WaitForSecondsRealtime : YieldInstruction { public WaitForSecondsRealtime(float time) { } }
|
|
public class AnimationState { public string name { get; set; } public float speed { get; set; } public float time { get; set; } public float length => 0f; }
|
|
}
|