Session resume — reload state and broadcast to peers (host+join) #4
Labels
No Label
blocked
bounced
in-progress
in-review
manual-only
needs-guidance
netplay
p1
p2
p3
rust
No Milestone
No project
No Assignees
1 Participants
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: pbwraith/gopher64-netplay#4
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Repo: gopher64-netplay (fork of https://github.com/gopher64/gopher64)
Context: Full scope doc at upstream analysis — see commit history. Netplay uses GGRS over WebRTC (matchbox_socket), reliable channel carries
NetplayMessage { name, data }in 16KB chunks. Savestates serialize full Device via postcard + compress.Goal: Host loads a
.netplay-statefile, then broadcasts the state to joining peers so everyone resumes at the saved frame.Background:
src/ui/netplay.rscurrently has no resume concept; session start sends cartridge saves only (ui/storage.rsload_saves)Acceptance:
.netplay-statefile; file picker like select_rom)send_netplay_state(message name from #1) BEFOREadvance_framestartsnetplay_state_readyack (timeout 30s; on timeout, disconnect that peer)netplay_state, loads viaload_savestate_from_datanetplay_state_readyackVerification:
cargo test; manual 2-player resume smoke test.Implementing lane 1 — PR ready for manual review.
PR: #18 — #18 (base
main, headissue-4, state open, mergeable)Branch commits (issue-#4 work, on the stacked dependency branch):
9097b45— session resume: reload saved state and broadcast to peers (#4)1bb409f— resume both sides at the saved GGRS frame (issue #5 reset_frame)92a4781— count same-batch peer acks in session-resume handshake (fixes 3+ player ack undercount: the by-name messages map collapses same-poll acks into one entry)79127f9— savestates: import netplay for reset_frame call (compile fix for #5's merged code)79e88dc— tests: fix resume mock session registration and RDRAM sizingAcceptance coverage:
.netplay-statefile picker mirroring select_rom); resume advertised to joiners via sessionresumefeature; after the player-number handshake, host loads its own state, resets the GGRS frame counter, broadcasts vianetplay_state, waits for every peer'snetplay_state_readyack (30s timeout → session abandoned, never started desynced).netplay_stateover the reliable channel, loads viaload_savestate_from_data, acksnetplay_state_ready.reset_frame(vendored ggrs, PR #9's patch — merged into this branch).Tests (
cargo test --libon the local worktree, full lib suite): 18 passed / 0 failedresume_state_reaches_peer_with_same_frame_metadata— mock 2-peer flow: host's in-memory savestate travels the chunked envelope, peer loads it, both agree on frame 12_345 and the peer's GGRS counter resumes thereresume_host_loads_state_from_disk_and_resets_frame— host path with real on-disk.netplay-state; device state + frame counter match the saved sessionack_batch_counts_every_ack— two acks in one poll both countedwait_for_ready_all_counts_acks_and_times_out— timeout pathresume_session_skips_non_resume_sessions— regular netplay untouchedcargo build --bin gopher64green;git diff --checkclean on the issue-#4 commits.Notes for the reviewer:
.cargo/config.toml,build.rs, clang-18/pkg-config/fcroot env,RUST_MIN_STACK=8388608for test threads,-lexpatlink arg) — none are part of this PR.cdylib(Android .so) target cannot link on this box (non-PIC static fontconfig/expat); bin + tests are the practical gate here.vendor/ggrs/examples/README.md(from #5's branch) is the onlydiff --checknit in the stack.