Update 2.224
8/6/2026
v2.224.0.0BETAMINOR
SeymourAug 2, 2026
OPERATION DEMON WAVE 1+2: F8 DASHBOARD RESTORED + F7/F8 KEY ARBITRATION
- F8 dashboard restored (source already in tree; wire was missing):
StartInGameMenuDashboard()+StartUnXBoosterHook()inInstallHooks(gate[dashboard] enableddefault ON — added tokDefaultIniin Config.cpp);InGameMenuDashboard.cpp/UnXBoosterHook.cpp/Config.cppre-added to vcxproj (Config.cpp was never in the project — thedashboard.enabledgate was never read). - Key arbitration (Wave 2): with
dashboard.enabled, F8/INSERT belong to the DASHBOARD (single owner);InGameMenuProcessKeyconsumes F8/INSERT without toggling (fallback with dashboard off). F7 (NativeMenu/F7_LeverApply) UNTOUCHED. - Legacy UnX REMOVED from deploy (INC-002 — proven 3/3 crash):
unx.dll/dxgi.dll/dxgi.ini/dxgi.dll.055508/dinput8 - Copia.dllmoved tomodules\_unx_legacy_removed_20260802_*(reversible backup) in Steam AND_isolated. - New defines in ffx_addresses.h:
RVA_FFX_DEBUG_FLAGS(0xD2A8F8),RVA_FFX_PERMANENT_SENSOR,RVA_FFX_BATTLE_PARTICIPATION/RVA_FFX_AP_EARN(0x1F10EA0/0x1F10EC4 from UnX). Playable Seymour OFF (party struct address not validated — pending RE; apply removed from booster). - Hooks-EN rule applied to dashboard: "F8 close", "On/Off", "Open/Closed"; dashboard
Log→DashLog(OutputDebugStringA — dllmain'sLogis static). - ffx-hooks.ini model created at
RuntimeTools/FfxHooksDll/ffx-hooks.ini(with[dashboard] enabled=1). - Gate: Release build 0 errors; dashboard strings in binary (4/4); Steam +
_isolateddeploy (backups.bak_20260802_184354). RT2 pending: F8 opens dashboard, F7 intact, dashboard cheats work. ### MINOR
v2.223.1.0
v2.224.0.1BETAPATCH
SeymourAug 2, 2026
OPERATION DEMON WAVE 3: DIALOG SKIP ported safely (hook, not patch)
DialogSkipHook.{h,cpp}(new): safe port of the UnX legacy hardcodedret 8patch (RVA 0x30B040 —FFX_FmodVoice_ReadEventData@ 0x70B040, __thiscall validated in IDA): MinHook/PolyHook2 on target; withinput.dialog_skip=1returns 0 immediately (same effect as the ret 8, REVERSIBLE and config-gated).- Dashboard:
Dialog Skip (voices)item in the Input tab (input.dialog_skip, default off). - Wire:
InstallDialogSkipHook(g_base, LogLine)in InstallHooks (inside the dashboard gate). - Define:
RVA_FFX_FMODVOICE_READ_EVENT_DATA(0x30B040) in ffx_addresses.h. - Gate: Release build 0 errors; strings in binary; Steam +
_isolateddeploy (backup185543). RT2: with the item ON, spoken dialogs skip (no crash); OFF = vanilla behavior. ### MINOR
v2.224.0.0
v2.224.0.2BETAREVISION
SeymourAug 2, 2026
OPERATION DEMON: Wave 4 documentation close + RT2 script
run_f8_rt2.ps1(new): boot smoke + F8 checks (dashboard/F7/cheats/dialog skip) — requires closed editor, throwaway save, before/after hashes.F8_UNX_INCONSISTENCY_REGISTER(session 3): INC-002/005 + P1/P2/P5/P7 RESOLVED; P3 partial (v2.flag already absent); never-port recorded (KillMeNow/auto-update/texture inject/sig-scan).- SESSION_HANDOFF + PORT_STATUS: F8
Needs Testing— in-game RT2 pending user (editor closed). - Cleanup:
ingame_menu_v2.flagalready absent from deploy (P3 confirmed clean). ### PATCH
v2.224.0.1
v2.224.0.3BETAREVISION
SeymourAug 2, 2026
OPERATION DEMON: post-F8 plan — Tier 2 via ffx-probe (§9) + RT2 check
- F7F8_RECONCILIATION_PLAN §9: with UnX out of deploy, vtable[9] (GetDeviceState) returns to ffx-probe.dll — the in-process main-thread probe (FORCEBATTLE/SETINPUT/SOUNDCMD/READ/WRITE/CALL — Tier 2: a_ability/arms_rate/Encounter Table/IA/Aurora calibration). Current state: OFF in deploy (
.RT2OFF); loader present; dashboard already hasplugins.ffx_probeitem. run_f8_rt2.ps1: probe heartbeat check (hooked=1) when the probe is active.- Gate: doc-only (REVISION); deploy untouched. ### REVISION
v2.224.0.2
v2.224.0.3BETAREVISION
SeymourAug 2, 2026
PPP DISPATCH TABLE: CYCLE CLOSED (consumer + main table)
- Consumer PROVEN:
FFX_MagicHost_RelocatePppSection(0x7121D0) —a2 + 40*index(stride 40 = 0x28 in code); callers pass&pppSysProgTbl(0x72a8eapush offset pppSysProgTbl→ 0xC3A500; 0x761b72). The on-diskhandler_table_indexof each slot becomes the table entry pointer; runtime slot = 16B ([0]=index, [1]/[2]=relocated ptrs; count at*(int16*)(record+0x26)) — matches the pppSclMove T3 window. - pppSysProgTbl @0xC3A500 = the MAIN table — "progtbl" layout (name@+0x00, fnMain@+0x08, fnExtra@+0x20), 418 entries (matches the 2026-07-31 MAGIC doc); slots 0-11 = pppAccele..pppColor with the Yonishi ranking handlers (pppSclMove T3 = 0x75C090 @ slot 6; pppScale = 0x75D0D0 @ slot 10; pppAngle = 0x75CF20 @ slot 9; pppSclAccele = 0x75B9F0 @ slot 2).
- Correction from the previous pass: 0xC3A500 is NOT a name vector (the 0xC3A4E0 block = debug strings END/CHR/MAP-G/MAT;
FFX_PppNameVectorrename REVERTED). - 2026-07-31 MAGIC renames propagated TO THE CANONICAL DB: 0x716D20→FFX_Render_PppProgramProcessor_2, 0x75B830→FFX_PppHandler_Accele, 0x75B900→FFX_PppHandler_Accele_SetFromGlobalQ, 0xC3E798→FFX_PppHostDispatchTable_AltQ, 0xC86080→FFX_PppKeyholeDispatchTable.
- Extractor gained the progtbl layout + the main table: 5 tables, 1191 handlers in
scripts/ppp_dispatch_table.json. Doc:docs/reverse/PPP_DISPATCH_TABLE_RECONCILED_2026-08-02.md(2nd pass). - C2 with the full chain: on-disk index → pppSysProgTbl + 40*index → entry (name+fn). Next: the 16B disk→runtime slot window (T3) and the 145 aliases. ### PATCH
v2.224.0.2
v2.224.0.4BETAPATCH
SeymourAug 2, 2026
F8 DISABLED (gate `dashboard.enabled=false`) + consolidated F8+probe doc
- Gate flip in 2 spots (Config.cpp kDefaultIni + dllmain
GetBool×2) — dashboard/booster/DialogSkipHook don't start; InGameMenu becomes F8/INSERT owner again (natural fallback). Reversible (reactivate = flip + deploy). docs/reverse/FFX_F8_PROBE_CONSOLIDADO_2026-08-02.md(new): F8 (Waves 1-3 + close) + ffx-probe (Tier 2) + how to reactivate + pending items.- Steam +
_isolateddeploy (backup191908); Release build 0 errors. Focus back to F7. ### REVISION
v2.224.0.3
v2.224.0.5BETAPATCH
SeymourAug 2, 2026
F7: FLICKER FIXED (root cause in lever wire) + no raw stepper numbers + REAL Difficulty lever
- FLICKER (user RT2 — root cause with log evidence): confirming a row closed the menu (
CloseMenu→m.obj=0) BUTg_forceSubsystemstayed ON — game stuck in menu mode (0x13407E4=1) with no menu drawn = alternating render = flickering screen (log:open→ confirm →close (force-gate off)only on 2nd F7 →open...). Fix: the wire now clearsg_forceSubsystemon confirm (same behavior asg_nativeWantClose). - F7 toggle debounce (250ms) in PresentTick — holding F7 (or stuck key) toggled the menu every edge = flicker.
- "Number where it shouldn't be": RT_STEPPER rows showed raw
[0]before editing. Fix:g_rowEdited[]— stepper value only appears AFTER L/R (toggle [ON]/[OFF] stays always visible). - REAL Difficulty lever (was a stub): new
F7_SetDifficultyLevel(0..5)(F7InLive) — setsg_cfg.diffGlobal(hpMul 1000/1150/1300/1500/1750/2000 — x1.00..x2.00) +F7_SaveConfig()— the battle-start auto-apply picks it up. - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup193746). RT2 pending: F7 → confirm → menu closes WITHOUT flicker; no initial [0]; Difficulty applies in battle.
v2.224.1.0
v2.224.1.0BETAPATCH
SeymourAug 2, 2026
F3.5 PART 2: DRAG GIZMO in Aurora (drag the monster on the canvas) + RE: T3 window proven + aliases decoded
- Gizmo in noclip (
scenes.ts,?edit=1): click selects the nearest actor (projection picking —clipFromWorldMatrix+ w-divide), drag on the ground plane (unproject on the actor's y-plane, FFX↔noclip conversion via matrix inverse), overlay (yellow ring + instructions), keys S = save (POST/api/edits/<encId>— the hub endpoint — with the slot delta) and R = reset (back to vanilla). Per-slot vanilla base stored insetUpMonsters(correct deltas even with a previous sidecar). - ViewerShell: "Gizmo 3D (arrastar no canvas)" checkbox in the edit panel +
&edit=1/0in the battle-preview URL + status showing the gizmo state. - RE (3rd pass): 16B T3 window PROVEN in the pppSclMove handler (0x75C090 =
FieldMap_AccumulateDoubleLayerDelta_C): reads the 4 floats ata2+16..+28(the T3record+0x10..+0x1Fwindow) and accumulates intoa1+160..+172. Aliases decoded: the 418 pppSysProgTbl entries = 273 unique names + 145 re-registrations (the MAGIC doc's "145 aliases" = repeated handlers, not alternative names); the extractor gainedfind_all_strings(368 strings in the region) + theisAliasfield. - Gate: noclip typecheck clean;
rsbuildOK; bundle461.7bf8f17f.jsdeployed to the serve-dir (containseditUpdate+ POST); C# build 0 errors; ViewerHub tests 17/17 PASS. - F3.5 COMPLETE: sidecar (part 1) + gizmo (part 2) — the edit → see → save → reopen cycle is closed. ### REVISION
v2.224.1.0
v2.224.1.2BETAPATCH
SeymourAug 2, 2026
F7 RT2 ROUND 2: "NOTHING OPENS" FIXED (the wire was stealing the confirm) + Force Battle no number + clear cheat label + submenus unlock music
- BUG 4 (critical — NO MENU OPENS): my PumpHook wire consumed
g_ourClosedBEFORE the original pump —PollMenunever saw the confirm → submenus NEVER opened. Definitive fix: the wire was REMOVED — the original pump (CloseMenu →DispatchConfirm→NativeMenu_OnEdge→ submenus/reopen/force-off) runs intact again. - BUG 3 (Force Battle with number): the row was RT_STEPPER (0..250) — now RT_NONE (no value; the FORCE submenu does the job —
F7_MENU_FORCE). - BUG 2 (Battle Cheats confusing): renamed to "Party Invincible (debug)" — the lever (0xD2A8F8+1) is the game's party invincible flag.
- BUG 1 (menu without music): the Music submenu (which Bug 4 prevented from opening) now opens — the user picks the track in the submenu (
F7_MENU_MUSIC). - Lever relocated:
F7_LeverApplyis now called byNativeMenu_OnEdge(ACT_AI_SWAP/ACT_BATTLE_CHEATS cases — direct actions without submenu; val fromg_ourResult). - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup200713). RT2: Arena+ opens, Music/Force/Difficulty submenus open, Party Invincible toggle applies. ### PATCH
v2.224.1.1
v2.224.1.3BETAPATCH
SeymourAug 2, 2026
F7 RT2 ROUND 3: MUSIC TRACK 0 = NONE (silent title screen + CRASH entering battle)
- Bug 1 (title/intro screen without music):
music_lock: 0inf7_inlive.json(saved by the Music submenu) —F7_MusicApplyLockapplied the track 0 override (silence/out of context) at boot. - Bug 2 (Custom Mix CRASHED entering battle):
music_battle: 0—F7_ApplyMusicBattle(battle-start auto-apply) didSetArenaBattleMusicPending(0)→ MusicHook applied track 0 → crash (log: FAULT rva 0x4FB05E right after compose). - Fix: track 0 becomes none in both setters (
F7_SetMusicLock/F7_SetMusicBattleTrack:<= 0 → -1) +f7_inlive.jsoncleaned (music_lock/music_battle= -1). - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup202945). RT2: title screen music back; Custom Mix enters battle without crash. ### PATCH
v2.224.1.2
v2.224.1.4BETAPATCH
SeymourAug 2, 2026
F7 RT2 ROUND 4: PREVIEW feedback + Custom Mix crash INVESTIGATED (UpdateWindowTitle/DrawUITextElement)
- Bug 2 (Preview "does nothing"):
F7_MusicPreviewwith lock-1(none — current config state) returned WITHOUT PLAYING (thetrack < 0guard). Fix: confirming Preview with val<= 0shows the on-screen status "Ajuste a faixa (L/R) antes do Preview"; with a valid val it plays. (The flow: L/R on "Music Lock" → confirm on the stepper = preview — already existed.) - Bug 1 (crash when building the battle — PERSISTS): the FAULT (same RVA
0x4FB05E) mapped in IDA:FFX_System_UpdateWindowTitle(0x4FAE40) →DrawUITextElement(0x640810,void(ctx, text, x, y, slot)— draws the SAVE text in the window title; calleeFFX_Save_SystemSaveGame) — the crash is in the menu 2D ctx ("NoTexture"/ResolveTextureNameForUI). The composed bin is OK (24272 B vs 24080 vanilla — 192 B grow with adjusted header). Isolation pending (user): (a) normal battle without compose → crash? (b) compose with 1 aeon → crash? (c) compose with the menu CLOSED before Launch → crash? - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup205601). ### PATCH
v2.224.1.3
v2.224.1.5BETAPATCH
SeymourAug 2, 2026
F7 RT2 ROUND 5: PREVIEW CRASH FIXED (probe OFF = MMF 0xCD) + "Preview" becomes "Save + Open Custom Mix"
- Preview CRASH (reproduced by user — "Enter on Preview = crash NOW"):
F7_MusicPreviewcalled the soundcmd via probe (ArenaPlus_MusicHookProbeSoundCmd→LabProbeSoundCmd→ MMFFFXProbeBlock_v1) — the probe is OFF in deploy (.RT2OFF) — the MMF exists but the data is the 0xCD pattern (freed/uninitialized memory) →AV READ accessed=0x10CDCDCDinside ffx-hooks. Fix: SEH (__try/__except) inF7_MusicPreview(the soundcmd can never crash the game again — override only) + the track stepper confirm now SAVES (doesn't play). - UX (user request): the Music submenu "Preview" became "Save + Open Custom Mix" — Enter saves the config (f7_inlive.json) + reopens the native menu for Arena+ → Custom Mix (the standard flow that WORKS). The music stays stored in the config (lock/battle) and applies in the right context (battle start), without probe playback.
- Gate: Release build 0 errors; Steam +
_isolateddeploy (backup214436). RT2: Enter on "Save + Open Custom Mix" does NOT crash; config saved; Custom Mix opens. ### PATCH
v2.224.1.4
v2.224.1.6BETAPATCH
SeymourAug 2, 2026
i18n: raw literals migrated to {x:Static} (StringsIntegrityTests gate green)
- F3.5 gizmo debt fixed: the "Gizmo 3D (arrastar no canvas)" checkbox and the hint ("Clique num monstro para selecionar... S = salvar · R = reset") used raw literals in attributes (
Content=/Text=) — theNoXamlHasRawHardcodedUiLiteraltest catches attributes. Migrated to{x:Static res:Strings.U_gizmo_3d_drag_on_canvas_1aa7857f}+U_click_monster_to_select_drag_hint_fe907a09(neutral EN + PT + Strings.cs props). - Another lane's debt (MonsterAi):
MonsterAiPhaseRotationAdvanced_Window.axamlhad 2 raw literals ("Foco ativo" / "Limpar foco") — migrated toU_active_focus_d59334a6/U_clear_focus_91699d35(the test is the project-wide arbiter). - Gate:
StringsIntegrityTests3/3 PASS; build 0 errors.
v2.224.1.5
v2.224.1.7BETAPATCH
SeymourAug 2, 2026
Aurora visualization: monster names in the battle (labels + gizmo)
export const MONSTER_NAMESinmonster_studio.ts(284 real names — "Raldo", "Bunyip"...).- scenes.ts: edit mode (
?edit=1) now draws labels over ALL battle monsters (real name in white; the selected one in yellow) + the gizmo overlay shows the selected monster's name (e.g. "Dark Flan (slot 6)") instead of just "slot N". - Gate: noclip typecheck clean;
rsbuildOK; bundle461.0fe1690d.jsdeployed (contains "Raldo"/"Bunyip"); patch versioned indocs/patches/noclip/(scenes.ts + monster_studio.ts).
v2.224.1.6
v2.224.1.8BETAPATCH
SeymourAug 2, 2026
Aurora: the AURORA CHAMBER is back as the main Aurora (battle preview retired) + i18n PT→EN of the Aurora modules
- Aurora Chamber REACTIVATED as the catalog "Aurora":
MenuItem_AuroraandMenuItem_AuroraChambernow openAuroraChamber_Control(BIANCA catalog + MapViewer + Open RealGame — the real battle). NewOpenAuroraChamber()helper. The battle preview (noclip) becomes legacy code ("aurora" entry disabled in the catalog; the ViewerHub/aurora desc stays frozen). - ModuleCatalogPolicy:
aurora-chamberentry reactivated ("Aurora Chamber");aurora(battle preview) marked 🚫 LEGACY (commented). Addedcase "aurora-chamber"dispatch. - i18n PT→EN of the Aurora modules: the neutral (Strings.resx) had PT values (EN editor showed PT) — fixed to EN: 12 existing keys (AURORA·Battle Maps, Selected place, Visualization, Editing, Session, Open arena in Aurora Chamber, Filter by field..., Selected field, Exports map/..., Field Picker, overworld, MapViewer 3D) + 23 new keys (Chamber and Field Explorer buttons: Re-scan, Mount missing, Remount all, Open EditViewer, Open RealGame, Save positions, Add/Remove monster, Export anchors, Restore RealGame, Reload battle, Re-export and open, Remount scene, Export folder, Save camera, Save camera params, Publish Scout, Update markers, Publish and open field, Validate visual, Open field, Re-export, Browser). EN in neutral + PT in satellite (verified: already there in PT) + Strings.cs props.
- Gate:
StringsIntegrityTests3/3 PASS; build 0 errors.
v2.224.1.7
v2.224.1.9BETAPATCH
SeymourAug 2, 2026
Bugfix: Open RealGame (404) + Aurora map upside down
- Bug 1 — RealGame 404:
Aurora3DLauncher.BuildBattleUrl(used by the Chamber's "Open RealGame") started a legacy python http.server at the noclip root (Downloads) — but the noclip index.html is indist/, so/index.htmlreturned 404 ("page not found"). Fix:BuildBattleUrlnow usesViewerHubService.BuildUrl("aurora", ...)(the in-process StudioWebServer with the noclip serve-dir — the correct index.html). RemovedEnsureViewerServer/IsPortListening(legacy python — retired in F2). The MODULE (RealGame with monsters) keeps working — only the battle-preview PAGE is legacy. - Bug 2 — map upside down:
applyAssetOrientationinRuntimeTools/FFXMapViewerWeb/app.jsappliedrotation.x = Math.PI(π flip on X) forbtlmap(the Aurora Chamber arena) — flipping the map. The map glTF is already Y-up. Fix:rotation.set(0,0,0)(no flip) for all — ground at the bottom, sky at the top. - Gate: build 0 errors;
node --checkOK on app.js; the MapViewer is served directly from the repo (prefix /map/) — the fixed app.js is already served.
v2.224.1.8
v2.224.1.10BETAPATCH
SeymourAug 2, 2026
Bugfix: {x:Static} as element content showed the raw literal (and crashed opening the editor)
- Bug: the 25 buttons of the Aurora modules (Chamber + Field Explorer) that I migrated to i18n used
{x:Static res:Strings.X}as element content (<Button>{x:Static}</Button>). Avalonia does not resolve{x:Static}as element content — it shows the raw literal ("{x:Static res:Strings.U_...}") and may crash at runtime when using the button (the reason the "map crashes opening the editor"). - Fix: converted all 25 to the attribute
Content="{x:Static res:Strings.X}"(the correct pattern).{x:Static}only resolves as an attribute (Content=,Text=,Header=,Watermark=,ToolTip.Tip=). - Gate: build 0 errors;
StringsIntegrityTests3/3 PASS;node --checkOK.
v2.224.1.9
v2.224.1.11BETAPATCH
SeymourAug 3, 2026
F7: glass panel in submenu (single window) + compose CRASH fixed (force-gate before launch)
- Bug 2 (UX — user asked for "a new window"):
F7Sub_DrawCb(dllmain ~11580) got the big glass panel (DrawMenuGlassPanel(NX(0.047f), NY(0.20f), NW(0.906f), NH(0.62f), F, 1)) — the Sound submenu is now a WINDOW (background + title + rows INSIDE), compose-pick style. - Bug 1 (Custom Mix battle-start crash — root cause):
ArenaPlus_LaunchComboBattleFromPump(the MsBattleEncountExe) ran with the force-gate ON (g_forceSubsystem = 0was only AFTER the launch) — the game entered battle with 0x13407E4=1 (menu mode) → the battle start crashed inUpdateWindowTitle→DrawUITextElement(rva 0x4FB05E — AV WRITE 0xBD). Fix:g_forceSubsystem = 0+ 0x13407E4 zeroed DIRECTLY BEFOREArenaPlus_LaunchComboBattleFromPump(Launch + LaunchCached — the relaunch). - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup095551). RT2 pending: Custom Mix → Build + Launch → battle enters WITHOUT crash; Sound submenu = single window. ### INFRA (CI) ci.ymlran the CI on any push tomainandcodexclaudiocodeffxeditor(the working branch where lanes commit constantly) — 2 jobs on Windows runners ($0.010/min) exhausted the free 3,000 min/month quota (Actions $22.70).- Fix: push trigger is now only
main(branches: [main]). CI still validatesmain(and PRs tomain); the working branch gets no automatic CI (validate locally withdotnet build). - Estimated savings: ~90% of Actions runs (cuts the recurring minutes cost). ### PATCH
v2.224.1.10
v2.224.1.12BETAPATCH
SeymourAug 3, 2026
LOG: auto-rotation by open count (max 10, `.old1..old9` history)
OpenLog(dllmain ~173) now counts opens (file%TEMP%\ffx-hooks.log.cnt); every 10th open, moves the current log toffx-hooks.log.oldN(accumulates.old1..old9history;.old1is overwritten after 9 rotations) and resets the counter. The main log no longer accumulates more than ~10 sessions; the user deletes.old*as needed.- Gate: Release build 0 errors; Steam +
_isolateddeploy (backup102648). ### PATCH
v2.224.1.11
v2.224.1.13BETAPATCH
SeymourAug 2, 2026
RealGame fix (battle vs field) + EditViewer always opens + DEBUG LOG general rule (Phases 1-4) + full-editor analysis map (Phase 5)
- RealGame fix (the battle returns):
BuildBattleUrlpassed the extraQuery WITH?toViewerHubService.BuildUrl(which already adds?) → URL becameindex.html??battle=...→ the noclipURLSearchParamsdidn't readbattle→ only the field (map), no battle. Now the extraQuery is without?→?battle=<encId>&map=&actors=1→ the battle with monsters returns. - EditViewer never "does nothing" again: the
RenderScenefallback now opens the empty scene (grid + overlay) even WITHOUT anchors when the glTF export fails (previously required anchors — without them, render returned an error and the button did nothing). The log captures the export reason. - DEBUG LOG — GENERAL RULE (
FFXProjectEditor/Diagnostics/DebugLog.cs): centralInfo/Warn/Errorhelper with[Conditional("DEBUG")](removed in Release — zero overhead). Output: debugger +%LOCALAPPDATA%\FFXProjectEditor\debug.log+work/editor-debug.log. Instrumented: RealGame (generated URL), EditViewer (render), SelectSceneByMapKey (bika00_10), ExportSceneGeometry (failures), ViewerHub (BuildUrl/EnsureServer). - Permanent rule: added to
AGENTS.md+CLAUDE.md— every new module MUST have debug responses. Docs:docs/ai/DEBUG_LOGGING_RULES.md(the rule) +docs/ai/DEBUG_LOGGING_MAP_2026-08-02.md(Phase 5 — full-editor analysis: ~51 modules + infra + boundaries; where/which debug field tables per domain; implementation priority; UI vs log). - i18n gate: 5 raw literals from
MagicDllEditor_Control.axaml(arrows + Back/Forward tooltips — another lane's debt) migrated to{x:Static}(the test is the project-wide arbiter). - Gate: Debug + Release build 0 errors; tests 20/20 PASS (StringsIntegrityTests 3/3 + ViewerHub 17/17).
- The hook captures the lab stdout via pipe (CreatePipe + STARTF_USESTDHANDLES — the compose job reads the output and extracts the PREV| lines) and draws the dots panel in the menu (left glass panel — the layout that will enter the battle).
- New "Build Preview (layout bolinhas)" button in Custom Mix: composes WITHOUT launch (menu stays open — status "Preview pronto — layout acima. Fight Last Mix p/ entrar.") → the user sees the dots BEFORE entering → "Fight Last Mix" (existing) launches the already-composed bin.
- Flow: pick aeons + scenario → Build Preview → see the map (P right / monsters left / cam h) → Fight Last Mix → battle.
- Lab build 0 errors + ffx-hooks (with PolyHook) 1,113,600 B; LabDeploy to Steam (real lab + hooks).
- RT2
Needs Testing: Custom Mix → 4 aeons → Build Preview → check the map on the left panel → Fight Last Mix → battle with the shown layout. ## [Unreleased] ### MINOR
v2.224.1.12
v2.224.1.14BETAPATCH
SeymourAug 2, 2026
DEBUG LOG v2: 3+1 per-area flags + global auto/dev/prod + UI Event Tracer + WebView console bridge + global exception + "Open debug log" menu item
- DebugLog v2 (
FFXProjectEditor/Diagnostics/DebugLog.cs): GLOBAL flag (auto=Debug→dev/Release→prod;FFX_DEBUG_MODE=dev|prodforces) + per-area flags (debug_flags.json:0=OFF,1=ACTIVElogs while the area is being handled,2=ALWAYSlogs on any error,3=FORCEDEBUGlogs EVEN in Release). LOGS ALWAYS IN ENGLISH (outside i18n). 5MB rotation +.old1..old9(aligned with the C++ hook lane). - UI Event Tracer:
Main_Windowintercepts ALL button clicks (AddHandler Button.ClickEvent) and logs automatically with the active module (UiTracer) — no per-click logging needed. - ActiveScope:
SetModuleactivates/deactivates the open module's area (flag 1 uses it). - WebView console bridge:
WebView2Hostinjects a script redirectingconsole.error/warn/logof the hosted JS (noclip/MapViewer) →WebMessageReceived→DebugLog(WebView.Console) — the viewer JS bugs now land in the log. - Global exception:
AppDomain.CurrentDomain.UnhandledException+TaskScheduler.UnobservedTaskException→DebugLog.Error("Global", ...). - Menu: "Open debug log" item in the language selector flyout (opens the debug.log).
- Test:
DebugLogTests(3/3 — EN write, timestamp+area+type format, exception with type). - Docs:
DEBUG_LOGGING_RULES.mdupdated (flag model + EN + tracer + the required manual minimum). - Gate: Debug + Release build 0 errors; tests 23/23 PASS (i18n 3/3 + ViewerHub 17/17 + DebugLog 3/3).
v2.224.1.13
v2.224.1.15BETAPATCH
SeymourAug 3, 2026
Custom Mix battle crash: compose-pick draw disabled DURING compose
- Mechanism (confirmed in IDA): the FAULT (AV WRITE
accessed=0xBD) lands insideDrawUITextElement(0x640810, pc 0x6409A5) — thectx(viaFFX_Menu2D_ResolveCaptureCtxCore) is null/corrupted —UpdateWindowTitle(0x4FAE40) crashes drawing the save text. The crash happens DURING compose (the ArenaMultiBossLab runner), with our menu (compose pick) open. - Fix:
ComposePick_Draw(the compose-pick DrawCb) now returns early wheng_jobState == JOB_RUNNING— our menu does NOT enqueue text into the game's 2D menu during compose (EncodeLabel/DrawStringcorrupted the text pool/cache: cache-hit → pool[cursor-1] no bound check → invalid handle). The menu freezes 1-2s (compose is fast) and returns to normal after. - FIRST WHY COMMENT — this fix already ships with the why-comment (English) in the code.
- Gate: Release build 0 errors; Steam +
_isolateddeploy (backup140132). RT2 pending: Custom Mix → Build + Launch → the compose crash should be gone. ### PATCH
v2.224.1.14
v2.224.1.16BETAREVISION
SeymourAug 3, 2026
WHY-COMMENT RULE for hooks + 1st WHY pass
- New rule (CLAUDE.md): touch a hook → leave the WHY in the code (in English) —
// WHY: ...(the rationale, not the what),// FIX <date>: ...(with the why),// KEY <date>: ...(RE insight). Focus on the non-obvious spots (gate, offset, critical order, pool/ctx collision, architecture decision) — no spam, no basics bible. - 1st WHY pass: dllmain (native-menu confirm flow — why the wire was removed; compose launch — force-gate before MsBattleEncountExe) + ArenaPlusComposePick (ComposePick_Draw disabled during compose — the 2D pool crash).
- Gate: Release build 0 errors (comments don't change behavior); no deploy (REVISION — doc/code-comment). ### PATCH
v2.224.1.15
v2.224.1.18BETAPATCH
LuluAug 3, 2026
Magic DLL Editor: `pppVertexApAt` schema decomposed (4 real fields) + `pppMatrixLoc` cleanup (host-only) + DebugLog in `Magic.Parse`/`Magic.Writer`
- Decomposition (IDA decompile 0x7583D0):
pppVertexApAtnow has 4 editable fields (model_indexu16@+4,vertex_countu8@+6,delay_framesu8@+7,order_modeu8@+8; window{4,5},editable=true). Applied tofield_map.json+MagicFieldMapEmbeddedData.cs. - Honest cleanup:
pppMatrixLoc(decompile 0x734200) operates only on host state (zeroa2/record reads) — the 3param_s32_64/68/72fields were invented offsets → removed,payload_consumer=false,SEM_PAYLOAD(correct). - Not applied (RE finding):
pppKeThRes32/48—a2+12is a resource pointer (chain builder), not a numeric knob; editing as u32 would corrupt the pointer. Documented. - DebugLog v2:
TryLoad(Magic.Parse) +TryGrowRecord(Magic.Writer) instrumented withDebugLog.Info/Warn/Error(English, monolingual). - Gate: Release build 0 errors; MagicDll tests 76/76 + StringsIntegrity 3/3 (79/79).
- The crash (reproduced WITHOUT compose): open F7 + browse the menu (after a preview/battle) → FAULT AV WRITE
pc=0x2409A5accessed=0xBD(the SAME as compose) —UpdateWindowTitle(0x4FAE40) crashes inDrawUITextElementwith the 2D menu pool/ctx corrupted by our menu (drawing MANY texts every frame: cache-hit → pool[cursor-1] no bound check). - Fix (definitive): hook on
FFX_System_UpdateWindowTitle(0x4FAE40) — with our native menu active (F7/submenu/compose pick), the hook returns 0 — the game does NOT draw the title text (cosmetic) and doesn't touch the corrupted pool → no crash. The title resumes updating when the menu closes. - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup144123). RT2: F7 open + leaving battle → no crash. ### REVISION
v2.224.1.17
v2.224.1.19BETAPATCH
SeymourAug 3, 2026
LIVE POSITION EDIT (Part 1): "dot-map" window in the hook (monsters + players)
- The window: in the compose pick (Custom Mix), with Build Preview done, press E → enters the grid edit mode (the 16×8 dot map — each bicho = a
P, the active one =X). - Interaction: arrows move the cursor (the active bicho's
P); TAB switches bicho; ENTER savesmodules\arena_positions.json(each bicho's grid gx/gy); Cancel back. SavePositions/ResolvePositionsPath: the JSON in modules (the 16×8 grid — the compose runner will read it later and apply the C#BattleArenaPositionWriterto the bin — the next-part link).- WHY (in code): the game reads bicho positions from the bin's chunk3 anchors (
pos = bin + chunk3 + 16×a5) — saving the edited grid lets compose apply the custom placement. - Gate: Release build 0 errors; Steam +
_isolateddeploy (backup153130). RT2: E in compose pick (with preview) → the dot window opens; move + ENTER saves the JSON. ### PATCH
v2.224.1.18
v2.224.1.20BETAPATCH
LuluAug 3, 2026
Magic DLL Editor: breadcrumb (back/forward) moved to FORA of the split folder/field — now also appears when you reach a leaf (item/field)
- Before: the back button only appeared in folder view (
IsContainer); when reaching a field/leaf, it disappeared — and you couldn't go back. - Now: the breadcrumb (⬅ back · ➡ forward · path) is displayed always when there is a selection (folder OU leaf), allowing back/forward navigation from any item.
- Gate: Release build 0 errors; StringsIntegrityTests 3/3.
- A window: in the compose pick (the Custom Mix), with Build Preview done, press E → enters grid edit mode (the 16×8 point map — each entity = one
P, the active one =X). - Interaction: arrows move the cursor (the
Pof the active entity); TAB toggles the entity; ENTER saves themodules\arena_positions.json(the grid gx/gy of each entity); Cancel goes back. SavePositions/ResolvePositionsPath: the JSON in modules (the 16×8 grid — the compose runner will read later and apply theBattleArenaPositionWriterC# in the bin — the link for the next part).- WHY (in code): the game reads the entity positions from the chunk3 anchors of the bin (
pos = bin + chunk3 + 16×a5) — saving the edited grid allows the compose to apply the custom positioning. - Gate: Release build 0 errors; deploy Steam +
_isolated(backup153130). RT2: E in the compose pick (with preview) → the points window opens; move + ENTER saves the JSON. ### PATCH
v2.224.1.19
v2.224.1.21BETAPATCH
SeymourAug 3, 2026
live position edit LINK: compose runner applies the custom grid to the bin
BattleComposeRunner(Part 2 of live positioning): newReadCustomPositionsJson(modRoot)(reads thearena_positions.jsonsaved in the hook) +ApplyCustomPositions(...)(converts the 16×8 grid → real X/Z — X ±28, Z 30→46 — and applies viaBattleArenaPositionWriter.WritePositions, preserving Y/W).- In compose: if
arena_positions.jsonexists, the runner uses the custom grid (firstactorCount= monsters in MonsterLive; the rest = party in PartyFront) instead of the camera auto-layout. Log:[custom-positions] grid do hook aplicado em .... - Full flow (Part 1 + 2): compose pick → Build Preview → E → move the
Ps (arrows/TAB) → ENTER saves the JSON → Launch → compose applies the custom grid to the bin → the battle starts with the edited placement. - Gate: lab (C#) build 0 errors; deployed
ArenaMultiBossLab.dllto the game (backup180311). RT2: edit the position in the hook → Launch → the battle with the custom placement. ### PATCH
v2.224.1.20
v2.224.1.26BETAPATCH
LuluAug 3, 2026
Magic DLL Editor: Phase 1 (clone) + Phase 2 (noclip magic override) + Phase 3 (embedded locked 3D preview)
- Phase 1 — Clone button: new
CloneMagicCommand+TryCloneMagic(copies the working bytes with edits to a newmagic_<id>.dll; .bak backup; validated id). "Clone" button in the toolbar. - Phase 2 —
MagicOverrideService: overwritesdata/FinalFantasyX/11/<id>.binin noclip with the custom DLL (vanilla.magic3d.bakbackup; restore). noclip already renders magic viaBIN.parseMagicFile— no deep RE needed. - Phase 3 — Embedded 3D preview: "Preview" button opens the embedded WebView2Host (mini browser) in the editor, locked to the magic being edited (override of
11/<id>.bin+ magic-studio URL). Close button (✕). - Gate: Release build 0 errors; MagicDll 76/76 + StringsIntegrity 3/3.
- Phase A — real type humanization: the field
DetailTextnow shows ONLY the human description (no[u16], offset, width) — the raw type you saw is gone. Read-only notice also in the folder view (non-editable slots like pppDrawMatrix show "Read-only" + reason). - Phase B — mass IDA research (23 handlers decompiled): reclassified 3 SEM_PAYLOAD → FECHADO with real fields:
pppKeLnsLpSft(110 DLLs, 2 lens-shift floats),pppDrawHook(10 DLLs, callback),pppKeAcmCic(mode). Confirmed the rest (KeShpTail*, KeDMat*, Matrix*, DrawMatrixWood) are host-only/stubs (no decomposition) — documented. - Phase C — expanded catalog: +19 human descriptions (total ~94 opcodes) covering the new FECHADO + host-only SEM_PAYLOAD.
- Gate: Release build 0 errors; MagicDll 76/76 + StringsIntegrity 3/3 (79/79).
- Field view redesigned: a field now shows name + human description + readable type (e.g. "decimal (float)") + editable value in a card. Offset and raw type (
u16) hidden — the player doesn't touch them. - Clear read-only: non-editable fields show a highlighted "Read-only" notice + the reason (e.g. "raw data — the editor can't decompose it yet").
- Human description catalog (
MagicPppDescriptionCatalog.cs): ~60 ppp opcodes with what they do in player language (based on IDA decompile + RE docs). Shown in the slot's DetailText. - Grow-size tooltip: explains that 4B/8B/12B/16B = extra bytes of space (1/2/3/4 values).
- Gate: Release build 0 errors; StringsIntegrity 3/3 + MagicDll 76/76 (79/79).
v2.224.1.25
v2.224.1.28BETAREVISION
LuluAug 4, 2026
Magic DLL: Phase 4 ? deep RE of the 3D Preview (noclip layout mapped at source)
- New doc:
docs/reverse/magic_dlls/NOCLIP_PREVIEW_LAYOUT_MAPPING_2026-08-03.md? maps theparseMagicFile?sniffMagic?parseParticleDatapath of noclip.website (real source). - Verdict: field edits confined to the window = SAFE for preview (noclip re-reads the same offsets; fixed strides 0x28/0x10 unchanged); structural grow in the middle of a record noclip strides over = BREAKS preview; safe grow = count-driven list extension at the tail + count bump.
- Clone caveat: noclip only renders ids present in its
magicTable; id outside the table ?sniffMagicnull ? empty emitters (noclip limitation, not the override). - Doc/RE only (REVISION) ? NO behavior change. — CUSTOMMIX MUSIC SOLVED: track 145 "Challenge" playing in battle.** Lane Jarvis-HOOK. [previous:
v2.224.1.26] - The win: after 4 failed routes (
SetArenaBattleMusicPending→ only Arena+ interceptors;PrepBattleTrack→ engine layer, not FMOD;PlayTrackWithPreload→ setevent_indexbut didn't populatetracks_array[].event_ptr),SwitchCrossfade(self, 145, 0, 1)unlocked it — via IDA MCP onffxoficial.exe.i64(FFX.exe pid=49476). - Key discovery (RE, commit
d4fdbc6c): the FFX audio tree has 3 layers —PlayTrackByIndex(0x7097E0) silently skips iftracks_array[track].event_ptr == 0;PlayTrackWithPreload(0x886980) only setsevent_indexin the engine sub-struct;SwitchCrossfade(0x7089F0, path B) is the ONLY one that populatesevent_ptrviaReadEventByRuntimeId→MapRuntimeIdToFevIndex(table0xB4F1C8) →EventSystem->GetEvent. - Checks proving 145 should play:
dword_B4F1C8[145] = 0x48(FEV index 72, valid ≤181);unk_CEC164 = 0(load gate doesn't block);IsValidTrackIndex(145) = true(145 ≤ 0xB5). - Fix in
MusicHook_Shim: on override, callSwitchCrossfade(overrideTrack, 0, 1)(fade=0, load_flag=1) instead ofPlayTrackWithPreload; prefer trampolineg_trampolineSwitch(skips shim, avoids recursion). - RT2 confirmed by user: "NOW TRACK 145 WORKS! I'M IN BATTLE WITH THE NEW MUSIC!" — Challenge plays in CustomMix.
- Gate: Release build 0 errors; deploy Steam +
_isolated; commitd4fdbc6cpushed.
v2.224.1.27
v2.224.1.30BETAPATCH
SeymourAug 5, 2026
CustomMix Gil: battle cost NEVER charged (race condition bug) + compose never overwrites vanilla bins
- CustomMix Gil:
ArenaPlusComposePick_Close()zeroedg_pendingLaunchGilCostBEFORELaunchComboBattleFromPumpcould read it — Gil was validated in the menu but never charged (x3/x4/x5, since compose was implemented). Sum was correct (e.g. 325000G for Trio) butgilCost=0in the log. Fix: moved the zero fromClose()toOpen()(session-open reset, not on close). - Compose overwrote vanilla bins (d5e56701): 5 cross-map scenarios (macalania_forest x3, remiem x3/x4/x5, bikanel x4) deployed to the template bin (
mcfr00_00,kino00_00,bika02_01) instead of the dedicated carrier (mcyt00_22,nagi05_23,nagi05_22) — the engine loaded random encounters instead of the composed team. C#:ResolveOutputBattleIdreturnscarrier.BattleId. C++: hook pin usesroute.battleId(carrier) for the encounter name. Vanilla bins intact. - Deploy: Hook DLL rebuilt + Steam deploy. Gate:
arena_plus_charge_gil.flag(active). - Phase 3 ? embedded id RE: comparing magic_0140 vs magic_0141 (same size, 22 diffs), found the id does NOT exist as u32 LE in .data ? only as 3 UTF-16LE strings ("magic_0140" / "magic_0140.dll") at offsets 0x07E3C6, 0x07E4B2, 0x07E4F2.
- Phase 3 ?
MagicDllNameRewriter: rewrites the 3 strings to the new id inTryCloneMagic(4-digit zero-padded = same length = no offset shift). Validated against the real DLL: 3 occurrences rewritten, size delta = 0 (RT0 byte-faithful outside the strings). - Phase 4 ?
MagicCommandAssociation: associates a command.bin row to the clone by settingAnim1Id = newId(proven chain: command.Anim1Id ? magic_%04d.dll). Field EDIT (not grow) viaAbility_Command.WriteList(preserves text pool). Honest limitation: replaces the original skill's visual effect; a NEW skill (preserving the original) would require grow (reference:CommandGrowWriter.AppendElementWards). - Deploy: LAB build in
FFX\Mods\FFXProjectEditor-v2.224.1.29\. offline_ci: 8 fails (all PhaseManager/battle pre-existing ? NONE from Magic/PPP).
v2.224.1.29
v2.224.1.31BETAPATCH
SeymourAug 6, 2026
F7 Marathon: 6 bugs + CustomMix Ultra + controller
- 6 bugs fixed: black screen on F7 exit (0x13407E4 cleared in all close paths), Challenge music leaking on EVERY battle (F7_ApplyMusicBattle default=145 removed), double-input FSM vs menu (ClaimModal/ReleaseModal in F7 submenus), input spam holding confirm/cancel (cooldown also on cancel), True Nightmare wrong elements (now HP 3x, stats ~2x, Haste+Regen+Protect+Shell, no Weak/Resist/Absorb), Force Battle captured Dark Aeons/Combos (F7_SetSkipForceCapture filter).
- CustomMix Ultra Phase 1+2: Compose engine C# (RunUltra — 1-8 monsters, auto-layout, deploy) + F7 menu integrated (Arena+ → CustomMix Ultra → Build+Launch). Carrier zzzz00_240, token 0x00F000F0. 13 debug logs.
- Controller in ComposePick: L2=edit grid, R2=camera, R1=next, L1=prev via PadDir edge detection + keyboard fallback. PS+Xbox dual labels (L2-LT, R2-RT, L1-LB, R1-RB).
- Deploy: Hook DLL + Lab C# deployed to Steam. Plans: Monster AI Swap, Ultra Phases 3-4.
v2.224.1.30