Fix replay verify for replays > 720 frames; add SSB64_RIG_EXIT and port_exit_process() (decomp bump + docs) - #265
Open
teslat0mic wants to merge 4 commits into
Open
Conversation
…EXIT docs/bugs/replay_verify_ring_window_2026-08-29.md documents the false negative (verify re-read the 720-entry input ring) and the fix; netplay docs updated for the new verify semantics and the SSB64_RIG_EXIT batch exit code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FDMaJejZnPFRN3jP6szrCs
decomp dbac284: the published-input checksum is now accumulated inside
syNetInputFuncRead() where the VS tick advances (frozen at the replay's
frame count), the dead ring-based checksum is deleted (0919e73), playback
that ends before the replay stream reports INCOMPLETE, and SSB64_RIG_EXIT
exits 0/1/2.
port/port_log.{c,h}: port_exit_process(code) - flush the log and stdio,
then TerminateProcess() on Windows / _exit() elsewhere. _exit() on
Windows runs ExitProcess, which kills the other threads and then runs
every DLL's DLL_PROCESS_DETACH on the calling thread; at VS scene
teardown that produced STATUS_FAIL_FAST_EXCEPTION (0xC0000602) instead
of the exit code. TerminateProcess skips all of it.
Docs: bug write-up rewritten for the final design and the exact
verification done (all synthetic input files; no live-controller
record->play round trip yet), API table and validation-path text no
longer reference the deleted function, exit code 2 documented.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FDMaJejZnPFRN3jP6szrCs
A controller-recorded 1800-frame match (MSVC build) replays PASS on both MSVC and clang; the same file with one button flipped at tick 900 FAILs with exit 1 on both. Replaces the "no human recording round-tripped" caveat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FDMaJejZnPFRN3jP6szrCs
…ck in port_exit_process() port_exit_process(): fall through to _exit() if TerminateProcess() ever returns, so a failed terminate can never resume the game with a bogus exit code. Docs: exit code 3 (LOADFAIL), the frame_count == 0 rejection, and the write-up's Status line now lists every touched file (netinput.c/.h, netreplay.c, port_log.c/.h). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FDMaJejZnPFRN3jP6szrCs
Author
|
Follow-up pushed (dd79e13, decomp 6adc1c5): exit code 3 = LOADFAIL when the replay file fails to load (previously no verdict, no exit — a batch runner would hang); loader rejects |
teslat0mic
force-pushed
the
rig/t1-state-trace
branch
from
August 30, 2026 02:33
75f2d32 to
dd79e13
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Companion to the decomp PR JRickey/ssb-decomp-re#14. Bumps the
decompsubmodule to pick up thenetreplay/netinputfix, adds the one port-layer helper it needs, and documents it.The bug:
SSB64_REPLAY_PLAYverification re-readsSYNetInputHistory— the 720-entry rollback input ring — at the end of playback, so for the default 1800-frame recording it hashed only ticks 1080–1799 while the recorded checksum covered all 1800. Every default recording reportedresult=FAILregardless of determinism.The fix (decomp):
syNetInputFuncRead()accumulates the published-input checksum at the point it advances the VS tick (so it agrees with the recorder by construction, including under the bootstrap P2P start barrier), frozen at the replay's frame count; the dead ring checksum is deleted; playback that ends before the replay stream reports INCOMPLETE;SSB64_RIG_EXIT=1makes the verdict the process exit code (0/1/2).This PR
port/port_log.{c,h}:port_exit_process(int code)— flush the log and all stdio streams, then terminate immediately:_exit()on POSIX,TerminateProcess()on Windows. On Windows_exit()isn't enough — it runsExitProcess, which kills the other threads and then runs every DLL'sDLL_PROCESS_DETACHon the calling thread; at VS scene teardown that producedSTATUS_FAIL_FAST_EXCEPTION(0xC0000602) instead of the exit code. (+28 lines.)docs/bugs/replay_verify_ring_window_2026-08-29.md— symptom, root cause with the arithmetic proof, final design, exactly what was and wasn't verified, audit hook ("end-of-run validation that re-reads a bounded ring is only valid for runs shorter than the ring"). Indexed indocs/bugs/README.md.docs/netplay_architecture.md,docs/netcode_agent_rules.md— API table and validation-path steps updated for the new functions (no more references to the deleted one),SSB64_RIG_EXITand exit code 2 documented.decomp→dbac284(3 commits; details and the verification table in the decomp PR).Verification
Live round trip: a controller-recorded 1800-frame match (human Fox vs 3 CPUs) replays PASS/exit 0 on MSVC 14.43 and clang 18; the same file with one button flipped FAILs/exit 1. Synthetic replays on both compilers: neutral CPU-vs-CPU FAIL→PASS; pseudo-random human input PASS; two corruption controls FAIL/exit 1; replay-longer-than-match INCOMPLETE/exit 2. Same checksums on both compilers. Details in the write-up.
Where this is going (so you can steer early)
I'd like to contribute rollback netplay on top of the netinput/netreplay/netpeer foundation, rig-first: a determinism harness you can trust before any snapshot/rollback code lands. Rough sequence, each as a small separate PR:
libmtrig on Windows;syNetInputFuncReadseam.If any of that conflicts with plans you or TechnicallyComputers already have, tell me and I'll adapt — I'd rather build what you'd merge.
🤖 Generated with Claude Code
https://claude.ai/code/session_01FDMaJejZnPFRN3jP6szrCs