Files
punktfunk/design/gamestream-host-plan.md
enricobuehler 7b99b41ede docs(design): trim shipped plans, consolidate cluster, add index
Much of design/ described work that has since shipped. Trim each doc to
its durable rationale + still-open items (the code is the source of truth
for shipped detail; git history holds the full originals).

- Shipped plans -> status stubs: stats-capture, gamestream-host-plan,
  apple-stage2-presenter, windows-service.
- Trimmed completed-out / open-kept: implementation-plan, hdr-pipeline,
  host-latency, gpu-contention (fixed stale status table), game-library,
  linux-setup (fixed m0->spike + stale zero-copy claim),
  session-aware-host-followups, windows-client-bootstrap,
  windows-dualsense-{scoping,game-detection}, windows-virtual-display,
  security-review (per-finding status table; #12 still open),
  apollo-comparison (shipped backlog collapsed to one-liners).
- Windows-host cluster consolidated: windows-host.md -> redirect into
  windows-host-rewrite.md (whose stale scorecard is corrected -- goal1 is
  merged, M4 done); windows-secure-desktop.md archived (now a fallback
  behind IDD-push primary).
- Kept evergreen: ci.md, gamescope-multiuser.md, windows-build-and-packaging.md.
- New design/README.md: per-doc status table + consolidated open-items
  roll-up so nothing is tracked in only one buried doc.
- Repoint 5 code comments to the archived secure-desktop doc path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:39:06 +00:00

3.3 KiB

title, description
title description
GameStream Host Stream to a stock Moonlight client on a client-sized virtual display.

Status: SHIPPED — works end-to-end with a stock Moonlight/Artemis client (initial merge ab6dda2, June 2026). Code: crates/punktfunk-host/src/gamestream/. Byte-level wire reference: research/gamestream-protocol-research.json (distilled from Sunshine + moonlight-common-c). This doc is trimmed to design rationale + open items; the shipped code is the source of truth for wire/packet detail.

A stock Moonlight client discovers this host, pairs, launches, and gets video + input + audio on a client-sized virtual display.

Architecture (respects the "one core" invariant)

  • punktfunk-core holds the P1 GameStream wire codec (ProtocolPhase::P1GameStream): the RTP+NV_VIDEO_PACKET framing, the GameStream FEC shard layout, and the video/audio AES-GCM/CBC paths. Hot path, native threads, no async. Kept beside punktfunk's native internal format (P2), selected by phase.
  • punktfunk-host holds the control plane (tokio/axum OK — I/O-bound, not the hot path): mDNS discovery, nvhttp serverinfo + the 4-phase pairing, the RTSP handshake, the ENet control stream + input injection, the virtual-display lifecycle, and Opus audio encode.

Why we shipped in this order (the two highest interop risks)

These two mitigations are why early bring-up deliberately skipped crypto and FEC — both turn out to be unnecessary on a clean LAN, and both have a wire-incompatibility that would have silently broken interop if done naively.

  1. RS-FEC matrix incompatibility — clean-LAN first. Sunshine + Moonlight both use nanors (GF(2⁸), poly 0x11d, Vandermonde systematic). punktfunk-core uses reed-solomon-erasure (Cauchy) — parity bytes don't match, so Moonlight silently fails to recover any frame with a lost data shard. Mitigation: on a clean LAN with no loss the client never runs RS decode, so we deferred it — get a frame decoded first, then port nanors for loss recovery.
  2. Crypto layout incompatibility — plaintext video first. punktfunk's SessionCrypto (salt + seq-as-AAD) is wire-incompatible with GameStream's GCM; P1 needs a separate GameStream GCM path (key = raw 16-byte RIKEY, IV = counter_le[8]||0,0,0||'V'(0x56), no AAD, FEC first, then encrypt per shard). Mitigation: video encryption is negotiated and usually off on LAN — we implemented plaintext video first and added GCM later.

Open items

  • HDR / 10-bit. Needs HDR capture + metadata plumbing. (av1_nvenc -highbitdepth 1 already encodes Main10 from 8-bit input on this box.)
  • Reconnect-at-new-mode robustness.
  • AV1 negotiation. Implemented + unit/live-capture tested; needs a live confirmation with a stock Moonlight client (select AV1 in a stock client).
  • Surround 5.1/7.1 audio. Implemented + tested; needs a real listen including FEC under loss, plus a live Moonlight confirmation.

Testing note

The host is headless; end-to-end needs a stock Moonlight client on the LAN pointed at this box (manual "add host" by IP works without mDNS). /serverinfo + the pair flow are testable with curl; video needs a client that can display.