Extract op->real-handler map (handler(op)=ctx[0x26c93+op]) from the
registration routine's override stores; ghidra_handler_map.py +
build/op-handler-map.json (420 overrides). Cross-check vs opcodes.toml
found 0 real drift. One-shot Ghidra pass then labeled the /v2 image:
281 raw FUN_/LAB_ handlers -> op_0xNN_handler, 107 bare VAs -> functions,
31 hand-named preserved, opcode plate comment on every handler.
Includes the Task A spec + plan and the two-program (/v2 vs SMM) gotcha.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One-unit scope for the gfx animation cluster (0x1fd, 0x21c-0x243): channel
model + faithful gfx_object_anim_interpolate port on FrameClock (fixes 'mach 5')
+ spritesheet cell selection. Grounded in the recovered dispatch table
(handler(op)=ctx[0x26c93+op]; Kelebek labels are drift) + the reversed
interpolator. Bounded RE Task-0 with known handler addresses.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hybrid architecture (engine resolves RenderObject blend plan, host blits).
Grounded in fresh Ghidra RE of gfx_object_composite/blit + the 0x202/0x203
color workers (renamed+plate-commented, saved). Includes a bounded RE Task-0
(colorkey format, blend-mode source, color/alpha anim coupling).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Design artifacts for the merged frame-stepped VM work (throttle the Godot VM
to a per-frame op budget). Probes measured the native ~1788 ops/sec cadence
and uncapped D3D9 Present that motivated the wall-clock-op-rate approach.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The frame-paced-sleep slice did NOT make the opening burst animate (only the
one-shot dramatic pauses). Correct the canonical result (phase-a-slice-plan),
the RE doc (engine-re), the opcode source+generated ref (opcodes.toml 0xc8),
and add correction banners to the point-in-time spec/plan. Also folds in the
diagnostics + headless halt-at-wait results into phase-a-slice-plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native RE of the largest remaining SC0000 rendering GAP band: resolved every
handler in 0x21c-0x243 (+0x2bd/0x2bf) via the dispatch table (ctx[0x26c93+op]
from FUN_00413860). The cluster is ONE subsystem = sprite transform + animation/
tween; two members already named (0x234 anim_start, 0x238 set_anim_clock).
Decoded representative ops 0x220/0x21e (argc6, cmd-type 0xd, transform worker
(handle,op2,op3,f4,f5,f6); 0x21e normalizes floats /_DAT_00571c28 -> scale%);
worker gfx_anim_set_channel@0x47eaa0 arms an anim channel on the same object
model GfxState tracks. anim_start+set_anim_clock => a per-frame clock that makes
AE* fades animate rather than snap.
engine-re.md: full op->handler map + contract. Ghidra annotated (renamed
gfx_op_0x220_set_transform3_abs / gfx_op_0x21e_set_transform3_norm /
gfx_anim_set_channel + plate comments, saved).
Add the approved brainstorming spec for the opening-slice implementation
(wall-clock tween, opening-driven subset, passive GfxState + compositor tween +
alpha-aware blit).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reversed create/set/draw-texture handlers + gfx_render_frame: surfaces at ctx+0x52bd4[slot]
(set-texture loads a file with a colorkey); objects in the ctx+0x408 registry reference a
surface by slot (live) + rect + position (V24) + visible bit; render iterates the registry
in ASCENDING HANDLE ORDER (= z-order) and composites visible objects. Answers both unknowns
(z-order = handle; slot 0 not special). Design spec + Phase 1 plan rebuilt on this model,
replacing the flawed flat-layer version. Ghidra annotated (gfx_op_0x1f8/9/b, gfx_object_bind_draw,
gfx_render_frame, gfx_object_composite, gfx_op_0x20c_present_frame).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Typed ITraceSink/TraceEvent seam in Age.Engine (zero deps, allocation-free
hot path); relocate CallScript/OnStub off IHost; Null + Text sinks; CLI
--trace; Godot dispatch hack retired onto a sink. Serilog/EventSource
deferred to optional edge sinks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Design for making call-script actually execute (load target .BIN by id,
run nested sharing globals, return to caller). Scope: subroutine
execution only. Drops vm0.py from oracle duty; C# owns golden traces.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stand up bethington/ghidra-mcp loop; prove it by reversing SCJUMP's native
decision->scene resolver. Raw-dump-first, pe-sieve fallback; findings -> docs/engine-re.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Guarded-DFS decode of SCJUMP's DAG into (chapter, guards)->decision table;
VM witness cross-check; native decision->scene boundary documented/deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Curated single-source global registry modeled on opcodes.toml; static
story-flag discovery miner; sys4load labels from merged build/globals.json.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Recon of SC0000 label_12649 shows sprite/background geometry is computed in
bytecode; the only missing native primitive is 0x208 get-texture-size. Spec:
implement 0x208 (host returns real image dims) + a faithful 800x600 blit
compositor; defer fades/chromakey/multi-surface. Headless `gfx` diagnostic as
numeric oracle; --selftest/trace parity preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverse-engineering + open reimplementation workspace for Eushully's AGE/SYS4
engine (first target: Himegari). The repo root is age-reimpl/; the original game
install and the extracted ALF data are siblings outside the repo and are never
tracked. build/ (derived corpora) is gitignored and regenerated by the tools.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>