# Steam development setup Steam support is optional. The default Godot build and every Phase 6 Docker check use ENet; they do not need a Steam client, SDK, or App ID. Selecting `transport="steam"` never falls back to ENet: a missing custom build or failed Steam initialization returns an error with the missing prerequisite. ## Pinned inputs The exact expected build inputs live in [`steam-dependencies.lock.json`](steam-dependencies.lock.json). They are not committed to this repository because the Steamworks SDK is governed by Valve's partner access and the engine binaries are platform-specific. Use the matching GodotSteam client build, server build, and `SteamMultiplayerPeer` extension from that lock file; do not mix release families. Place the resulting custom executables/templates outside this checkout and set: ```bash export COSMIC_CLASH_STEAM_CLIENT_GODOT=/absolute/path/to/godotsteam export COSMIC_CLASH_STEAM_SERVER_GODOT=/absolute/path/to/godotsteam-server make verify-steam-templates ``` The command imports the project with each custom build, checks the `steam` feature plus the `Steam`/`SteamServer` singleton and `SteamMultiplayerPeer`, then exports `Linux Steam Client` and `Linux Steam Dedicated Server`. It refuses to use a normal Godot binary, so a green result proves the expected native pieces are in the supplied builds. It writes only ignored `steam/build/` artifacts. ## App IDs and scope The local-development default is Valve's Spacewar App ID **480**. To use a different development App ID, set `COSMIC_CLASH_STEAM_APP_ID` to a positive integer and place `steam_appid.txt` beside the executable (never commit that file). Spacewar is only for local bootstrap/transport tests: it must not be used to advertise servers, validate ownership/VAC, or ship. A project-owned Steamworks App ID and its server credentials are required before Phase 7 server browser, `BeginAuthSession`, identity-backed slot reclaim, bans, or public hosting. Until then, Phase 6's external test is controlled-only because display-name slot reclaim is insecure. ## Transport contract `NetworkManager.host()` and `NetworkManager.join()` default to `"enet"`. Passing `"steam"` explicitly creates a `SteamMultiplayerPeer` over SDR; for this foundation the join address is the server's numeric Steam ID and the virtual port is zero. Discovery and server advertisement intentionally remain unimplemented until the project-owned App ID exists.