JARVIS-ARENA
Update 2.128
6/16/2026
v2.128.0.0MINORJarvis-ARENA
Arena+ Multi Dark Aeon custom-token resolver REDIRECT (Option A of the spike)
- (new DLL capability: the read-only spike grew the redirect path described in
FFX_ARENA_PLUS_CUSTOM_TOKEN_RESOLVER_HOOK_SPIKE.md). TheResolverLogHooknow has 2 modes: (a) LOGGER — previous behavior, default; (b) REDIRECT — opt-in viaarena_plus_custom_token_resolver.flag(env:FFXHOOKS_ENABLE_ARENA_PLUS_CUSTOM_TOKEN_RESOLVER). In redirect mode, BEFORE calling the vanilla trampoline, the shim consults acustomToken -> aliasTokentable (mandatory HIWORD range0xA001..0xAFFF); on a hit, the token is swapped for the vanilla alias so the resolver returns a legitimaterow. Downstream code cannot tell it was redirected; reverting = remove the flag or the DLL. New APIs inhooks/ResolverLogHook.h:SetCustomTokenRedirects(table, count)(cap 32, validates range),SetCustomTokenRedirectEnabled(bool),IsCustomTokenRedirectEnabled(),ResolverRedirectHitCount(). New sidecarmods/Spira Reforge/arena/spira-arena-custom-tokens.{json,schema.json}seeded with 4 entries (duo0xA0010046->0x00DC0046, trio0xA0020046->0x00DC0046, quartet0xA0030046->0x01AE0046, penta0xA0040046->0x01AE0046). Boot-time load viaArenaPlus_LoadCustomTokenRedirects()indllmain.cpp— search order:$FFXHOOKS_ARENAPLUS_CUSTOM_TOKENS_PATH-><DllDir>/mods/Spira Reforge/arena/spira-arena-custom-tokens.json-><DllDir>/spira-arena-custom-tokens.json; any I/O or parse failure keeps the hook in logger mode (zero regression). PolyHook build PASS 11/11 cpp. In-game RT2 Needs Test (waits until a launcher actually emits a custom token; not yet wired into any UI)
v2.127.0.0
v2.128.0.1REVISIONJarvis-MAGIC
Ronso Mana (6th RE pass): RUNTIME CLOSED — Kimahri's OD `−1` reduces to `WalkMenuBlobIndex(blob2,43)==0`; gauge/OD-ready DISCARDED for good (the `hudSafe=24` RT2 log proves it)
- (RE/docs + comments on the real
.i64; NO behavior change, DLL untouched — the other room keeps using it). Read thehudSafe=24RT2 log (%TEMP%\ffx-hooks.log) that theB0-resolvedetour was already capturing — this closes bug #1's causal chain. Evidence:B0 resolve a1=2 a2=1 treeId=43 a4=1 ->-1(onringKind=1ANDringKind=12) withP0 dispatch charge=100 max=100 590=0x0D(OD-ready FORCED: the hook already sets the 0x590 bits,79AF70returns 1,6C8, and pinsmax:=charge) — and OD stayed hidden. ⇒ OD-ready/charge==max is NOT the gate (closes out hudSafe 17–24). Also:blob2=0x1B5C8D70= a LIVE HEAP pointer (not the empty offlinesystem_00) → the gate is the blob's index, runtime data. Structural BREAKTHROUGH (symbol arithmetic, no runtime):dword_1134564[N] ≡ unk_C8F8D0[N+1217317]((0x1134564−0xC8F8D0)/4=1217317exact) ⇒dword_1134564[0](the countResolvereads) IS the countPushMenuTreeEntry(797B80)increments, anddword_1134564[2*v8+1537]IS the pushed entry → Push feeds exactly the node-def loop ofResolveMenuTreeNode(797D60);case 2 subtype=1→unk_112A994[8]=0x112A9B4=blob2. So the−1reduces toWalkMenuBlobIndex(blob2,43)==0⇒blob2[2+43]==0xFF(treeId 43 not registered) OR43>=blob2[1](count≤43). Since kind=1 (sel=1) AND kind=12 (sel=12) BOTH returned −1, it's the PRIMARY GATE (not the secondary selector).79BB70(BuildActorCommandMenu) decompiled and RULED OUT as the gate writer: it only builds the layer-A ring buffer (ringBase+1144*slot+catOffset, routingbyte241→+120/2→+72/3→+168/4→+296/0xE→+232; headerdword28&0x1000→+40/&0x800→+56/else→+0), it does not write the resolution blob oractor+0xF7C. 1 measurement left (blob2[1]count +blob2[2+43]idx) — I left a turnkey DIAG patch (≤6 lines, read-only) ready to paste into theB0-resolveshim in §12.4 of the doc, with the 3 refined fix candidates (B=writeblob2[2+43], C=redirect to thea2=0path like the Aeons, A=synthesize the node) decided by the dump in 1 RT2..i64comments (GOLDEN RULE, saved):0x797D60/0x797B80/0x797420/0x7985A0/0x112A9B4. Doc:docs/reverse/FFX_RONSO_MANA_COMMAND_RING_PIPELINE_RE_2026-06-16.md§12
v2.128.0.0