Drive ATTACK frames through the headless receive conductor and assert on engine
board state (node-native harness). Two cases: follower -> enemy leader (leader
life drops by atk, attacker spent) and a lethal follower-vs-follower trade (both
removed). ATTACK opcode confirmed = 10 (NetworkBattleDefine.PlayActionType).
Headless view-untangle (no Engine logic edits; drift clean):
- IBattlePlayerView.AttackSelectControl -> non-null HeadlessAttackSelectControl
(no-op RegisterAttackPair/ResetCardAfterAttack); IsCardTranslatable left to base.
- IBattleCardView.CardInfo -> backing card via BuildInfo (so IsCardTranslatable
reads authentic IsClass); class/null view ctors now chain : base(buildInfo).
- IBattleCardView._inPlayFrameEffect -> non-null no-op control.
- Seed Certification.viewer_id headless so the IsRecovery target parse
(vid != UserViewerID) does not throw inside SavedataManager and silently drop
the parsed targetList.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- _IfaceImpl.g.cs: extend header to warn about hand-edits; tag all bare
// HEADLESS-FIX lines with their milestone (M13 on GetSideLogControl ×2)
so `grep HEADLESS-FIX` reliably surfaces every block before a regen.
- HeadlessHandViewStub / HeadlessPlayQueueViewStub: narrow from public to
internal sealed — both stubs are consumed only within SVSim.BattleEngine
(via the generated partial impls); no public surface exposes the concrete
type, so internal is correct and aligns with HeadlessIconAnimations.
- SessionBattleEngine.SeedMulliganInfoControl: add one-line comment on the
GetComponent<MulliganInfoControl>() call explaining the shim's lazy
materialisation behaviour (otherwise reads like a guaranteed NRE).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The engine's receive CONDUCTOR fuses each authoritative mutation behind a view
call: the play mutation is an InstantVfx registered to VfxMgr, and the deal hand
is seated by MulliganPhaseBase.StartDeal wired to OperateReceive.OnReceiveDeal.
Headless, the shared VfxMgr no-op'd registration (correct for the direct
ActionProcessor path the M2-M12 oracles use) and OnReceiveDeal was never wired,
so the receive path resolved nothing.
Untangle (Candidate B, zero Engine logic edits):
- InstantVfx.Run() opt-in executor (authored shim).
- HeadlessConductorVfxMgr : VfxMgr runs registered InstantVfx; wired only via the
node's SessionContentsCreator.CreateVfxMgr (verified the receive mgr's VfxMgr
comes from there — BattleManagerBase.cs:768). M2-M12 use HeadlessContentsCreator,
so they're isolated by construction.
- WireMulliganPhase: construct NetworkMulliganPhase + MulliganEventSetting() to
install OnReceiveDeal -> StartDeal (the node never pumps the phase machine).
View no-op surface (the 7 from the probe, minus 1 not hit; +1 emergent):
- Deal wiring (NetworkMulliganPhase) [node seed]
- MulliganInfoControl._partsPlayer/_partsOpponent._exchangeMark/_keepZone/_abandonZone [node seed: prefab + SeedMulliganInfoControl]
- Data.BattleRecoveryInfo (IsMulliganEnd=false) [EngineGlobalInit seed]
- IBattlePlayerView.PlayQueueView -> HeadlessPlayQueueViewStub [_IfaceImpl.g.cs, both getters]
- DetailMgr.DetailPanelControl/SubDetailPanelControl [node seed]
- BattleCardIconAnimations.collection (emergent: UpdateInPlayBattleCardIconLabel) -> HeadlessIconAnimations empty SkillCollectionBase [_IfaceImpl.g.cs]
- BattleMenuBtn (probe item 7): NOT hit on the vanilla path; not seeded.
Oracle (HeadlessConductorTests): node Deal seats 3-card hand; a vanilla
hand-card Play leaves hand (-1), adds board (+1), drops PP by cost.
Regression: 24/24 BattleEngine.Tests oracles (M2-M12) green; 241/241
SVSim.UnitTests BattleNode green. The 2 SessionEngine capture-replay shadow
tests are marked Ignore (superseded): they passed VACUOUSLY when the receive
path resolved nothing; with resolution live they hit the documented
capture-replay draw-misalignment artifact. Node-native battles are the oracle.
Drift: no drift.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Full single-client capture replay (cl1 send=player seat, receive=opponent seat,
ts-ordered) ingests end-to-end: 33 frames, 0 rejects, 0 invariant violations at
turn boundaries (leader life/PP/board/hand).
Headless gaps filled per playbook (no Engine/ drift):
- IsRecovery=true after construction: the engine's own headless replay mode gates
the live view/UI layer off (BattleUIContainer, turn-control UI, VFX waits) while
keeping the live NetworkBattleReceiver (ND4) and authoritative state.
- Seed ToolboxGame.RealTimeNetworkAgent, BattleUIContainer, _backGround, and
per-player NullPlayerEmotion no-ops the receive/turn cycle dereferences.
- _IfaceImpl.g.cs (shim, not Engine/): BattleCardView.BattleCardIconAnimations
returns a lazy non-null no-op so the opponent card-reveal icon-init (deferred
VFX) doesn't NRE.
- HeadlessCardMaster.Load made cumulative: it replaced the global CardMaster each
call, so a Load(deck) evicted the oracle card set and broke tests run after.
Adds board-state accessors (LeaderLife/Pp/HandCount/BoardCount) and CaptureReplay
ts ordering.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Proves the deck->hand transfer dimension (design §5 draw oracle) — the last
deterministic, non-RNG card-effect class no prior milestone touched (M3/M4/M6/M8
moved stats, M2/M5/M7 the board, M3 the leader).
Card 800114010 (clan-1 ELF cost-1 when_play draw 1 from own deck, ungated, no
evo/preprocess). The resume-guide's skill_target=none/no-RNG shape does not exist
in cards.json — EVERY draw selects from the deck via a random_count filter
(skill_option is always literally 'none'). RNG neutralized structurally: seed the
deck with EXACTLY ONE known card so random_count=1 is deterministic regardless of
seed. New primitive HeadlessEngineEnv.SeedDeck (create via the null-view seam +
engine AddToDeck). Oracle DrawSpellOracleTests asserts: seeded card moves deck->hand
(by id + by reference), deck -1, drawn card IsInHand, spell pays cost + leaves hand
+ resolves to cemetery, board/opponent untouched. Load-bearing confirmed the M7 way
(seed a different id -> the by-id assertion fails).
Shim gap fixed (the predicted M9 cost): Skill_draw's BattleLog tail
(UpdateFusionedCardSkillDrewCard, unguarded; + the IsBattleLog AddLogSkillDrawCard
calls) dereferences BattleLogManager.GetInstance(), an M1 'default!' null singleton
-> NRE after the draw already committed. One-line HEADLESS-FIX (M9) in
BattleLogManager.g.cs returns the existing _instance singleton (all its methods are
no-ops), per the M2/M7 Null*-singleton playbook. No Engine/ edit (drift clean).
9/9 green; check_drift.py clean; engine still 0 Error(s).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First proof that follower DEATH / board-removal commits in the authoritative
part of PlayCard headless (not the cosmetic post-Process tail). Card 800144120
(cost-0 when_play destroy of a select_count=1 enemy follower) resolves via the
M6 selectedCards path: selected enemy follower removed (board -1 + cemetery +1),
un-selected untouched (routing confirmed load-bearing by swapping the selection).
Shim gap fixed (the predicted M7 cost): SkillProcessor.SelectCardToHaveDestroyVoicePlay's
cosmetic death-voice tail NRE'd on three M1 default!/Null* shadows
(IBattleCardView.VoiceInfo, CardVoiceInfoCache.GetCardVoiceInfoForBattle,
ReadOnlyVoiceInfo.GetDestroyVoice — the last unusable as the interface since
m1_stub_gen dropped its : IReadOnlyVoiceInfo base). Fix = one hand shim
HeadlessVoiceInfo : IReadOnlyVoiceInfo returning the engine's own
VoiceAndWaitTime._nullVoice sentinel, wired into the two generated seams with
// HEADLESS-FIX markers. No Engine/ edit (drift clean).
dotnet test SVSim.BattleEngine.Tests -> 7/7 green; check_drift.py clean; engine 0 Error(s).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Card 800134010 (clan-1 cost-1 ungated spell, summon_token=100011020): a when_play
summon places one new neutral 2/2 follower token on the caster board. New oracle
dimension = board-count + token-identity delta from a SKILL-CREATED card. 5/5 green;
engine 0 errors; check_drift clean; zero new Engine copies.
This is the first headless run of the PUBLIC prefab card-creation path
(CardCreatorBase.CreateCard, createNullView:false) — engine-internal card creation
(summon/draw/token) has no null-view path in solo mode, unlike the M2-M4 hand-card
seam. Built that path headless:
- Self-consistent no-op Unity object graph (UnityShim.cs): Component.gameObject/
transform, GameObject.transform, Transform.parent/Find now lazily non-null +
cached; GetComponent routed through the GameObject component model.
- Targeted NGUI material backing-field wiring (UIFont.mMat / UILabel.mMaterial) so
the copied material getters return non-null via their simple branch (blanket/deep
wiring would make them delegate down a re-nulling chain).
- getUIBase_CardManager() default! -> field-wired no-op via new ShimView.Create<T>().
- Test-side seeds: SBattleLoad card templates + 3D scene GameObjects (InitCardTemplates).
Load-bearing proof: swapping to the M3 non-summoning spell fails the board-count
(Expected 2, was 1) + token-not-found assertions; reverted to green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Card 900124030 (ELF cost-3, when_play damage=3 to enemy leader) resolves to
correct authoritative state headless via the IsForecast/IsRecovery +
ActionProcessor.PlayCard path. New oracle dimension (opponent leader-life delta)
passes; 3/3 tests green; engine still 0 errors; check_drift clean.
Four headless gaps, each mechanical (no logic/Unity wall):
- Data seam: InitLeaderLife (SetupInitialGameState->InitializeClassLife subset);
leader BaseMaxLife was 0 => game-over => play silently rejected. M2 missed it
(only asserted leader life unchanged: 0==0).
- Runtime cast: re-attach IClassBattleCardView on the generated
NullClassBattleCardView stub (members already present; base-clause recovery
stripped the decl). Compiled fine -> M1 loop never surfaced it.
- M1 mis-cut: copy NullVfxWithLoading verbatim (its GetInstance() lazy singleton
was stubbed to default!/null). Same pattern as M2 NullCardVfxCreator.
- Card events: CreateHeadlessHandCard now calls SetupCardEvent so a spell's
OnPlay->RemoveSpellCardFromHand / OnFinishWhenPlaySkill->AddSpellCardToCemetery
fire (the bare CreateCardWithoutResources seam skips them).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First green: a zero-skill vanilla follower (100011010, neutral 1/2) resolves to
correct authoritative state HEADLESS via IsForecast/IsRecovery + ActionProcessor.
PlayCard (DP4), no Unity runtime. §5 oracle passes (PP-cost; hand->in-play;
atk/health == CardCSVData base; opponent unchanged; no exception). VERDICT: the
port approach is validated through the resolution path, not just M1's compile path.
VanillaFollowerOracleTests.Vanilla_follower_resolves_to_correct_state — GREEN.
HeadlessCardMaster now loads the follower's real id from cards.json.
Resolution-path shim/engine gaps closed (all mechanical no-op fills or data seams,
never a Unity/logic wall):
- M1 mis-cut copies (DP1/DP3 — pure no-op logic wrongly stubbed to null):
Engine/Wizard.Battle.View.Vfx/NullCardVfxCreator.cs (its GetInstance() singleton
was nulled) + its dep NotEmptyNullVfx.cs. Deleted the generated NullCardVfxCreator
stub + its _IfaceImpl block; both manifested, check_drift clean.
- _IfaceImpl explicit-impl shadow: interface-typed view/mgr calls dispatch to the
explicit impls (which returned default!), shadowing public stubs. Fixed
IBattlePlayerView.GetSideLogControl (SkillProcessor side-log tail) to return a
non-null no-op. KEY M3+ learning: fix _IfaceImpl.g.cs for interface-typed NREs.
(GameMgr/component-model/Resources/IClassBattleCardView shim fills + CardIconControl
copy + the SVSim.BattleEngine.Tests project landed in the prior commit 2b50657.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First green of the M2 go/no-go probe: `new SingleBattleMgr(StandardBattleMgr-
ContentsCreator)` now builds the two-player pair fully headless against the shim,
no Unity runtime. Verdict: headless construction is feasible; every blocker was a
mechanical no-op shim fill or data seam, not a Unity/logic wall.
Shim fills (authored):
- GameMgr: lazy non-null DataMgr/PrefabMgr/InputMgr/SoundMgr/BattleControl.
- GameObject: lazy cached component model so GetComponent<T>/AddComponent<T> return
non-null no-op instances for Component-derived T (F1: unguarded view touches).
- Resources.Load(string): cached non-null GameObject so the prefab->Instantiate->
GetComponent chain (UnityEventAgent) yields a real object.
- ClassBattleCardViewBase: re-attach dropped IClassBattleCardView (no-op members);
ClassBattleCardBase.Setup casts the created view to it.
Engine copy (DP1/DP3 mis-cut fix):
- CardIconControl.cs copied verbatim (manifested) + generated null-stub deleted.
SplitAndCompleteIconStr is pure string logic on the resolution path that M1 had
wrongly stubbed as "View" -> null deref in SkillCreator.CreateBuildInfo.
Test harness (SVSim.BattleEngine.Tests, authored fixture):
- HeadlessContentsCreator/HeadlessPhaseCreator: deterministic replica of the solo
practice init (StandardBattleMgrContentsCreator + SingleBattlePhaseCreator) with
no-op recovery/replay managers.
- HeadlessCardMaster: reflects the loader cards.json dump into CardMaster.
- HeadlessMasterData: minimal Data.Master (class-character list, empty collections)
+ Data.Load + player/enemy chara ids.
- ConstructionProbeTests.SingleBattleMgr_constructs_headless — GREEN.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Final three clusters:
- RoomParamKey: copy Wizard.RoomMatch/RoomParamKey.cs verbatim (UriNames/WatchUriNames
static dicts keyed by PlayerController.ROOM_URI + PlayerControllerForWatching.
SEND_PARAMETER — both now real enums).
- CardChooseTask: copy the TwoPick/CardChooseTask.cs (TaskManager `using`s .Arena.TwoPick,
not .Competition — copy_loop had only landed the Competition twin).
- SetCardNumLabel CS1739: decompiler param-name artifact — the local fn's 3rd param was
recovered as `flag` but call sites pass it named `isRed:`. First DP5 tracked patch:
Engine/UICardList.cs edited (flag->isRed, zero logic change), recorded in
Patches/ + manifest patched=1 (drift-clean).
M1 exit criteria met: `dotnet build SVSim.BattleEngine` = 0 errors, no Unity ref in csproj,
check_drift clean. Session 7: 198 -> 0 across waves 7a-7k.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Material.SetVector(int nameID, Vector4); Plane(Vector3, float d) ctor; Socket.On
(SocketIOEventTypes, callback) overload.
- Global GetValueOrDefault(this IDictionary<,>) extension — the BCL form only binds to
IReadOnlyDictionary, so the IDictionary call mis-resolved to JsonDataExtension.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- VFX: SequentialVfxPlayer.GetAllVfxAsList, ParallelVfxPlayer.GetVfxList,
VfxMgr.CheckAndAddEffectVfxList; point our own ShowBattleUIImmediatelyVfx stub at
NullVfx.GetInstance() (it called a non-existent NullVfx.Create).
- Static factories: SkillTargetSelectTouchProcessor.Create (10-arg),
DialogReportToManagement.Create(long).
- Re-add StartSkillSelectVfx.OnStart event (m1_stub_gen drops `event` decls — the
recurring session-6 gap; generator event-capture fix still pending).
- Stop the BattleCardView/GameObjMgr ctor cascade: parameterless ctors on the no-op
BattleCardView and GameObjMgr hand shims so non-chaining subclass/field stubs satisfy
their implicit base() call.
- Copy Cute/ListExtensions.cs (FisherYatesShuffle extension) verbatim into Engine.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add the (JsonData) ctor to the LoginBonus data hand stubs (Continuous/Normal/
Special/FreeCardPackBox) and StoryRecoveryData (LitJson.JsonData is copied).
- Full-surface the two nested View types that only the parent's empty stub covered:
BattleCardView.BuildInfo (14-arg ctor) and DestroyVfx.FileNamePair (ctors +
ObjectFileName/SeFileName); add BattleCardView(BuildInfo) to the hand shim.
- Regenerate Field/Spell/UnitBattleCardView: stale stubs whose ctors had dropped the
decomp `: base(buildInfo)` chain, exposed (CS7036) once BattleCardView lost its
implicit default ctor.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Generate both SelectionProcessing Parameter classes namespace-aware (full-surface
captures the 8-arg Main / 6-arg BattleResult ctors); drop the empty hand stubs.
- Add the missing decomp ctors to the 5 empty Touch-processor hand stubs
(SetCard/EvolutionSimple/Emotion/ClassBuff/DetailPanel) — compile-only ballast,
empty bodies.
- Regenerate FusionWaitProcessor.g.cs: it was a stale stub whose ctor had dropped
its decomp `: base(...)` initializer; harmless while SetCardProcessor had an
implicit default ctor, exposed (CS7036) once the parameterized ctor landed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate the Main-namespace versions of the four colliding SelectionProcessing
dialog classes (ChapterCharaDecider/DownloadInfoGetter/DeckSelectionDialogDisplay/
DeckSelectionConfirmDialogDisplay) via the new --ns path — AreaSelectUI uses the
Main module and constructs them into an IProcessing[]. baseclauses binds each to
Main.ProcessingBase; iface_reattach (regenerated full) attaches Main.IProcessing.
Also fill IReplayRecordManager with its 3 real members (SetupRecording/
SetupBattleInfoFilter/SetupOperateMgrEvents); both implementors already had them.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Story chapter-selection processing subsystem is duplicated across two
namespaces (…SelectionProcessing.Main and .BattleResult), each with its own
ProcessingBase : IProcessing + Parameter. m1_genstub keyed output by bare type
name, so only ONE ProcessingBase.g.cs was emitted (BattleResult), and
m1_baseclauses cross-qualified the Main leaves to BattleResult.ProcessingBase —
making it impossible to give IProcessing its real members (Execute(Main.Parameter)
≠ inherited Execute(BattleResult.Parameter) → CS0535).
Now both ProcessingBase variants are generated via the namespace-aware tooling
(<Type>__<Namespace>.g.cs), baseclauses resolves each leaf to its same-namespace
ProcessingBase, and both IProcessing interfaces carry NextProcessing + Execute.
8 IProcessing CS1061 cleared, no CS0535 introduced.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
base-clause recovery strips interfaces (to dodge CS0535), but copied code converts
the stubs to those interfaces -> ~120 CS0266/CS1503. Two mechanisms:
- _IfaceImpl.g.cs: explicit no-op impls of the FULL (copied) interfaces, layered
onto each hierarchy base (BattleCardView/CardVfxCreatorBase/BattlePlayerView/
BattleEnemyView/ClassInfomationUIBase + NullCardVfxCreator). Explicit form never
collides with existing members; leaves inherit. Walks base-interface chains
(IPlayerView : IBattlePlayerView) and emits events.
- _InterfaceReattach.g.cs: plain ': IFoo' for the empty stub interfaces
(IProcessing, IReplayRecordManager).
- ClassBattleCardViewBase/NullBattleCardView: restore dropped BattleCardView base
so they inherit its IBattleCardView impl.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- VfxWith<T> ctor params were swapped ((T,VfxBase) vs decomp (VfxBase,T)) -> ~38
CS1503 across SkillCollectionBase/BattleCardBase skill-processing (ProcessInfo
<-> VfxBase). These are on the resolution path. Fixed to match decomp.
- UnityEngine primitives: implicit Vector3/Vector2<->Vector4 + Color->Color32
conversions; Transform.Translate/Rotate(Vector3,Space) overloads (iTween).
- ITouchProcessor was dropped from touch-processor stubs by base-clause recovery;
re-attach via Shim/View/TouchProcessorIfaces.cs (interface-only for generated
full-surface stubs, interface+no-op members for the empty hand stubs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Regenerate 31 VFX/View/UI/Touch stubs to keep their decomp ': base(...)' /
': this(...)' ctor initializers (m1_stub_gen was dropping them -> CS7036/CS1729
when the copied base has no parameterless ctor). Whole base-ctor cluster cleared.
- UnityEngine.Event: add rawType/keyCode/modifiers/Use() + EventType enum (NGUI
UIInput/UIInputOnGUI legacy IMGUI path).
- Reward: copy the real Wizard.Scripts.Network.Data.TaskData.Arena.Reward verbatim
(was an empty ambiguous-name shim in LooseEnds); deps (UserGoods/JsonData) present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BestHTTP.SocketIO: Socket.On/Off/Emit + SocketIOCallback delegate, SocketManager ctors/
State/Socket/indexer/Open/Close/SettingRealtimeNetworkAgent, SocketOptions. Spine: Skeleton
(Data/Skin/Scale/FindBone/SetSkin/Update), Bone (WorldX/Y/RotationX), SkeletonMecanim
(MonoBehaviour + skeleton). All minimal hand shims (no full-surface -> no SDK closure pull);
node-socket path is Phase-2, off the battle path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the minimal hand shims partial + generate full member surface for the manager/
task/controller god-objects (LoadingViewManager/DeckUpdateTask/MyPageTask/ReplayController/
PlayerControllerForWatching/WatchDataHandler/EvolutionTouchProcessor/StoryChapterSelection
Utility/NonDialogPopup). NonDialogPopup given MonoBehaviour base + hand Close() removed
(superseded by full surface). LoadTask dup deleted (already copied verbatim). RoomMatch
watch/replay closure types stubbed. Copied 8 more closure files.
CS0246-in-generated-signature masking note: 4 such errors were hiding ~1582 — generated
CS0246 masks as hard as header CS0246; the real frontier is 1586 (CS7036 base-ctor +
member-level), 0 structural.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The hand-shim VFX containers only had no-arg Create(); the engine calls them with
collection/params/loading-main args (510 CS1501). Add the real decomp Create overloads
to SequentialVfxPlayer/ParallelVfxPlayer/VfxWithLoading/VfxWithLoadingSequential.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The stub generator emits net-new types as base-LESS partials, so generated Vfx/View
types weren't actually VfxBase/etc. -> hundreds of CS1503/CS0029 'cannot convert to
VfxBase' at every polymorphic call site. m1_baseclauses.py recovers each generated
type's decomp base CLASS (interfaces dropped to avoid CS0535) into _BaseClauses.g.cs,
cross-namespace bases fully qualified. Generated the intermediate Vfx/processing base
types (SpreadOutVfx/OpenCardVfx/ProcessingBase/DamageVfxBase/ForecastIconVfxBase/...).
DefaultOpeningVfx regenerated WITH override (its base OpeningVfx is copied+abstract).
Clearing the polymorphism cascade + the masking base-type CS0246s unmasked the true
member-level frontier: 2202 (CS1501/CS1061/CS1503), 0 structural errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend the UnityEngine value/component shims with no-op members surfaced by the compile
loop (UnityWebRequest/Font/Mesh/LODGroup/AudioSource/Rigidbody/Camera/Sprite/Animation/
Transform/Material/Texture2D/Light/Input/Resources + CharacterInfo/Vector4), via partial
declarations + UnityShimExt.cs. Add the missing UnityEngine static classes (PlayerPrefs/
Physics/GUI/SystemInfo/Graphics/QualitySettings/StackTraceUtility) + enums (TextureFormat/
ColorSpace/EventModifiers/RenderTextureReadWrite) + Experimental.Rendering.GraphicsFormat*
in UnityStatics.cs. All cosmetic, off the battle path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hand-model the CRI ADX2 (audio) + CRI Mana (movie) SDK surface exercised by the copied
audio/movie engine files (AudioManager/Voice/Se/Effect/MoviePlayer). No decomp source
exists; signatures mirror the real CRI API as called at the sites (arg counts/types from
the call sites). All no-op, cosmetic, off the battle path. Reconciled with the empty CRI
stubs already in SdkStubs (CriAtomExAcb/CriAtomExPlayback/CriManaMovieMaterial).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate no-op shells for the entire stop-listed View/Vfx/UI/Touch/Story missing-
type closure (~180 types) + 5 copyable engine files. Net-new shells emitted base-less,
so override members are stripped via the new --no-override generator flag. SDK/BCL
over-reach (Adjust/GZipStream/Socket*) and non-battle Story-world clusters reduced to
minimal/empty stubs instead of full-surface. Nested-type closure (BuildInfo/BattleDialog/
ROOM_URI/FuncGetCantAttackText) placed top-level in their decomp namespaces.
Clearing the last View CS0115 unmasked the true member-level frontier: 3916 errors,
0 generated/structural errors, now dominated by Unity-type + god-object members.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add no-op members + supporting types (FilterMode/TextureWrapMode/WrapMode/Keyframe/
AnimatorStateInfo/AnimatorClipInfo) to the UnityEngine shim. Standard Unity API surface,
inferred from frontier member names — Unity types aren't in the decomp so they're
hand-extended, not generated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate the COMPLETE decomp member surface (not frontier-subset, which silently drops
already-provided members) for UIManager(+ViewScene/ChangeViewSceneParam), GameObjMgr,
BattleLogManager/Item, InPlayCardFrameEffectControl. UIManager/Footer base fixes:
UIManager is MonoBehaviour (singleton kept by hand via --exclude); Footer is the copied
Engine type (removed the conflicting global shim). Add HUDMode enum, Wizard manager
return-type stubs, and a closure-stubs file for 7 referenced empties.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stub-generate BattleLogManager(45)/BattleLogItem(17)/InPlayCardFrameEffectControl(4)
member surfaces from decomp signatures; declare BattleLogWindow+nested enum; make
BattleLogItem a MonoBehaviour so inherited gameObject/transform resolve.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clears the last type+header frontier (RoomInviteFriendColum override). Per F3 this
unmasks the remaining View/UI/god-object member bodies (~8k) -- the next grind is
pure member-surface growth, closure (~3242 files) now essentially complete.