Atualização 2.224
06/08/2026
v2.224.0.0BETAMINOR
Seymour2 de ago. de 2026
OPERATION DEMON WAVE 1+2: F8 DASHBOARD RESTORED + F7/F8 KEY ARBITRATION
- F8 do dashboard restaurado (fonte já na árvore; o wire faltava):
StartInGameMenuDashboard()+StartUnXBoosterHook()emInstallHooks(gate[dashboard] enableddefault ON — adicionado akDefaultIniem Config.cpp);InGameMenuDashboard.cpp/UnXBoosterHook.cpp/Config.cppre-added para o vcxproj (Config.cpp nunca estava no projeto — o gatedashboard.enablednunca era lido). - Arbitragem de chaves (Wave 2): com
dashboard.enabled, F8/INSERT pertencem ao DASHBOARD (dono único);InGameMenuProcessKeyconsome F8/INSERT sem alternar (fallback com dashboard off). F7 (NativeMenu/F7_LeverApply) INTOCADO. - UnX REMOVED legado removido do deploy (INC-002 — provado 3/3 crash):
unx.dll/dxgi.dll/dxgi.ini/dxgi.dll.055508/dinput8 - Copia.dllmovidos paramodules\_unx_legacy_removed_20260802_*(backup reversível) em AND_isolateddo Steam. - Novos defines em ffx_addresses.h:
RVA_FFX_DEBUG_FLAGS(0xD2A8F8),RVA_FFX_PERMANENT_SENSOR,RVA_FFX_BATTLE_PARTICIPATION/RVA_FFX_AP_EARN(0x1F10EA0/0x1F10EC4 do UnX). Seymour jogável OFF (endereço da struct de party não validado — pendente RE; apply removido do booster). - Regra Hooks-EN aplicada ao dashboard: "F8 close", "On/Off", "Open/Closed"; dashboard
Log→DashLog(OutputDebugStringA — oLogdo dllmain é estático). - Modelo ffx-hooks.ini criado em
RuntimeTools/FfxHooksDll/ffx-hooks.ini(com[dashboard] enabled=1). - Gate: build Release 0 erros; strings do dashboard no binário (4/4); deploy Steam +
_isolated(backups.bak_20260802_184354). RT2 pendente: F8 abre o dashboard, F7 intacto, cheats do dashboard funcionam. ### MINOR
v2.223.1.0
v2.224.0.1BETAPATCH
Seymour2 de ago. de 2026
OPERATION DEMON WAVE 3: DIALOG SKIP portado com segurança (hook, não patch)
DialogSkipHook.{h,cpp}(novo): port seguro do patch hardcodedret 8do UnX legado (RVA 0x30B040 —FFX_FmodVoice_ReadEventData@ 0x70B040, __thiscall validado em IDA): MinHook/PolyHook2 no alvo; cominput.dialog_skip=1retorna 0 imediatamente (mesmo efeito do ret 8, REVERSIBLE e config-gated).- Dashboard: item
Dialog Skip (voices)na aba Input (input.dialog_skip, default off). - Wire:
InstallDialogSkipHook(g_base, LogLine)em InstallHooks (dentro do gate do dashboard). - Define:
RVA_FFX_FMODVOICE_READ_EVENT_DATA(0x30B040) em ffx_addresses.h. - Gate: build Release 0 erros; strings no binário; deploy Steam +
_isolated(backup185543). RT2: com o item ON, diálogos falados pulam (sem crash); OFF = comportamento vanilla. ### MINOR
v2.224.0.0
v2.224.0.2BETAREVISION
Seymour2 de ago. de 2026
OPERATION DEMON: fechamento da documentação Wave 4 + script RT2
run_f8_rt2.ps1(novo): smoke de boot + checks F8 (dashboard/F7/cheats/dialog skip) — exige editor fechado, save descartável, hashes antes/depois.F8_UNX_INCONSISTENCY_REGISTER(sessão 3): INC-002/005 + P1/P2/P5/P7 RESOLVED; P3 parcial (v2.flag já ausente); never-port registrado (KillMeNow/auto-update/injeção de textura/sig-scan).- SESSION_HANDOFF + PORT_STATUS: F8
Needs Testing— in-game RT2 pendente do usuário (editor fechado). - Cleanup:
ingame_menu_v2.flagjá ausente do deploy (P3 confirmado limpo). ### PATCH
v2.224.0.1
v2.224.0.3BETAREVISION
Seymour2 de ago. de 2026
OPERATION DEMON: plano post-F8 — Tier 2 via ffx-probe (§9) + check RT2
- F7F8_RECONCILIATION_PLAN §9: com o UnX fora do deploy, vtable[9] (GetDeviceState) volta para ffx-probe.dll — o probe in-process main-thread (FORCEBATTLE/SETINPUT/SOUNDCMD/READ/WRITE/CALL — Tier 2: a_ability/arms_rate/Encounter Table/IA/calibração Aurora). Estado atual: OFF no deploy (
.RT2OFF); loader presente; dashboard já tem o itemplugins.ffx_probe. run_f8_rt2.ps1: check de heartbeat do probe (hooked=1) quando o probe está ativo.- Gate: doc-only (REVISION); deploy intocado. ### REVISION
v2.224.0.2
v2.224.0.3BETAREVISION
Seymour2 de ago. de 2026
PPP DISPATCH TABLE: CYCLE CLOSED (consumidor + tabela principal)
- Consumidor PROVEN:
FFX_MagicHost_RelocatePppSection(0x7121D0) —a2 + 40*index(stride 40 = 0x28 no código); callers passam&pppSysProgTbl(0x72a8eapush offset pppSysProgTbl→ 0xC3A500; 0x761b72). O on-diskhandler_table_indexde cada slot vira o ponteiro da entrada da tabela; slot de runtime = 16B ([0]=índice, [1]/[2]=ptrs relocados; contagem em*(int16*)(record+0x26)) — bate com a janela pppSclMove T3. - pppSysProgTbl @0xC3A500 = a tabela MAIN — layout "progtbl" (name@+0x00, fnMain@+0x08, fnExtra@+0x20), 418 entradas (bate com o doc MAGIC de 2026-07-31); slots 0-11 = pppAccele..pppColor com os handlers de ranking Yonishi (pppSclMove T3 = 0x75C090 @ slot 6; pppScale = 0x75D0D0 @ slot 10; pppAngle = 0x75CF20 @ slot 9; pppSclAccele = 0x75B9F0 @ slot 2).
- Correção do pass anterior: 0xC3A500 é NOT um vetor de nomes (o bloco 0xC3A4E0 = strings de debug END/CHR/MAP-G/MAT; rename
FFX_PppNameVectorREVERTED). - Substituições do MAGIC de 2026-07-31 propagadas PARA O BANCO DE DADOS CANÔNICO: 0x716D20→FFX_Render_PppProgramProcessor_2, 0x75B830→FFX_PppHandler_Accele, 0x75B900→FFX_PppHandler_Accele_SetFromGlobalQ, 0xC3E798→FFX_PppHostDispatchTable_AltQ, 0xC86080→FFX_PppKeyholeDispatchTable.
- Extractor ganhou o layout progtbl + a tabela principal: 5 tabelas, 1191 handlers em
scripts/ppp_dispatch_table.json. Doc:docs/reverse/PPP_DISPATCH_TABLE_RECONCILED_2026-08-02.md(2º pass). - C2 com a cadeia completa: índice on-disk → pppSysProgTbl + 40*índice → entrada (name+fn). Próximo: a janela de slot 16B disco→runtime (T3) e os 145 aliases. ### PATCH
v2.224.0.2
v2.224.0.4BETAPATCH
Seymour2 de ago. de 2026
F8 DISABLED (gate `dashboard.enabled=false`) + doc F8+probe consolidado
- Gate flipado em 2 pontos (Config.cpp kDefaultIni + dllmain
GetBool×2) — dashboard/booster/DialogSkipHook não iniciam; InGameMenu vira o dono de F8/INSERT de novo (fallback natural). Reversível (reativar = flip + deploy). docs/reverse/FFX_F8_PROBE_CONSOLIDADO_2026-08-02.md(novo): F8 (Waves 1-3 + close) + ffx-probe (Tier 2) + como reativar + itens pendentes.- Deploy Steam +
_isolated(backup191908); build Release 0 erros. Focus de volta a F7. ### REVISION
v2.224.0.3
v2.224.0.5BETAPATCH
Seymour2 de ago. de 2026
F7: FLICKER FIXED (causa raiz no wire de alavanca) + sem números crus de stepper + alavanca REAL Difficulty
- FLICKER (report RT2 do usuário — causa raiz com evidência de log): confirmar uma linha fechava o menu (
CloseMenu→m.obj=0) BUTg_forceSubsystemficava ON — jogo preso em modo menu (0x13407E4=1) sem menu desenhado = render alternado = tela piscando (log:open→ confirm →close (force-gate off)só no 2º F7 →open...). Fix: o wire agora limpag_forceSubsystemno confirm (mesmo comportamento dog_nativeWantClose). - Debounce de toggle F7 (250ms) em PresentTick — segurar F7 (ou tecla presa) alternava o menu a cada borda = flicker.
- "Número onde não deveria": linhas RT_STEPPER mostravam
[0]cru antes de editar. Fix:g_rowEdited[]— o valor do stepper só aparece AFTER L/R (toggle [ON]/[OFF] fica sempre visível). - Alavanca REAL Difficulty (era um stub): novo
F7_SetDifficultyLevel(0..5)(F7InLive) — setag_cfg.diffGlobal(hpMul 1000/1150/1300/1500/1750/2000 — x1.00..x2.00) +F7_SaveConfig()— o battle-start auto-apply pega. - Gate: compilação Release com 0 erros; implantação na Steam +
_isolated(backup193746). RT2 pendente: F7 → confirmar → menu fecha SEM piscar; sem [0] inicial; Difficulty é aplicada na batalha.
v2.224.1.0
v2.224.1.0BETAPATCH
Seymour2 de ago. de 2026
F3.5 PART 2: DRAG GIZMO na Aurora (arrastar o monstro no canvas) + RE: janela T3 provada + aliases decodificados
- Gizmo no noclip (
scenes.ts,?edit=1): click seleciona o actor mais próximo (picking por projeção —clipFromWorldMatrix+ w-divide), drag no plano do chão (unproject no y-plane do actor, conversão FFX↔noclip via inversa da matriz), overlay (anel amarelo + instruções), teclas S = salvar (POST/api/edits/<encId>— o endpoint do hub — com o delta de slot) e R = reset (volta ao vanilla). Base vanilla Per-slot armazenada emsetUpMonsters(deltas corretos mesmo com sidecar anterior). - ViewerShell: checkbox "Gizmo 3D (arrastar no canvas)" no painel de edição +
&edit=1/0no battle-preview URL + status mostrando o estado do gizmo. - RE (3º pass): janela T3 de 16B PROVEN no handler pppSclMove (0x75C090 =
FieldMap_AccumulateDoubleLayerDelta_C): lê os 4 floats ema2+16..+28(a janela T3record+0x10..+0x1F) e acumula ema1+160..+172. Aliases decodificados: as 418 entradas pppSysProgTbl = 273 nomes únicos + 145 re-registrations (o "145 aliases" do doc MAGIC = handlers repetidos, não nomes alternativos); o extrator ganhoufind_all_strings(368 strings na região) + o campoisAlias. - Gate: typecheck do noclip limpo;
rsbuildOK; bundle461.7bf8f17f.jsdeployado no serve-dir (contémeditUpdate+ POST); build C# 0 erros; testes ViewerHub 17/17 PASS. - F3.5 COMPLETE: sidecar (parte 1) + gizmo (parte 2) — o ciclo editar → ver → salvar → reabrir está fechado. ### REVISION
v2.224.1.0
v2.224.1.2BETAPATCH
Seymour2 de ago. de 2026
F7 RT2 ROUND 2: "NOTHING OPENS" FIXED (o wire roubava o confirm) + Force Battle sem número + label de cheat claro + submenus desbloqueiam música
- BUG 4 (crítico — NENHUM MENU ABRE): meu wire PumpHook consumia
g_ourClosedANTES o pump original —PollMenununca via o confirm → submenus NEVER abriam. Fix definitivo: o wire foi REMOVED — o pump original (CloseMenu →DispatchConfirm→NativeMenu_OnEdge→ submenus/reabrir/force-off) roda intacto de novo. - BUG 3 (Force Battle com número): a linha era RT_STEPPER (0..250) — agora RT_NONE (sem valor; o submenu FORCE faz o trabalho —
F7_MENU_FORCE). - BUG 2 (Battle Cheats confuso): renomeado para "Party Invincible (debug)" — a alavanca (0xD2A8F8+1) é a flag de party invencível do jogo.
- BUG 1 (menu sem música): o submenu Music (que o Bug 4 impedia de abrir) agora abre — o usuário escolhe a trilha no submenu (
F7_MENU_MUSIC). - Alavanca realocada:
F7_LeverApplyagora é chamada porNativeMenu_OnEdge(casos ACT_AI_SWAP/ACT_BATTLE_CHEATS — ações diretas sem submenu; val deg_ourResult). - Gate: build Release 0 erros; deploy Steam +
_isolated(backup200713). RT2: Arena+ abre, submenus Music/Force/Difficulty abrem, toggle Party Invincible aplica. ### PATCH
v2.224.1.1
v2.224.1.3BETAPATCH
Seymour2 de ago. de 2026
F7 RT2 ROUND 3: MUSIC TRACK 0 = NONE (tela de título silenciosa + CRASH entrando em batalha)
- Bug 1 (tela de título/intro sem música):
music_lock: 0emf7_inlive.json(salva pelo submenu Music) —F7_MusicApplyLockaplicava o override da trilha 0 (silêncio/fora de contexto) no boot. - Bug 2 (Custom Mix CRASHED entrando em batalha):
music_battle: 0—F7_ApplyMusicBattle(battle-start auto-apply) faziaSetArenaBattleMusicPending(0)→ MusicHook aplicava a trilha 0 → crash (log: FAULT rva 0x4FB05E logo após o compose). - Fix: a trilha 0 vira none nos dois setters (
F7_SetMusicLock/F7_SetMusicBattleTrack:<= 0 → -1) +f7_inlive.jsonlimpo (music_lock/music_battle= -1). - Gate: build Release 0 erros; deploy Steam +
_isolated(backup202945). RT2: música da tela de título de volta; Custom Mix entra em batalha sem crash. ### PATCH
v2.224.1.2
v2.224.1.4BETAPATCH
Seymour2 de ago. de 2026
F7 RT2 ROUND 4: feedback PREVIEW + crash do Custom Mix INVESTIGATED (UpdateWindowTitle/DrawUITextElement)
- Bug 2 (Preview "não faz nada"):
F7_MusicPreviewcom lock-1(nenhum — estado atual da configuração) retornava SEM REPRODUZIR (a guardatrack < 0). Correção: confirmar Preview com val<= 0mostra o status na tela "Ajuste a faixa (L/R) antes do Preview"; com valor válido, toca. (O fluxo: L/R em "Music Lock" → confirmar no stepper = preview — já existia.) - Bug 1 (crash ao montar a batalha — PERSISTS): o FAULT (mesmo RVA
0x4FB05E) mapeado em IDA:FFX_System_UpdateWindowTitle(0x4FAE40) →DrawUITextElement(0x640810,void(ctx, text, x, y, slot)— desenha o texto SAVE no título da janela; calleeFFX_Save_SystemSaveGame) — o crash está no ctx 2D do menu ("NoTexture"/ResolveTextureNameForUI). O bin composto é OK (24272 B vs 24080 vanilla — grow de 192 B com header ajustado). Isolamento pendente (usuário): (a) batalha normal sem compose → crash? (b) compose com 1 aeon → crash? (c) compose com o menu CLOSED antes do Launch → crash? - Gate: build Release 0 erros; deploy Steam +
_isolated(backup205601). ### PATCH
v2.224.1.3
v2.224.1.5BETAPATCH
Seymour2 de ago. de 2026
F7 RT2 ROUND 5: PREVIEW CRASH FIXED (probe OFF = MMF 0xCD) + "Preview" vira "Save + Open Custom Mix"
- Crash do Preview CRASH (reproduzido pelo usuário — "Enter no Preview = crash NOW"):
F7_MusicPreviewchamava o soundcmd via probe (ArenaPlus_MusicHookProbeSoundCmd→LabProbeSoundCmd→ MMFFFXProbeBlock_v1) — o probe é OFF no deploy (.RT2OFF) — o MMF existe mas o dado é o padrão 0xCD (memória liberada/não inicializada) →AV READ accessed=0x10CDCDCDdentro de ffx-hooks. Fix: SEH (__try/__except) emF7_MusicPreview(o soundcmd nunca mais pode crashar o jogo — só override) + o confirm do stepper de trilha agora SAVES (não toca). - UX (pedido do usuário): o "Preview" do submenu Music virou "Save + Open Custom Mix" — Enter salva a config (f7_inlive.json) + reabre o menu nativo para Arena+ → Custom Mix (o fluxo padrão que WORKS). A música fica armazenada na config (lock/battle) e aplica no contexto certo (início de batalha), sem playback de probe.
- Gate: build Release 0 erros; deploy Steam +
_isolated(backup214436). RT2: Enter em "Save + Open Custom Mix" não NOT crash; config salva; Custom Mix abre. ### PATCH
v2.224.1.4
v2.224.1.6BETAPATCH
Seymour2 de ago. de 2026
i18n: literais crus migrados para {x:Static} (gate StringsIntegrityTests verde)
- Dívida do gizmo F3.5 corrigida: o checkbox "Gizmo 3D (arrastar no canvas)" e a dica ("Clique num monstro para selecionar... S = salvar · R = reset") usavam literais crus em atributos (
Content=/Text=) — o testeNoXamlHasRawHardcodedUiLiteralpega atributos. Migrados para{x:Static res:Strings.U_gizmo_3d_drag_on_canvas_1aa7857f}+U_click_monster_to_select_drag_hint_fe907a09(neutro EN + PT + props Strings.cs). - Dívida de outra lane (MonsterAi):
MonsterAiPhaseRotationAdvanced_Window.axamltinha 2 literais crus ("Foco ativo" / "Limpar foco") — migrados paraU_active_focus_d59334a6/U_clear_focus_91699d35(o teste é o árbitro project-wide). - Gate:
StringsIntegrityTests3/3 PASS; build 0 erros.
v2.224.1.5
v2.224.1.7BETAPATCH
Seymour2 de ago. de 2026
Visualização Aurora: nomes de monstros na batalha (labels + gizmo)
export const MONSTER_NAMESemmonster_studio.ts(284 nomes reais — "Raldo", "Bunyip"...).- scenes.ts: modo de edição (
?edit=1) agora desenha labels sobre os monstros ALL da batalha (nome real em branco; o selecionado em amarelo) + o overlay do gizmo mostra o nome do monstro selecionado (e.g. "Dark Flan (slot 6)") em vez de só "slot N". - Gate: typecheck do noclip limpo;
rsbuildOK; bundle461.0fe1690d.jsdeployado (contém "Raldo"/"Bunyip"); patch versionado emdocs/patches/noclip/(scenes.ts + monster_studio.ts).
v2.224.1.6
v2.224.1.8BETAPATCH
Seymour2 de ago. de 2026
Aurora: a AURORA CHAMBER volta como a Aurora principal (preview de batalha aposentado) + i18n PT→EN dos módulos Aurora
- Aurora Chamber REACTIVATED como o "Aurora" do catálogo:
MenuItem_AuroraeMenuItem_AuroraChamberagora abremAuroraChamber_Control(catálogo BIANCA + MapViewer + Open RealGame — a batalha real). Novo helperOpenAuroraChamber(). O preview de batalha (noclip) vira código legado (entrada "aurora" desabilitada no catálogo; a desc ViewerHub/aurora fica congelada). - ModuleCatalogPolicy: entrada
aurora-chamberreativada ("Aurora Chamber");aurora(preview de batalha) marcada 🚫 LEGACY (comentada). Dispatchcase "aurora-chamber"adicionado. - i18n PT→EN dos módulos Aurora: o neutro (Strings.resx) tinha valores PT (o editor EN mostrava PT) — corrigido para EN: 12 chaves existentes (AURORA·Battle Maps, Selected place, Visualization, Editing, Session, Open arena em Aurora Chamber, Filter by field..., Selected field, Exports map/..., Field Picker, overworld, MapViewer 3D) + 23 chaves novas (botões da Chamber e do Field Explorer: Re-scan, Mount missing, Remount all, Open EditViewer, Open RealGame, Save positions, Add/Remove monster, Export anchors, Restore RealGame, Reload battle, Re-export e open, Remount scene, Export folder, Save camera, Save camera params, Publish Scout, Update markers, Publish e open field, Validate visual, Open field, Re-export, Browser). EN no neutro + PT no satellite (verificado: já está em PT) + props Strings.cs.
- Gate:
StringsIntegrityTests3/3 PASS; build 0 erros.
v2.224.1.7
v2.224.1.9BETAPATCH
Seymour2 de ago. de 2026
Bugfix: Open RealGame (404) + mapa da Aurora de cabeça para baixo
- Bug 1 — RealGame 404:
Aurora3DLauncher.BuildBattleUrl(usado pelo "Open RealGame" da Chamber) iniciava um legado python http.server na raiz do noclip (Downloads) — mas o index.html do noclip fica emdist/, então/index.htmlretornava 404 ("página não encontrada"). Correção:BuildBattleUrlagora usaViewerHubService.BuildUrl("aurora", ...)(o StudioWebServer em processo com o diretório servido do noclip — o index.html correto). RemovidoEnsureViewerServer/IsPortListening(python legado — desativado na F2). O MÓDULO (RealGame com monstros) continua funcionando — somente a PÁGINA de prévia de batalha é legada. - Bug 2 — mapa de cabeça para baixo:
applyAssetOrientationemRuntimeTools/FFXMapViewerWeb/app.jsaplicavarotation.x = Math.PI(flip π no X) parabtlmap(a arena da Aurora Chamber) — virando o mapa. O mapa glTF já é Y-up. Fix:rotation.set(0,0,0)(sem flip) para todos — chão embaixo, céu em cima. - Gate: build 0 erros;
node --checkOK no app.js; o MapViewer é servido diretamente do repositório (prefixo /map/) — o app.js corrigido já está sendo servido.
v2.224.1.8
v2.224.1.10BETAPATCH
Seymour2 de ago. de 2026
Bugfix: {x:Static} como conteúdo de elemento mostrava o literal cru (e crashava ao abrir o editor)
- Bug: os 25 botões dos módulos Aurora (Chamber + Field Explorer) que I migraram para i18n usavam
{x:Static res:Strings.X}como conteúdo de elemento (<Button>{x:Static}</Button>). O Avalonia não resolve{x:Static}como conteúdo de elemento — mostra o literal cru ("{x:Static res:Strings.U_...}") e pode crashar em runtime ao usar o botão (o motivo do "mapa crasha ao abrir o editor"). - Fix: convertidos os 25 para o atributo
Content="{x:Static res:Strings.X}"(o padrão correto).{x:Static}só resolve como atributo (Content=,Text=,Header=,Watermark=,ToolTip.Tip=). - Gate: build 0 erros;
StringsIntegrityTests3/3 PASS;node --checkOK.
v2.224.1.9
v2.224.1.11BETAPATCH
Seymour3 de ago. de 2026
F7: painel de vidro no submenu (janela única) + compose CRASH corrigido (force-gate antes do launch)
- Bug 2 (UX — usuário pediu "uma janela nova"):
F7Sub_DrawCb(dllmain ~11580) ganhou o grande painel de vidro (DrawMenuGlassPanel(NX(0.047f), NY(0.20f), NW(0.906f), NH(0.62f), F, 1)) — o submenu Sound agora é um WINDOW (fundo + título + linhas INSIDE), estilo compose-pick. - Bug 1 (crash do Custom Mix battle-start — causa raiz):
ArenaPlus_LaunchComboBattleFromPump(o MsBattleEncountExe) rodava com o force-gate ON (g_forceSubsystem = 0só era AFTER o launch) — o jogo entrava em batalha com 0x13407E4=1 (modo menu) → o início de batalha crashava emUpdateWindowTitle→DrawUITextElement(rva 0x4FB05E — AV WRITE 0xBD). Fix:g_forceSubsystem = 0+ 0x13407E4 zeram DIRECTLY ANTESArenaPlus_LaunchComboBattleFromPump(Launch + LaunchCached — o relaunch). - Gate: compilação Release com 0 erros; implantação na Steam +
_isolated(backup095551). RT2 pendente: Custom Mix → Build + Launch → batalha entra SEM travar; submenu Sound = janela única. ### INFRA (CI) ci.ymlrodava o CI em qualquer push paramainecodexclaudiocodeffxeditor(a branch de trabalho onde lanes committam constantemente) — 2 jobs em runners Windows ($0.010/min) esgotavam a cota grátis de 3.000 min/mês (Actions $22.70).- Fix: o trigger de push agora é só
main(branches: [main]). CI ainda validamain(e PRs paramain); a branch de trabalho não ganha CI automático (valide local comdotnet build). - Economia estimada: ~90% das execuções de Actions (corta o custo recorrente de minutos). ### PATCH
v2.224.1.10
v2.224.1.12BETAPATCH
Seymour3 de ago. de 2026
LOG: auto-rotation por contagem de aberturas (máx 10, histórico `.old1..old9`)
OpenLog(dllmain ~173) agora conta aberturas (arquivo%TEMP%\ffx-hooks.log.cnt); a cada 10ª abertura, move o log atual paraffx-hooks.log.oldN(acumula histórico.old1..old9;.old1é sobrescrito após 9 rotações) e reseta o contador. O log principal não acumula mais que ~10 sessões; o usuário exclui.old*conforme necessário.- Gate: build Release 0 erros; deploy Steam +
_isolated(backup102648). ### PATCH
v2.224.1.11
v2.224.1.13BETAPATCH
Seymour2 de ago. de 2026
fix RealGame (batalha vs campo) + EditViewer sempre abre + regra geral DEBUG LOG (Fases 1-4) + mapa de análise full-editor (Fase 5)
- Fix RealGame (a batalha volta):
BuildBattleUrlpassava o extraQuery WITH?paraViewerHubService.BuildUrl(que já adiciona?) → URL viravaindex.html??battle=...→ oURLSearchParamsdo noclip não liabattle→ só o campo (mapa), sem batalha. Agora o extraQuery está sem?→?battle=<encId>&map=&actors=1→ a batalha com monstros volta. - EditViewer nunca mais "não faz nada": o fallback
RenderSceneagora abre a cena vazia (grid + overlay) mesmo sem âncoras quando a exportação glTF falha (antes exigia âncoras — sem elas, a renderização retornava erro e o botão não fazia nada). O log captura o motivo da exportação. - DEBUG LOG — GENERAL RULE (
FFXProjectEditor/Diagnostics/DebugLog.cs): helper centralInfo/Warn/Errorcom[Conditional("DEBUG")](removido no Release — zero overhead). Saída: debugger +%LOCALAPPDATA%\FFXProjectEditor\debug.log+work/editor-debug.log. Instrumentado: RealGame (gerado URL), EditViewer (render), SelectSceneByMapKey (bika00_10), ExportSceneGeometry (falhas), ViewerHub (BuildUrl/EnsureServer). - Regra permanente: adicionada a
AGENTS.md+CLAUDE.md— todo módulo novo MUST ter respostas de debug. Docs:docs/ai/DEBUG_LOGGING_RULES.md(a regra) +docs/ai/DEBUG_LOGGING_MAP_2026-08-02.md(Fase 5 — análise full-editor: ~51 módulos + infra + fronteiras; onde/quais tabelas de campo de debug por domínio; prioridade de implementação; UI vs log). - Gate i18n: 5 literais crus de
MagicDllEditor_Control.axaml(setas + tooltips Back/Forward — dívida de outra lane) migrados para{x:Static}(o teste é o árbitro project-wide). - Gate: build Debug + Release 0 erros; testes 20/20 PASS (StringsIntegrityTests 3/3 + ViewerHub 17/17).
- O hook captura o stdout do lab via pipe (CreatePipe + STARTF_USESTDHANDLES — o job de compose lê a saída e extrai as linhas PREV|) e desenha o painel de pontos no menu (painel de vidro esquerdo — o layout que entrará na batalha).
- Novo botão "Build Preview (layout bolinhas)" no Custom Mix: compõe sem iniciar (o menu fica aberto — status "Preview pronto — layout acima. Fight Last Mix p/ entrar.") → o usuário vê os pontos ANTES de entrar → "Fight Last Mix" (existente) lança o binário já composto.
- Fluxo: escolher aeons + cenário → Build Preview → ver o mapa (P direita / monstros esquerda / cam h) → Fight Last Mix → batalha.
- Build do lab 0 erros + ffx-hooks (com PolyHook) 1.113.600 B; LabDeploy para o Steam (lab real + hooks).
- RT2
Needs Testing: Custom Mix → 4 aeons → Build Preview → conferir o mapa no painel esquerdo → Fight Last Mix → batalha com o layout mostrado. ## [Unreleased] ### MINOR
v2.224.1.12
v2.224.1.14BETAPATCH
Seymour2 de ago. de 2026
DEBUG LOG v2: 3+1 flags per-area + auto global/dev/prod + Event Tracer UI + ponte de console WebView + exceção global + item de menu "Open debug log"
- DebugLog v2 (
FFXProjectEditor/Diagnostics/DebugLog.cs): flag GLOBAL (auto=Debug→dev/Release→prod;FFX_DEBUG_MODE=dev|prodforça) + flags per-area (debug_flags.json:0=OFF,1=ACTIVEloga enquanto a área é tratada,2=ALWAYSloga em qualquer erro,3=FORCEDEBUGloga EVEN no Release). LOGS ALWAYS IN ENGLISH (fora do i18n). Rotação de 5MB +.old1..old9(alinhado com a lane de hooks C++). - Event Tracer UI:
Main_Windowintercepta cliques de botão ALL (AddHandler Button.ClickEvent) e loga automaticamente com o módulo ativo (UiTracer) — sem logging per-click necessário. - ActiveScope:
SetModuleativa/desativa a área do módulo aberto (a flag 1 usa isso). - Ponte de console WebView:
WebView2Hostinjeta um script redirecionandoconsole.error/warn/logdo JS hospedado (noclip/MapViewer) →WebMessageReceived→DebugLog(WebView.Console) — os bugs JS do viewer agora caem no log. - Exceção global:
AppDomain.CurrentDomain.UnhandledException+TaskScheduler.UnobservedTaskException→DebugLog.Error("Global", ...). - Menu: item "Open debug log" no flyout do seletor de idioma (abre o debug.log).
- Test:
DebugLogTests(3/3 — EN write, formato timestamp+área+tipo, exceção com tipo). - Docs:
DEBUG_LOGGING_RULES.mdatualizado (modelo de flag + EN + tracer + o mínimo manual exigido). - Gate: build Debug + Release 0 erros; testes 23/23 PASS (i18n 3/3 + ViewerHub 17/17 + DebugLog 3/3).
v2.224.1.13
v2.224.1.15BETAPATCH
Seymour3 de ago. de 2026
crash de batalha do Custom Mix: draw compose-pick desabilitado DURING compose
- Mecanismo (confirmado em IDA): o FAULT (AV WRITE
accessed=0xBD) cai dentro deDrawUITextElement(0x640810, pc 0x6409A5) — octx(viaFFX_Menu2D_ResolveCaptureCtxCore) é null/corrompido —UpdateWindowTitle(0x4FAE40) crasha desenhando o texto do save. O crash acontece DURING compose (o runner ArenaMultiBossLab), com nosso menu (pick de compose) aberto. - Fix:
ComposePick_Draw(o compose-pick DrawCb) agora retorna cedo quandog_jobState == JOB_RUNNING— nosso menu não NOT enfileira texto no menu 2D do jogo durante o compose (EncodeLabel/DrawStringcorrompiam o pool/cache de texto: cache-hit → pool[cursor-1] sem check de bounds → handle inválido). O menu congela 1-2s (o compose é rápido) e volta ao normal depois. - PRIMEIRO COMENTÁRIO WHY — esta correção já vem com o comentário why (em inglês) no código.
- Gate: build Release 0 erros; deploy Steam +
_isolated(backup140132). RT2 pendente: Custom Mix → Build + Launch → o crash do compose deve sumir. ### PATCH
v2.224.1.14
v2.224.1.16BETAREVISION
Seymour3 de ago. de 2026
REGRA DE COMENTÁRIOS WHY para hooks + 1º passe WHY
- Nova regra (CLAUDE.md): tocar num hook → deixar o WHY no código (em inglês) —
// WHY: ...(a justificativa, não o quê),// FIX <date>: ...(com o porquê),// KEY <date>: ...(insight de RE). Mantenha o Focus nos pontos não óbvios (gate, offset, ordem crítica, colisão de pool/ctx, decisão de arquitetura) — sem spam, sem bíblia de básicos. - 1º passe WHY: dllmain (fluxo de confirmação no menu nativo — por que o wire foi removido; início da composição — force-gate antes de MsBattleEncountExe) + ArenaPlusComposePick (ComposePick_Draw desabilitado durante a composição — o crash do pool 2D).
- Gate: build Release 0 erros (comentários não mudam comportamento); sem deploy (REVISION — doc/code-comment). ### PATCH
v2.224.1.15
v2.224.1.18BETAPATCH
Lulu3 de ago. de 2026
Magic DLL Editor: schema `pppVertexApAt` decomposto (4 campos reais) + cleanup `pppMatrixLoc` (host-only) + DebugLog em `Magic.Parse`/`Magic.Writer`
- Decomposição (decompile IDA 0x7583D0):
pppVertexApAtagora tem 4 campos editáveis (model_indexu16@+4,vertex_countu8@+6,delay_framesu8@+7,order_modeu8@+8; janela{4,5},editable=true). Aplicado afield_map.json+MagicFieldMapEmbeddedData.cs. - Cleanup honesto:
pppMatrixLoc(decompile 0x734200) opera só no estado do host (zero leiturasa2/record) — os 3 camposparam_s32_64/68/72eram offsets inventados → removidos,payload_consumer=false,SEM_PAYLOAD(correto). - Não aplicado (achado RE):
pppKeThRes32/48—a2+12é um ponteiro de recurso (chain builder), não um knob numérico; editar como u32 corromperia o ponteiro. Documentado. - DebugLog v2:
TryLoad(Magic.Parse) +TryGrowRecord(Magic.Writer) instrumentados comDebugLog.Info/Warn/Error(inglês, monolíngue). - Gate: build Release 0 erros; testes MagicDll 76/76 + StringsIntegrity 3/3 (79/79).
- O crash (reproduzido no compose WITHOUT): abrir F7 + navegar no menu (após um preview/batalha) → FAULT AV WRITE
pc=0x2409A5accessed=0xBD(o SAME como compose) —UpdateWindowTitle(0x4FAE40) crasha emDrawUITextElementcom o pool/ctx 2D do menu corrompido pelo nosso menu (desenhando textos MANY a cada frame: cache-hit → pool[cursor-1] sem check de bounds). - Fix (definitivo): hook em
FFX_System_UpdateWindowTitle(0x4FAE40) — com nosso menu nativo ativo (F7/submenu/compose pick), o hook retorna 0 — o jogo não NOT desenha o texto do título (cosmético) e não toca no pool corrompido → sem crash. O título volta a atualizar quando o menu fecha. - Gate: build Release 0 erros; deploy Steam +
_isolated(backup144123). RT2: F7 aberto + saindo da batalha → sem crash. ### REVISION
v2.224.1.17
v2.224.1.19BETAPATCH
Seymour3 de ago. de 2026
LIVE POSITION EDIT (Parte 1): janela "dot-map" no hook (monstros + players)
- A janela: no compose pick (Custom Mix), com Build Preview feito, pressionar E → entra no modo de edição do grid (o mapa de pontos 16×8 — cada bicho = um
P, o ativo =X). - Interação: setas movem o cursor (o
Pdo bicho ativo); TAB troca de bicho; ENTER salvamodules\arena_positions.json(o gx/gy do grid de cada bicho); Cancel volta. SavePositions/ResolvePositionsPath: o JSON em modules (o grid 16×8 — o runner do compose vai ler depois e aplicar o C#BattleArenaPositionWriterno bin — o link next-part).- WHY (no código): o jogo lê as posições de bicho das âncoras do chunk3 do bin (
pos = bin + chunk3 + 16×a5) — salvar o grid editado deixa o compose aplicar o posicionamento custom. - Gate: build Release 0 erros; deploy Steam +
_isolated(backup153130). RT2: E no compose pick (com preview) → a janela de pontos abre; mover + ENTER salva o JSON. ### PATCH
v2.224.1.18
v2.224.1.20BETAPATCH
Lulu3 de ago. de 2026
Magic DLL Editor: breadcrumb (voltar/avançar) movido para FORA da divisão pasta/campo — agora aparece também ao chegar numa folha (item/campo)
- Antes: o botão voltar só aparecia na view de pasta (
IsContainer); ao chegar num campo/folha, sumia — e você não conseguia voltar. - Agora: o breadcrumb (⬅ voltar · ➡ avançar · caminho) é exibido sempre quando há seleção (pasta OU folha), permitindo navegação voltar/avançar de qualquer item.
- Gate: build Release 0 erros; StringsIntegrityTests 3/3.
- Janela A: no compose pick (o Custom Mix), com Build Preview feito, pressionar E → entra no modo de edição do grid (o mapa de pontos 16×8 — cada entidade = um
P, a ativa =X). - Interação: setas movem o cursor (o
Pda entidade ativa); TAB alterna a entidade; ENTER salva omodules\arena_positions.json(o gx/gy do grid de cada entidade); Cancel volta. SavePositions/ResolvePositionsPath: o JSON em modules (o grid 16×8 — o runner do compose vai ler depois e aplicar oBattleArenaPositionWriterC# no bin — o link para a próxima parte).- WHY (no código): o jogo lê as posições de entidade das âncoras do chunk3 do bin (
pos = bin + chunk3 + 16×a5) — salvar o grid editado permite ao compose aplicar o posicionamento custom. - Gate: build Release 0 erros; deploy Steam +
_isolated(backup153130). RT2: E no compose pick (com preview) → a janela de pontos abre; mover + ENTER salva o JSON. ### PATCH
v2.224.1.19
v2.224.1.21BETAPATCH
Seymour3 de ago. de 2026
edição de posição ao vivo LINK: o runner do compose aplica o grid custom ao bin
BattleComposeRunner(Parte 2 do posicionamento ao vivo): novoReadCustomPositionsJson(modRoot)(lê oarena_positions.jsonsalvo no hook) +ApplyCustomPositions(...)(converte o grid 16×8 → X/Z reais — X ±28, Z 30→46 — e aplica viaBattleArenaPositionWriter.WritePositions, preservando Y/W).- No compose: se
arena_positions.jsonexiste, o runner usa o grid custom (primeiroactorCount= monstros em MonsterLive; o resto = party em PartyFront) em vez do auto-layout da câmera. Log:[custom-positions] grid do hook aplicado em .... - Fluxo completo (Parte 1 + 2): compose pick → Build Preview → E → mover os
Ps (setas/TAB) → ENTER salva o JSON → Launch → compose aplica o grid custom ao bin → a batalha começa com o posicionamento editado. - Gate: build do lab (C#) 0 erros; deployado
ArenaMultiBossLab.dllno jogo (backup180311). RT2: editar a posição no hook → Launch → batalha com o posicionamento custom. ### PATCH
v2.224.1.20
v2.224.1.26BETAPATCH
Lulu3 de ago. de 2026
Magic DLL Editor: Fase 1 (clone) + Fase 2 (override de magia do noclip) + Fase 3 (preview 3D embutido travado)
- Fase 1 — botão Clone: novo
CloneMagicCommand+TryCloneMagic(copia os bytes de trabalho com edições para um novomagic_<id>.dll; backup .bak; id validado). Botão "Clone" na toolbar. - Fase 2 —
MagicOverrideService: sobrescrevedata/FinalFantasyX/11/<id>.binno noclip com o DLL custom (backup vanilla.magic3d.bak; restore). O noclip já renderiza magia viaBIN.parseMagicFile— sem RE profundo necessário. - Fase 3 — Preview 3D embutido: botão "Preview" abre o WebView2Host embutido (mini browser) no editor, travado na magia em edição (override de
11/<id>.bin+ magic-studio URL). Botão fechar (✕). - Gate: build Release 0 erros; MagicDll 76/76 + StringsIntegrity 3/3.
- Fase A — humanização de tipo real: o campo
DetailTextagora mostra ONLY a descrição humana (sem[u16], offset, largura) — o tipo cru que você via sumiu. Aviso Read-only também na view de pasta (slots non-editable como pppDrawMatrix mostram "Read-only" + motivo). - Fase B — pesquisa em massa IDA (23 handlers descompilados): reclassificou 3 SEM_PAYLOAD → FECHADO com campos reais:
pppKeLnsLpSft(110 DLLs, 2 floats lens-shift),pppDrawHook(10 DLLs, callback),pppKeAcmCic(modo). Confirmou o resto (KeShpTail*, KeDMat*, Matrix*, DrawMatrixWood) como host-only/stubs (sem decomposição) — documentado. - Fase C — catálogo expandido: +19 descrições humanas (total ~94 opcodes) cobrindo os novos FECHADO + host-only SEM_PAYLOAD.
- Gate: build Release 0 erros; MagicDll 76/76 + StringsIntegrity 3/3 (79/79).
- View de campo redesenhada: um campo agora mostra nome + descrição humana + tipo legível (e.g. "decimal (float)") + valor editável num card. Offset e tipo cru (
u16) escondidos — o jogador não toca neles. - read-only claro: campos non-editable mostram um aviso destacado "Read-only" + o motivo (e.g. "dados crus — o editor ainda não consegue decompor").
- Catálogo de descrições humanas (
MagicPppDescriptionCatalog.cs): ~60 opcodes ppp com o que fazem em linguagem de jogador (baseado no decompile IDA + docs RE). Mostrado no DetailText do slot. - Tooltip Grow-size: explica que 4B/8B/12B/16B = bytes extras de espaço (1/2/3/4 valores).
- Gate: build Release 0 erros; StringsIntegrity 3/3 + MagicDll 76/76 (79/79).
v2.224.1.25
v2.224.1.28BETAREVISION
Lulu4 de ago. de 2026
Magic DLL: Fase 4 — deep RE do Preview 3D (layout do noclip mapeado no source)
- Novo doc:
docs/reverse/magic_dlls/NOCLIP_PREVIEW_LAYOUT_MAPPING_2026-08-03.md— mapeia oparseMagicFile→sniffMagic→ caminhoparseParticleDatade noclip.website (source real). - Veredito: edições de campo confinadas à janela = SAFE para preview (o noclip re-reads os mesmos offsets; strides fixos 0x28/0x10 inalterados); grow estrutural no meio de um record que o noclip percorre = BREAKS preview; grow seguro = count-driven extensão de lista na cauda + bump de contagem.
- Caveat do clone: o noclip só renderiza ids presentes na
magicTabledele; id fora da tabela →sniffMagicnull → emitters vazios (limitação do noclip, não do override). - Só doc/RE (REVISION) → NO mudança de comportamento. — CUSTOMMIX MUSIC SOLVED: trilha 145 "Challenge" tocando em batalha.** Lane Jarvis-HOOK. [previous:
v2.224.1.26] - A vitória: após 4 rotas falhas (
SetArenaBattleMusicPending→ só interceptores do Arena+;PrepBattleTrack→ camada de engine, não FMOD;PlayTrackWithPreload→ setavaevent_indexmas não populavatracks_array[].event_ptr),SwitchCrossfade(self, 145, 0, 1)desbloqueou — via IDA MCP emffxoficial.exe.i64(FFX.exe pid=49476). - Descoberta-chave (RE, commit
d4fdbc6c): a árvore de áudio FFX tem 3 camadas —PlayTrackByIndex(0x7097E0) pula silenciosamente setracks_array[track].event_ptr == 0;PlayTrackWithPreload(0x886980) só setaevent_indexno engine sub-struct;SwitchCrossfade(0x7089F0, caminho B) é a ONLY que populaevent_ptrviaReadEventByRuntimeId→MapRuntimeIdToFevIndex(tabela0xB4F1C8) →EventSystem->GetEvent. - Checks provando que 145 deveria tocar:
dword_B4F1C8[145] = 0x48(FEV índice 72, válido ≤181);unk_CEC164 = 0(o gate de load não bloqueia);IsValidTrackIndex(145) = true(145 ≤ 0xB5). - Fix em
MusicHook_Shim: no override, chamarSwitchCrossfade(overrideTrack, 0, 1)(fade=0, load_flag=1) em vez dePlayTrackWithPreload; preferir o trampolimg_trampolineSwitch(pula o shim, evita recursão). - RT2 confirmado pelo usuário: "NOW TRACK 145 WORKS! I'M IN BATTLE WITH THE NEW MUSIC!" — Challenge toca em CustomMix.
- Gate: build Release 0 erros; deploy Steam +
_isolated; commitd4fdbc6cenviado.
v2.224.1.27
v2.224.1.30BETAPATCH
Seymour5 de ago. de 2026
CustomMix Gil: custo de batalha NEVER cobrado (bug de condição de corrida) + compose nunca sobrescreve bins vanilla
- CustomMix Gil:
ArenaPlusComposePick_Close()zeravag_pendingLaunchGilCostANTESLaunchComboBattleFromPumppodia ler — Gil era validado no menu mas nunca cobrado (x3/x4/x5, desde que o compose foi implementado). A soma estava correta (e.g. 325000G para Trio) masgilCost=0no log. Fix: moveu o zero deClose()paraOpen()(reset session-open, não no close). - Compose sobrescrevia bins vanilla (d5e56701): 5 cenários cross-map (macalania_forest x3, remiem x3/x4/x5, bikanel x4) deployados no bin de template (
mcfr00_00,kino00_00,bika02_01) em vez do carrier dedicado (mcyt00_22,nagi05_23,nagi05_22) — o engine carregava encontros aleatórios em vez do time composto. C#:ResolveOutputBattleIdretornacarrier.BattleId. C++: o pin do hook usaroute.battleId(carrier) para o nome do encontro. Bins vanilla intactos. - Deploy: Hook DLL reconstruído + deploy Steam. Gate:
arena_plus_charge_gil.flag(ativo). - Fase 3 — id embutido RE: comparando magic_0140 vs magic_0141 (mesmo tamanho, 22 diffs), descobriu que o id não existe como u32 LE no .data — só como 3 strings UTF-16LE ("magic_0140" / "magic_0140.dll") nos offsets 0x07E3C6, 0x07E4B2, 0x07E4F2.
- Fase 3 —
MagicDllNameRewriter: reescreve as 3 strings para o novo id emTryCloneMagic(zero-padded de 4 dígitos = mesmo comprimento = sem shift de offset). Validado contra o DLL real: 3 ocorrências reescritas, delta de tamanho = 0 (RT0 byte-faithful fora das strings). - Fase 4 —
MagicCommandAssociation: associa uma command.bin ao clone setandoAnim1Id = newId(cadeia provada: command.Anim1Id → magic_%04d.dll). Campo EDIT (não grow) viaAbility_Command.WriteList(preserva o pool de texto). Limitação honesta: substitui o efeito visual da habilidade original; uma habilidade NEW (preservando a original) exigiria grow (referência:CommandGrowWriter.AppendElementWards). - Deploy: build LAB em
FFX\Mods\FFXProjectEditor-v2.224.1.29\. offline_ci: 8 falhas (todas PhaseManager/batalha preexistente → NONE do Magic/PPP).
v2.224.1.29
v2.224.1.31BETAPATCH
Seymour6 de ago. de 2026
F7 Marathon: 6 bugs + CustomMix Ultra + controle
- 6 bugs corrigidos: tela preta ao sair de F7 (0x13407E4 limpo em todos os caminhos de close), música Challenge vazando em batalha EVERY (F7_ApplyMusicBattle default=145 removido), double-input FSM vs menu (ClaimModal/ReleaseModal em submenus F7), spam de input segurando confirm/cancel (cooldown também no cancel), True Nightmare com elementos errados (agora HP 3x, stats ~2x, Haste+Regen+Protect+Shell, sem Weak/Resist/Absorb), Force Battle capturando Dark Aeons/Combos (filtro F7_SetSkipForceCapture).
- CustomMix Ultra Fase 1+2: engine de Compose C# (RunUltra — 1-8 monstros, auto-layout, deploy) + menu F7 integrado (Arena+ → CustomMix Ultra → Build+Launch). Carrier zzzz00_240, token 0x00F000F0. 13 logs de debug.
- Controle em ComposePick: L2=editar grid, R2=câmera, R1=próximo, L1=anterior via detecção de borda PadDir + fallback de teclado. Labels duplos PS+Xbox (L2-LT, R2-RT, L1-LB, R1-RB).
- Deploy: Hook DLL + Lab C# deployados no Steam. Planos: Monster AI Swap, Ultra Fases 3-4.
v2.224.1.30