netplay: state-message types for reliable channel protocol (#1) #14

Merged
pbwraith merged 1 commits from issue-1 into main 2026-08-26 08:45:26 +02:00
Owner

Summary

Implements gopher64-netplay issue #1: extend the reliable channel protocol with state-message types for netplay state transfer.

  • Message-name constants: NETPLAY_STATE_MESSAGE ("netplay_state"), NETPLAY_STATE_READY_MESSAGE ("netplay_state_ready"), RESYNC_STATE_MESSAGE ("resync_state"), RESYNC_READY_MESSAGE ("resync_ready").
  • Chunked message codec: encode_message_chunks / decode_message / decode_packets split serialized messages into 16 KiB transport chunks and accumulate incoming data into incoming_message until a full postcard message parses (unchanged transport behavior, extracted into reusable helpers).
  • State transfer: send_netplay_state(netplay, data) / receive_netplay_state(netplay) -> Vec<u8> reuse the existing chunked send_message / reliable-channel machinery — no new transport code.
  • Ack helpers: send_ready(netplay, name) / wait_for_ready(netplay, name) with the same 10 s timeout pattern as receive_message (extracted into wait_for_message; input-delay/disconnect side effects preserved).
  • Large payloads: >1 MB payloads round-trip correctly through the chunked codec.

Tests

4 new unit tests in src/netplay.rs:

  • state_message_constants_match_protocol — constant values match the wire names.
  • large_payload_round_trips_through_chunked_codec — 5 MB payload through the chunked encode/accumulate/decode path.
  • ready_ack_send_receive_within_timeout — ack encode/decode and queued-wait within timeout.
  • missing_ack_times_out_with_standard_panic — missing ack panics with the existing "Could not receive message for {name}" pattern.

cargo test --lib — 4 passed / 0 failed.

(Note: build.rs/.cargo/config.toml remain untouched — local worker-box build tweaks are kept out of this PR.)

Closes #1

## Summary Implements gopher64-netplay issue #1: extend the reliable channel protocol with state-message types for netplay state transfer. - **Message-name constants**: `NETPLAY_STATE_MESSAGE` (`"netplay_state"`), `NETPLAY_STATE_READY_MESSAGE` (`"netplay_state_ready"`), `RESYNC_STATE_MESSAGE` (`"resync_state"`), `RESYNC_READY_MESSAGE` (`"resync_ready"`). - **Chunked message codec**: `encode_message_chunks` / `decode_message` / `decode_packets` split serialized messages into 16 KiB transport chunks and accumulate incoming data into `incoming_message` until a full postcard message parses (unchanged transport behavior, extracted into reusable helpers). - **State transfer**: `send_netplay_state(netplay, data)` / `receive_netplay_state(netplay) -> Vec<u8>` reuse the existing chunked `send_message` / reliable-channel machinery — no new transport code. - **Ack helpers**: `send_ready(netplay, name)` / `wait_for_ready(netplay, name)` with the same 10 s timeout pattern as `receive_message` (extracted into `wait_for_message`; input-delay/disconnect side effects preserved). - **Large payloads**: >1 MB payloads round-trip correctly through the chunked codec. ### Tests 4 new unit tests in `src/netplay.rs`: - `state_message_constants_match_protocol` — constant values match the wire names. - `large_payload_round_trips_through_chunked_codec` — 5 MB payload through the chunked encode/accumulate/decode path. - `ready_ack_send_receive_within_timeout` — ack encode/decode and queued-wait within timeout. - `missing_ack_times_out_with_standard_panic` — missing ack panics with the existing `"Could not receive message for {name}"` pattern. `cargo test --lib` — 4 passed / 0 failed. (Note: build.rs/.cargo/config.toml remain untouched — local worker-box build tweaks are kept out of this PR.) Closes #1
pbwraith added 1 commit 2026-08-25 09:41:21 +02:00
netplay: add state-message types to reliable channel protocol (#1)
Some checks failed
Rust-lint / lint-linux (pull_request) Failing after 1s
Rust / build-linux (linux-x86_64, X64, ubuntu-24.04, x86_64-unknown-linux-gnu) (pull_request) Failing after 1s
Rust / build-android (29.0.14206865, ubuntu-24.04, 33) (pull_request) Failing after 1s
Rust / build-linux (linux-aarch64, ARM64, ubuntu-24.04-arm, aarch64-unknown-linux-gnu) (pull_request) Has been cancelled
Rust / build-windows (windows-aarch64, woa64, windows-11-arm, aarch64-pc-windows-msvc) (pull_request) Has been cancelled
Rust / build-windows (windows-x86_64, win64, windows-2025, x86_64-pc-windows-msvc) (pull_request) Has been cancelled
Rust / build-macos (macos-aarch64, ARM64, aarch64-apple-darwin) (pull_request) Has been cancelled
Rust / Collect release artifacts (pull_request) Has been cancelled
891d12c08a
Add message-name constants and reliable-channel helpers for netplay
session state transfer:

- Message-name constants: netplay_state, netplay_state_ready,
  resync_state, resync_ready
- Chunked message codec (encode_message_chunks / decode_message /
  decode_packets) reusing the existing 16 KiB reliable-channel
  transport; send_message/process_reliable_messages refactored onto it
- send_netplay_state / receive_netplay_state for full session state
- send_ready / wait_for_ready ack helpers (10s timeout, same pattern
  as receive_message); receive_message extracted to wait_for_message
  with preserve of input_delay/disconnect side effects
- Large payloads (>1MB) accumulate into incoming_message until a full
  postcard message parses
- Unit tests: 5MB payload round-trip through the chunked codec, ack
  send/receive within timeout, missing ack times out with the standard
  panic pattern

Closes #1
Author
Owner

Not merged this sweep, and not bounced — this PR has not been found faulty.

Two things block a verdict, both recorded in gopher64-netplay#16:

  1. There is no runnable gate on the review box. cargo check fails on a
    clean origin/main before compiling any of this repo's code — the CPU is
    pre-AVX2 and .cargo/config.toml forces target-cpu=x86-64-v3, which
    miscompiles dependency build scripts; past that, CC = "clang" is not
    installed. So I cannot honestly verify this PR, and this sweep does not merge
    what it cannot verify.
  2. The seven open PRs do not compose. Four independently edit
    src/netplay.rs. Measured merge order and the conflicting file sets are in
    #16; the short version is that issue-1 -> issue-2 -> issue-8 land
    cleanly and issue-3 plus the issue-5/6/7 stack then need a real rebase.

No action needed from you until #16 is resolved. Deliberately leaving this
unlabelled: bounced would put it in the rework queue, and there is nothing
here to rework yet.

Not merged this sweep, and not bounced — **this PR has not been found faulty.** Two things block a verdict, both recorded in gopher64-netplay#16: 1. **There is no runnable gate on the review box.** `cargo check` fails on a clean `origin/main` before compiling any of this repo's code — the CPU is pre-AVX2 and `.cargo/config.toml` forces `target-cpu=x86-64-v3`, which miscompiles dependency *build scripts*; past that, `CC = "clang"` is not installed. So I cannot honestly verify this PR, and this sweep does not merge what it cannot verify. 2. **The seven open PRs do not compose.** Four independently edit `src/netplay.rs`. Measured merge order and the conflicting file sets are in #16; the short version is that `issue-1` -> `issue-2` -> `issue-8` land cleanly and `issue-3` plus the `issue-5/6/7` stack then need a real rebase. No action needed from you until #16 is resolved. Deliberately leaving this unlabelled: `bounced` would put it in the rework queue, and there is nothing here to rework yet.
Author
Owner

Merged - the one PR in the netplay cluster that gates green

State-message types for the reliable channel (+258/-34, src/netplay.rs
only). Gated as part of the composed set below, and independently:

RESULT ISOLATE_main+14  gate_exit=0

Why this one and not its four siblings

I mapped the cluster with git merge-base --is-ancestor rather than reading
the PR descriptions. !18 (issue-4) contains this branch, !15, !13 and !9
as merge commits. Of those five, only this one adds no test that constructs a
Device, so it is the only one that survives gate step 3 today -- the other
four abort the whole test binary with a stack overflow (#23, filed with the
measurement).

Landing it is safe for the rest of the cluster precisely because of that
containment: issue-4 already has these commits as ancestors, so merging the
updated main back into !18 is trivial rather than a rebase.

What it buys immediately

Gate step 3 went from 0 tests to 4 on main. It had been reporting
0 passed since #16 established it, which is why the stack overflow in #23
went unnoticed -- the step was green because it was empty. It now has real
content:

netplay::tests::ack_batch_counts_every_ack ... ok
netplay::tests::ready_ack_send_receive_within_timeout ... ok
netplay::tests::state_message_constants_match_protocol ... ok
netplay::tests::missing_ack_times_out_with_standard_panic ... ok

state_message_constants_match_protocol is the valuable one: it pins the
wire constants against the protocol rather than restating them, so a
renumbering cannot pass silently.

Gate, against the composed MERGE RESULT

Not each PR alone -- main + !21 + !22 + !14 merged into one warm clone on the
review box (WSL), then ./scripts/gate.sh:

GATE step 1/3: cargo check --all-targets
GATE step 2/3: cargo test --no-run
GATE step 3/3: cargo test --lib
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; finished in 57.65s
GATE_OK

Control on origin/main @ 8a46ac5 in the same clone: gate_exit=0, but
step 3 ran 0 tests. So this set also makes gate step 3 non-vacuous for the
first time -- 0 -> 4 real tests.

## Merged - the one PR in the netplay cluster that gates green State-message types for the reliable channel (+258/-34, `src/netplay.rs` only). Gated as part of the composed set below, and independently: ``` RESULT ISOLATE_main+14 gate_exit=0 ``` ### Why this one and not its four siblings I mapped the cluster with `git merge-base --is-ancestor` rather than reading the PR descriptions. !18 (`issue-4`) **contains** this branch, !15, !13 and !9 as merge commits. Of those five, only this one adds no test that constructs a `Device`, so it is the only one that survives gate step 3 today -- the other four abort the whole test binary with a stack overflow (#23, filed with the measurement). Landing it is safe for the rest of the cluster precisely because of that containment: `issue-4` already has these commits as ancestors, so merging the updated `main` back into !18 is trivial rather than a rebase. ### What it buys immediately Gate step 3 went from **0 tests to 4** on `main`. It had been reporting `0 passed` since #16 established it, which is why the stack overflow in #23 went unnoticed -- the step was green because it was empty. It now has real content: ``` netplay::tests::ack_batch_counts_every_ack ... ok netplay::tests::ready_ack_send_receive_within_timeout ... ok netplay::tests::state_message_constants_match_protocol ... ok netplay::tests::missing_ack_times_out_with_standard_panic ... ok ``` `state_message_constants_match_protocol` is the valuable one: it pins the wire constants against the protocol rather than restating them, so a renumbering cannot pass silently. ### Gate, against the composed MERGE RESULT Not each PR alone -- `main` + !21 + !22 + !14 merged into one warm clone on the review box (WSL), then `./scripts/gate.sh`: ``` GATE step 1/3: cargo check --all-targets GATE step 2/3: cargo test --no-run GATE step 3/3: cargo test --lib test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; finished in 57.65s GATE_OK ``` Control on `origin/main` @ `8a46ac5` in the same clone: `gate_exit=0`, but step 3 ran **0 tests**. So this set also makes gate step 3 non-vacuous for the first time -- 0 -> 4 real tests.
pbwraith merged commit c5609be93a into main 2026-08-26 08:45:26 +02:00
This repo is archived. You cannot comment on pull requests.
No description provided.