# Netcode revival (branch `netcode-revival`) Goal: revive Skate 3's **original** Xbox 360 multiplayer — the game's own RakNet-based peer-to-peer netcode — instead of only the ghost co-presence layer. `main` keeps the working ghost multiplayer + releases; this branch carries the netcode work and stays clearly separate. The transport is **RakNet over XNet/XSocket** (confirmed: rexglue's XNet comments reference RakNet, and the game's `socket → setsockopt → bind → sendto` sequence matches `RakPeer::Startup`). The game speaks its own protocol; we only need the **platform netcode layer to work** (implement rexglue's stubbed XNet session APIs + route the game's UDP through the relay). We do not decode the game protocol. ## Architecture - **Virtual addressing**: each machine gets a stable `XNADDR` (virtual IP `10.80.0.x` + unique 6-byte `abEnet` → RakNet GUID). `XNetXnAddrToInAddr` / `XNetServerToInAddr` resolve those into the socket layer's address space. - **Relay = P2P stabilizer**: session UDP is forwarded outbound through the relay (tagged `game` vs `ghost`) to the destination member's real socket; on a LAN the transport can go direct. The server stabilizes NAT/remote play but is not required on a LAN. - **Session registry in the relay**: `XNetQosListen` advertises a session; `XNetQosLookup` returns discovered sessions; the lobby/room-code UI stays as the manual join path. - **Ghost layer is kept** as the guaranteed fallback (co-presence that works for everyone even if the netcode path fails). ## Phase 0 — XNet session/address layer (done, rexglue `767bd6e`) Implemented in `rexglue-sdk/src/kernel/xam/xam_net.cpp`: - `XNetGetTitleXnAddr`: stable virtual identity (was loopback + `0xCC` MAC). - `XNetXnAddrToInAddr` / `XNetInAddrToXnAddr` / `XNetServerToInAddr` / `XNetXnAddrToMachineId` / `XNetInAddrToString`: resolve virtual addresses (were failure / `666.666.666.666`). - `XNetQosListen`: accept advertisement (was `X_ERROR_FUNCTION_FAILED`). - `XNetQosLookup`: success + empty `XNQOS` + completion signal (Phase 1 fills it from the relay registry). - `XNetCreateKey` / `XNetRegisterKey` / `XNetUnregisterKey`: session keys. - `XNetConnect` / `XNetGetConnectStatus`: report established. - `getsockopt`: real basic reads off the native socket. - `XNetSetSystemLinkPort`: accept. ## Phase 1 — relay game-transport + session registry (next) - Extend `ghost_relay` to forward game UDP between room members + expose the session list that `XNetQosLookup` reads. - Give rexglue `XSocket` a relay-transport mode (recognize `10.80.0.x` virtual destinations; route via the relay outbound). - Test: two game instances on one machine (loopback through the relay) reach a joined session. ## Phase 2 — invite UI - `XamShowGameInviteUI` / `XamShowFriendsUI` as ImGui `XamDialog`s backed by the relay lobby (real player list). Receive side (`XamNotifyCreateListener` / `XamSessionRefObjByHandle`) already works. ## Phase 3 — iterate to playable Whatever the game needs past discovery (RakNet handshake, ports, privilege fakes). Ghost stays as fallback throughout. ## Notes - Testing is done with **two instances on one machine** (no second device); the relay loops them via `127.0.0.1`. A headless harness may be added. - Build: `clang-22` override, preset `linux-relwithdebinfo`, per `docs/build.md` — same as `main`.