Export a Godot game for the web
This guide uses Citadel’s browser-safe Godot transport. It avoids the desktop
GDExtension completely and works through Godot’s built-in WebSocketPeer.
-
Enable Citadel’s WebSocket listener and publish it at a browser-reachable hostname. For an HTTPS game page, terminate TLS and expose a matching
wss://game.example.com:7352/endpoint; browsers reject an insecurews://endpoint from HTTPS. -
Build or download
citadel-client-godot-web-v<version>.zip, then extract it at the game’sres://root. It installsaddons/citadel/{protocol,client,web_client,rooms}.gdand includes a distributableweb/verification export with matched.html,.js,.pck, and.wasmfiles. Do not copy a.gdextensionor nativebin/folder into the Web-specific export. From a Citadel checkout, build it withGODOT_BIN=/path/to/godot make package-client-godot-web(or setGODOT_BINtoGodot.exeand run./make.ps1 package-client-godot-webon Windows). -
Instantiate
CitadelWebClientand drive its non-blockingpumpmethod from_process. Wait foris_open, then repeat the authentication helper until it returnsOK. -
Inspect the returned handshake
statusbefore sending gameplay messages. Then use the normalsend/pollloop and pass room events toCitadelRooms. -
In the Godot Export dialog, add a Web preset and export the project. Serve the
.html,.wasm,.pck, and JavaScript files over HTTP(S); do not open the HTML directly from disk. Keep their generated names together and configure the server to send.wasmasapplication/wasm. -
Verify the distributable application against a real local Citadel server. The archive’s
web/directory containscitadel-e2e.tomlandserve_web.py. With a Citadel checkout available, run:Terminal window cargo build --bin citadeltarget/debug/citadel --yes --config citadel-e2e.toml servepython3 serve_web.py --port 18080Then open
http://127.0.0.1:18080/index.html?citadel_ws=ws://127.0.0.1:17532/in a WebAssembly/WebGL2-capable browser. The app opens two browser clients, guest-authenticates, checks the Citadel position relay, and closes both connections.ws://is only valid for this loopback proof; deployed HTTPS pages must use a browser-trustedwss://endpoint.
The transport supports all reliable framed operations: authentication, correlated generic RPC, named rooms, notifications, chat events, and relayed messages. Authentication remains the first Citadel envelope, and gameplay sends are held until its reply succeeds. It does not support QUIC, unreliable snapshots, transform-sync, or native NetworkPeer codecs. See the Godot Web SDK reference for each method and error result.
Verification checklist
Section titled “Verification checklist”- The browser developer console has no mixed-content or certificate error.
is_openbecomes true beforeauthenticate_*reportsOK.- The auth dictionary contains a non-rejected status.
- A reliable RPC or room join receives its expected envelope in the single application-owned poll loop.
- CI verifies both the shared GDScript transport against a deterministic local
WebSocket fixture and the actual browser-loaded Godot
.wasmapplication against a running Citadel server; perform the final check from the deployed HTTPS origin with its productionwss://certificate andapplication/wasmMIME type.