Skip to content

guest sdk: large-room callbacks — roster-epoch ctx mode + declared heartbeats + Rust parity#27

Merged
BCook98 merged 1 commit into
mainfrom
large-room-callbacks
Jun 7, 2026
Merged

guest sdk: large-room callbacks — roster-epoch ctx mode + declared heartbeats + Rust parity#27
BCook98 merged 1 commit into
mainfrom
large-room-callbacks

Conversation

@BCook98

@BCook98 BCook98 commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

The kit half of the large-room-callbacks change (engine half follows; design lives in the platform's spec workspace). Targets the two measured per-callback costs in large rooms plus heartbeat flexibility.

1. Ctx roster-epoch mode — opt-in via GameMeta.CtxFeatures

The host re-sends the full member list in every callback payload (~100KB/callback at 1000 players — the dominant input-path cost, and the residual -gc=leaking leak). With kit.CtxFeatRosterEpoch declared, the member section becomes sentinel-keyed (ABI.md §4.1):

memberCount meaning
0x0000..0xFFFD legacy full roster — byte-identical to today
0xFFFE full roster at a u32 epoch
0xFFFF unchanged since epoch — 6 bytes total

Both SDKs decode the sentinels into an epoch-aware roster cache (zero member allocations on the unchanged form); full forms are authoritative; an epoch mismatch logs once and degrades to the cached roster. Legacy guests never see the new forms; pre-feature hosts keep working via the retained byte-skim cache. ABI major stays 2.

2. GameMeta.HeartbeatMS — declare your tick

Validated (0 or 20..1000) at meta encode; rides a new always-written, presence-guarded meta trailer with the features bitset (ABI.md §4.2). shellcade-kit play honors it locally. Host-side precedence: admin host.heartbeat_ms > declaration > 50ms default.

3. Rust crate parity (including a v2.5.0 gap)

v2.5.0's rosterCap 16→1024 + lazy baselines shipped Go-only — the Rust crate still silently dropped send for index ≥ 16. This PR brings the Rust crate to full parity: ROSTER_CAP 1024, per-slot lazy baselines, allocated-only broadcast reconcile, both new meta fields, sentinel decode, and an Rc-shared epoch roster cache. Golden vectors pin Go/Rust meta encodings byte-identical (trailer bytes cross-checked against the actual Go encoder).

Also

  • GUIDE.md: new "Large rooms" authoring section — declare heartbeat + feature, render-on-change dirty tracking, Members() lifetime contract.
  • Tests: wire sentinel round-trips + legacy byte-identity golden + trailer presence-guards both directions; SDK epoch-cache behavior incl. AllocsPerRun ceiling on the unchanged form; meta validation panics; Rust sentinel decode + trailer golden + lazy-reconcile contract. go test ./... and cargo test green.

Sequencing: merge + tag v2.6.0 → engine PR pins it.

🤖 Generated with Claude Code

…artbeats + Rust parity

The kit half of the large-room-callbacks OpenSpec change. Three pieces:

Ctx roster-epoch mode (negotiated via GameMeta.CtxFeatures bit 0): the
member section gains sentinel forms — count 0xFFFE = full roster at a
u32 epoch, 0xFFFF = unchanged-since-epoch (6 bytes total) — emitted
only to guests that declare the feature; legacy guests stay
byte-identical and real counts (<= 0xFFFD) keep the legacy layout, so
all four host/guest version pairings are unambiguous. Both SDKs decode
the sentinels into an epoch-aware roster cache: zero member
allocations on the unchanged form (the byte-skim cache stays for
pre-feature hosts), full forms are authoritative, and an epoch
mismatch degrades to the cached roster with a single warning, never a
trap. ABI major stays 2 (ABI.md §4.1).

GameMeta.HeartbeatMS: games declare their wake cadence (validated 0 or
20..1000 at meta encode, the config-specs fail-fast posture). It rides
a new always-written, presence-guarded meta trailer with the features
bitset (ABI.md §4.2); shellcade-kit play honors it locally; host
precedence is admin config > declaration > 50ms default.

Rust crate parity: mirrors the meta fields, sentinel decode, and an
Rc-shared epoch roster cache — and picks up the v2.5.0 Go-only
baseline work it missed: ROSTER_CAP 16 -> 1024 with lazily-allocated
per-slot baselines and allocated-only broadcast reconcile. Golden
vectors pin Go/Rust meta encodings byte-identical (trailer bytes
cross-checked against the Go encoder).

GUIDE.md gains the large-room authoring section (declare heartbeat +
feature, render-on-change dirty tracking, Members() lifetime).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@BCook98
BCook98 merged commit 6df5bea into main Jun 7, 2026
5 checks passed
@BCook98
BCook98 deleted the large-room-callbacks branch June 7, 2026 00:46
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.

1 participant