Clarifies that releases ship ONLY the recompiled binaries (skate3 +
librexruntime + ghost_relay + README) - never the game files; the game dump
(default.xex + EAWebkit.xex) is required at BUILD TIME for codegen only.
- tools/release/release.sh: builds + packages a per-platform release zip
(configure -> codegen -> build -> zip), prints a sha256sum, and with
--upload creates/updates a Forgejo Release and attaches the zip via the
API (GITEA_TOKEN). Supports linux/windows/macos presets on their native
hosts.
- .forgejo/workflows/release.yml: optional automation - builds on a
self-hosted Docker runner (ubuntu-24.04 label), self-heals the broken
nested submodule pins via tools/ci/init-submodules.sh, and publishes a
Linux release on v* tags. Needs the game dump mounted on the runner
(codegen only, never uploaded), SUBMODULE_KEY + RELEASE_TOKEN secrets.
- tools/ci/init-submodules.sh: recursive submodule init that self-heals
upstream pins a fresh clone can no longer fetch (the rexglue fork pins
thirdparty/imgui to a commit ocornut/imgui dropped; the script checks out
the upstream default tip for any nested submodule left empty).
- docs/releases.md: what's in a release, the local path, and the optional
CI path.
- .gitignore: keep tools/ci + tools/release, ignore local release zips.
- docs/ghost-multiplayer.md: the full beta guide - player usage, cvars,
relay deployment (VPS build/install, free-tunnel option, verification),
logging/troubleshooting and security notes.
- tools/ghost_relay.service: hardened systemd unit for the public relay
(Restart=on-failure, NoNewPrivileges, PrivateTmp, ProtectSystem).
- tools/ghost_relay_deploy.sh: one-shot build + install + enable script for
the VPS (GHOST_RELAY_PORT / GHOST_RELAY_VERBOSE overrides; opens the UDP
port via ufw). Verified: the exact build line compiles and runs.
- README: multiplayer pointer under 'How Do I Play?'.
Bolt-on multiplayer layer confined to src/native and hand-written code (no
codegen output touched):
- GhostRelay core (src/native/skate3_native_ghost_relay.*): small UDP relay
matching clients into rooms by a shareable code; forwards each client's
pose to the other room members. Used by both the standalone binary and
the in-game LAN host fallback.
- Standalone server (tools/ghost_relay_main.cpp, ghost_relay target): runs
on a public VPS or behind a free tunnel; clients connect OUTBOUND, so no
port forwarding is needed on any client.
- In-game module (skate3_native_ghost.*): captures the local player's world
transform at Sk8::UpdateBoneTransforms exit (pack-owner entity +416,
verified layout) and broadcasts it at a fixed rate; auto-connects to the
default public relay, falls back to LAN auto-host + UDP broadcast
discovery when unreachable.
- Renderer: draws a solid-color cube per remote player in RenderScene via
the existing scene PSO tint.a>0 branch (no new shader/SPIR-V).
- UI: GhostDialog (M key) with enable toggle, room code, relay override,
status readout. Off by default.
Wire protocol in skate3_native_ghost_proto.h (JOIN/HELLO/POSE/PING/LEAVE).