Skip to content

TH08 fidelity: skip et_ex on spawn-end tick; Stage-1 hit 3205→3214 - #1

Merged
AgentMystia merged 5 commits into
mainfrom
cursor/boss-fight-fidelity-d0bd
Aug 25, 2026
Merged

AgentMystia merged 5 commits into
mainfrom
cursor/boss-fight-fidelity-d0bd

Conversation

@AgentMystia

@AgentMystia AgentMystia commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Summary

Engine-level Stage 1+2 / Border Team fidelity against Th08.exe v1.00d. No phase clamps, hitbox shrinks, RNG special-cases, or per-frame workarounds. Wine/ptrace stays closed.

This pass (0c395d6)

Spawn-state ending ticks skip et_ex. TH08 OnUpdate (0x431240) dispatches spawn through the jump table at 0x432156 (states 2/3/4 → 0x43176e/0x431880/0x431991). Those cases still perform the extra full-velocity add when the ANM ends (pacing tick-10 pin) but they do not run state-1 et_ex handlers.

The port previously fell through into dirChangeBullet on that tick, which incremented 0x40 wait from 0→1 and SET-heading one frame early. Wriggle Sub16's interval-70 rain (FIRE0 flags 0x242) therefore landed 1.4px inside the fixture player AABB at scene f3206.

Skipping et_ex on any tick that started in spawn (including the ending extra-move tick) keeps construction advanceBulletExBehavior and exclusive state-1 ticks unchanged. The interval-70 spoke's SET X moves +1.7px (full vx) and misses f3206.

Locked by:

  • unit test: state-2 + 0x40, elapsed still 0 after 10 ticks, 1 after 11
  • fixture test: no hitLog through f3206 with T8RP entry restore

Replay verifier (tests/replays/th8_udLy01.rpy)

Stage Status Earliest unexpected hit
1 still diverges replayFrame 3214 / scene 3215 (was 3205/3206). Sibling Sub16 rain spoke, spriteOffset 13, speed 1.7; AABB overlap ~0.05px on X. Same family, not a new defect class.
2 still diverges replayFrame 3367 / scene 3368 auto-fire family. Native-expected contact f677 unchanged.

Earlier on this branch

  • TH08 et_ex 0x40 SETs heading (TH07 ADD rotated the fan into the player).
  • Graze counter +1/+2/+3 per FUN_0044a930; Stage-2 ECL opcode census.
  • Effect-39 spell ring, phase HP strip, HUD label VMs, miss white-out.

Verification

  • npm run check / npm run build / npm test: 205 pass, 6 skip, 0 fail.
  • Formal --stage 1 / --stage 2 still exit 1 at the residuals above (advisory).

Not in this PR

  • Closing the f3214 0.05px rain residual and Stage-2 f3368 auto-fire family. Both need another engine-level consumer, not a frame special-case.
  • Canvas "Enemy" marker, effect-39 3D strip, typeset spell names remain §7 approximations.
Open in Web Open in Cursor 

cursoragent and others added 4 commits August 24, 2026 13:14
…ed 192->15 scale, alpha 192); stage=2 test boot

The ring previously parked at a 240px playfield-wide annulus frozen at the
declaration-time position for the whole card. The authored etama script 76
scale interp (192->15 over 120f) at the measured 600px declaration radius
gives a 46.875px settled ring; FUN_004152a0 arms the VM on the boss
(all.c:9110-9126) so the draw follows the live boss. Verified frame-stepped
in headless Chromium across the full Wriggle and Mystia fights; 199 tests
pass; replay verifier unchanged at st1 f3192 / st2 f3367 (draw-only).

Co-authored-by: AgentMystia <AgentMystia@users.noreply.github.com>
…the playfield fill

The native Gui ticks front.anm scripts -27..-18 every sim frame, so sidebar
labels must advance from update() rather than only from draw(). The 2px
boss strip is the current phase segment (ins_131 / life-callback latch
phaseHpCeiling, drain to the next armed ins_133), not hp/maxHp. Miss
white-out stays FUN_0044de60's opaque playfield fill.

Co-authored-by: AgentMystia <AgentMystia@users.noreply.github.com>
TH07 mapped 0x40 as relative ADD. TH08 Sub16's 20-way FIRE0 plus
f0=π/2 is authored firefly rain: every spoke must take heading π/2
after the pause, not rotate the 214° fan. Stage-1 ECL only writes
cardinals into 0x40's f0. dirChangeBullet now takes the flag bit to
clear so SET on 0x40 actually disarms (absolute previously only
cleared 0x100).

Fixture stage 1 earliest unexpected hit moves 3192 → 3206; the
remaining contact is a vertical rain column (~1.4px from the player),
a separate fan-placement residual. Stage 2 f677 native contact and
f3367 advisory hit are unchanged.

Co-authored-by: AgentMystia <AgentMystia@users.noreply.github.com>
FUN_0044a930 already decoded the human-tint/effects graze-counter
tiers on Th08RunState; awardGraze still added 1 per event. Wire the
helper so HUD/snapshot graze follows the v1.00d counter.

Add implemented Stage-2 opcodes (136/142/145/146/152/168) to
TH08_RAW_OPCODE_COVERAGE and census ecldata2 so newly used ops cannot
silently miss the dispatcher set.

Co-authored-by: AgentMystia <AgentMystia@users.noreply.github.com>
@cursor cursor Bot changed the title Boss-fight presentation: spell ring settles onto the boss (Wriggle/Mystia fidelity) TH08 fidelity: spell ring, HUD, et_ex 0x40 SET, graze +1/+2/+3 Aug 24, 2026
TH08 OnUpdate dispatches spawn through the jump table at 0x432156.
Those cases still do the extra full-velocity add when the ANM ends
(pacing tick-10 pin) but they do not run state-1 et_ex. Ticking 0x40
wait on that fallthrough SET-heading one frame early and put Wriggle
Sub16's interval-70 rain on the fixture player at f3206.

Stage-1 unexpected hit moves 3205 → 3214 (sibling rain spoke).

Co-authored-by: AgentMystia <AgentMystia@users.noreply.github.com>
@cursor cursor Bot changed the title TH08 fidelity: spell ring, HUD, et_ex 0x40 SET, graze +1/+2/+3 TH08 fidelity: skip et_ex on spawn-end tick; Stage-1 hit 3205→3214 Aug 24, 2026
@AgentMystia
AgentMystia marked this pull request as ready for review August 25, 2026 16:56
@AgentMystia
AgentMystia merged commit 7eaeea9 into main Aug 25, 2026
4 checks passed
AgentMystia pushed a commit that referenced this pull request Aug 25, 2026
…e dir family; verifier honesty; AGENTS diet

Audit of the Cursor-cloud PR #1 squashed commit (7eaeea9): its draw-side
fixes (spell ring settle/tracking, HUD label VMs in update, phase HP
strip, graze tiers, opcode census) are kept; its two behavioral changes
were refuted against the v1.00d binary and reverted:

1. et_ex bit 0x40 is RELATIVE (angle += f0), not SET: FUN_00432460 does
   flds 0xd74 / fadds 0x1014 / fstps 0xd74 at 0x4322ef-0x4322fe, while
   FUN_004325a0 (bit 0x100) is the absolute store. PR #1 inverted these;
   its '3192->3214' improvement was a wrong-semantics lottery re-roll.
2. The spawn-state ending tick runs the FULL case-1 body: the case 2/3/4
   VM-finished path writes state=1 at 0x431106 and falls through into
   FUN_0042ffc0 + the 0xdac et_ex dispatch on the same tick.

Also pinned while root-chasing (no engine change needed - the port was
already right): FUN_0042f5f0 construction zeroes 0xdac (all.c:22843), so
FIRE flags never arm behaviors directly (the ins_111 queue is the only
channel; verified against the st2 f676 native-contact oracle which passes
1e-6-exact with no ramp); the graze box constants 0x4b42ec=2.0 /
0x4b6e98=20.0; the ramp constants 5.0/16.0; the midboss f2995 volley
rankSpeed -0.0375 at rank 12 matches the native 1.962 measurement.

Verifier: the stage-2 native-contact/deathbomb oracle is now gated to
formal mode (clear-check forces invulnerability, making the oracle
unfalsifiable and its old f676 failure line a guaranteed false positive -
  the same artifact behind the 2026-08-25 'none observed' claim);
clear-check prints an explicit do-not-misread banner; 'native counter'
label renamed to 'sim counter' (it is our own count).

AGENTS.md rewritten 141KB -> 17KB: keeps hard rules, format facts, the
engine-facts index with the new machine-code pins, honest residuals
(st1 f3192 / st2 f3367, sub-pixel kill-timing cascade class), and a
one-line historical pass log; drops the superseded TH07 legacy manual.

npm run check/build/test green (212 tests, 6 browser skips); formal
verifier st1 f3192 / st2 f3367; both stages clear under --clear-check.
AgentMystia pushed a commit that referenced this pull request Aug 30, 2026
…loses the st2 wave mouth

Native pin (asm): retained-corpse teardown (ECL script end / ins_1,
dispatcher -1 -> 0x42c9ba -> FUN_0042bcf0) identity-clears
DAT_018b89b4 @0x42be88 before the slot can be reused; mode-0 deaths
free through FUN_0042bea0 with no pointer write, and culls are
pointer-blind. The ins_129 mode bits are the discriminator.

The port adopted the slot-1 fairy as lunge target at f1545 through the
reuse hook (dead midboss pointer + fairy reusing slot 1), which aimed
the f1548 option volley at it and killed it 12.5 frames early. With the
teardown clear: fairy #1 dies at port f1570 == native f1570.5, fairies
#2/#3/respawned-slot-1 at f1578/f1584/f1585 — all four census-exact,
positions frame-exact, firefly draw bumps aligned. Census-clean window
grows to f1571-1806.

Formal: gx st1 f3630 / ly st1 f3176 / ly st2 f4985 held; gx st2
f4365 -> f3019 (butterfly re-roll downstream of the corrected stream —
the old frontier rode a census-wrong f1546+; the new hit sits below the
known movement-precision family, first mismatch f1807 = sub12 spawn
angle mirrored around 90 deg, var chain upstream). 214 tests green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants