A complete multiplayer XBOX game, built in Godot 4. NetRumble is a 2D top-down space shooter: dodge the asteroids, grab laser, rocket and mine pick-ups, and shoot your friends for points. Lobby and party voice chat, invites straight from the guide, achievements and a saved match history, all in the box.
Most platform samples show you one API at a time against a stub. NetRumble wires every Microsoft GDK and PlayFab service into the place a shipping title would really call it, so you can watch sign-in, privileges, privacy, Party networking and account-owned Game Saves work around an actual game loop, and then go and play the result. It is a working reference, not a certified title.
Built with GDScript and the XBOX Godot Sample
GDK/PlayFab addons, pinned as a submodule at external/xbox-godot-sample and built into
addons/.
Important
This is a source-only sample, not a shipping game. NetRumble is MIT-licensed at the game layer; the Microsoft GDK, PlayFab and XBOX Godot Sample dependencies still require their own installs and license acceptance, consistent with other XBOX samples. There is no specified update cadence for support or maintenance. We'll watch the repo, monitor issues, and iterate where it makes sense, but this isn't a commercial release. We are excited to hear your feedback, and see any community PRs, as we evolve this together.
All gameplay needs an account and ready Game Saves. Sign-in, Lobby discovery, Matchmaking, Party, privileges, achievements and Game Save all run against the XDKS.1 sandbox and title, which needs an XBOX publishing relationship and a test account from that sandbox. Without it you can still clone, build and inspect the project, but cannot play, including Practice. Sign-in or save-loading failures offer Retry / Back, not unsaved play. Please join the XBOX Developer Program to get access.
Every platform feature in the sample, and the environments it runs in. This is what the code is built to do rather than a record of live test results; service availability, title access and account policy still apply.
| Feature | XBOX on PC | XBOX Series X|S | Debug desktop custom-ID | Offline |
|---|---|---|---|---|
| XBOX identity → PlayFab authentication | XBOX-linked | XBOX-linked | PlayFab custom-ID only | Platform-dependent; not guaranteed at cold launch |
| PlayFab Lobby discovery + Party transport | Yes, after saves are ready | Yes, after saves are ready | No gameplay; diagnostics only | Unavailable |
| PlayFab Matchmaking (Quick Match) | Yes, after saves are ready | Yes, after saves are ready | No gameplay | Unavailable |
| PlayFab Party voice + in-match typed text | Subject to XBOX policy | Subject to XBOX policy | No gameplay | Unavailable |
| XBOX privileges, privacy, string verification, reporting | Yes | Yes | Bypassed / unavailable | Unavailable |
| XBOX friends, activity, invites, recent players | Yes | Yes | Unavailable | Unavailable |
| XBOX achievement reporting | Yes | Yes | No gameplay progress | Same-account counters; service reporting needs connectivity |
| GlobalScore standalone leaderboard | Online-match writes subject to title policy; top-10 reads | Online-match writes subject to title policy; top-10 reads | No gameplay; lower-level API diagnostics only | No submission or cached board; Practice stays local |
| Xbox XGameSaveFiles roaming | Per-account synced folder | Per-account synced folder | Unavailable without a signed-in XboxUser | No cloud sync while disconnected |
| Settings, history and counters | Account-owned Game Saves | Account-owned Game Saves | No save cache or gameplay | Platform-managed account folder only, if ready |
| Lifecycle / controller detection | Focus and device detection | Suspend/resume, constrain, association detection | Desktop behavior | Platform-dependent |
Practice is a local simulation, not an unsigned mode. It requires an identified account and
a successfully initialized/loaded Game Saves folder, including when the platform supports
offline access to that folder. A cold offline launch is not guaranteed to resolve the required
identity and store. PC and console use the same GameSaveService / GDK.game_save
backend; historical shared or --pf-user token files are never read, imported, moved or deleted.
Hosted matches use PlayFab Lobby discovery. Quick Match uses PlayFab Matchmaking: the
Matchmaking row above Host Match gathers a group of one to four in its own lobby. A group of
one to three readies up and searches the godotnr_q queue together for a match of two to four
players (capacity four), then plays the matched game in a fresh private arranged session and stays
together there for hosted rematches. The matched game starts with the players who have arrived;
one who arrives after it has started cannot join that round. A full group of four does not search:
when all four are ready it starts a private match in the same lobby and stays together there for
rematches in the same way; see Private Start. When the queue,
the PlayFab addon's matchmaking support or the four-player Deathmatch profile is missing, the row
shows that reason and starts nothing. See
Known issues and
Matchmaking.
Voice mute and typed-text privacy are separate. Text is in-match only: four recent messages,
100 characters each, no persistence or scrollback, and no speech-to-text, text-to-speech or
translation. The lobby remains voice-only. See communication behavior.
The game has no host migration or join-in-progress and favors low-latency demonstrations;
these are sample gameplay limits, not Party limits.
Known issues: this sample is still being built and some things are broken, including a multiplayer bug that can cost you control of your ship in three-player matches, and a hang when leaving a match that used voice or typed text. See Known issues before you file a bug.
- Godot 4.6 or later, tested with 4.6.2. A standard build is enough; the GDK addons are GDExtensions and need no custom engine.
- Windows, for the GDK and PlayFab addons to load.
- Visual Studio 2022 with the vcpkg component, and a Microsoft GDK edition. These are needed once, to build the addons.
- Exporting to XBOX Series X|S additionally requires GDKX through an NDA XBOX developer program, an authorized devkit and a Middleware console fork of Godot. Complete the XBOX Development Kit setup first (authorized access required).
The registered-PC path also needs GDK PC tooling (wdapp), appropriate export templates,
authorized access to the sample's XDKS.1 sandbox/title, and an XBOX test account from that
sandbox signed in to the XBOX app. Registration alone does not grant service access.
Check sandbox/account setup before exporting;
changing the sandbox is administrator-only and machine-wide.
New to the GDK or PlayFab? Before you start walks the three provisioning steps in order, marks which you can complete yourself and which need an XBOX publishing relationship, and lists what runs without the full set.
addons/ is build output and is not committed, so a fresh clone has to build it once:
git clone --recurse-submodules https://github.com/microsoft/XBOX-Godot-NetRumble.git
cd godot-netrumble
.\tools\sync_addons.ps1
.\tools\deploy-pc.ps1 -LaunchAlready cloned without --recurse-submodules? tools\sync_addons.ps1 checks the submodule out
itself. The build takes a while the first time, because vcpkg restores the GDK and PlayFab SDKs,
and is only repeated when the pin moves. See Addon maintenance.
If PowerShell refuses to run the scripts, see running the PowerShell scripts.
deploy-pc.ps1 exports the XBOX on PC preset, verifies loose-package registration in
wdapp list, then launches the registered AUMID. The deliverable is build\_gdk_staging,
not an executable at the preset's nominal export path. A successful demonstration reaches
the acquire-user screen and then the menu with the signed-in gamertag. If sign-in fails,
read its stage/reason and check registration, sandbox and account access. Save initialization
and loading must also succeed; failures offer Retry / Back and block every gameplay path.
Keep the committed sample title/package identifiers unchanged; see the configuration checklist. Continue with the Walkthroughs to demonstrate identity, joining and services.
- Editor exploration: after addon setup,
godot.exe --path .(or F5) can inspect the front end, but missing identity/save readiness blocks Practice as well as multiplayer. An initialized GDK in the editor is not registered package identity. - Custom-ID diagnostics: debug
--pf-user/--pf-titleoverrides can exercise authentication against a separate development title. Without a signed-in XboxUser they cannot prepare Game Saves or enter gameplay. Use two registered devices/accounts for multiplayer; see testing prerequisites. - Console: after completing the authorized GDKX and devkit setup, use a Middleware console
fork and
.\tools\deploy-console.ps1 -Launch; see configuration.
Follow these source boundaries alongside the Walkthroughs.
| Feature | Source | Guide |
|---|---|---|
| GDK sign-in and the exchange for a PlayFab identity | scripts/services/identity_service.gd |
Platform services |
| Account/save readiness, progress and Retry/Back | scripts/ui/screens/acquire_user_screen.gd |
Platform services |
PlayFab Party as a drop-in Godot MultiplayerPeer |
scripts/services/party_service.gd |
Multiplayer |
| Join-code discovery with PlayFab Lobby | scripts/services/party_service.gd |
Connection flows |
| Multiplayer and communications privilege checks | scripts/services/privilege_service.gd |
Platform services |
| Per-player mute, block and avoid enforcement | scripts/services/privacy_service.gd, scripts/autoload/platform_session.gd |
Platform services |
| Text verification before user-authored content is published | scripts/services/moderation_service.gd |
Platform services |
| Party voice and four-message typed-text display | scripts/services/chat_service.gd, scripts/ui/elements/nr_chat_log.gd |
Multiplayer |
| One-shot and incremental achievement progress | scripts/services/achievement_service.gd, scripts/services/achievement_tracker.gd |
Platform services |
| PC/console Game Saves: account-owned profile, history and counters | scripts/services/game_save_service.gd |
Platform services |
| Standalone leaderboard submission and browsing | scripts/services/leaderboard_service.gd, scripts/ui/screens/leaderboards_screen.gd |
Leaderboard behavior and client-access policy |
| Suspend, resume and constrain handling | scripts/main.gd |
Architecture |
| Activity publishing and join-from-guide invites | scripts/autoload/platform_session.gd, scripts/services/activity_service.gd, scripts/autoload/invite_router.gd |
Multiplayer |
| Connectivity detection before online play is offered | scripts/services/connectivity_service.gd |
Architecture |
| Controller association/detection, without input filtering | scripts/services/device_service.gd, scripts/main.gd |
Platform services |
| GameInput device tracking behind the GDK user/device APIs | scripts/services/device_service.gd |
Platform services |
Services owns the service instances, including both PartyService and ChatService.
NetManager consumes that facade for the session; its PlatformSession helper maintains
the XBOX view of the session. Small UI adapters also wrap system UI, such as the console keyboard.
XboxBootstrap GDK runtime bootstrap
Services Owns identity, Party, chat, policy, saves and XBOX service wrappers
NetManager → Services Session, authenticated peer roster and gameplay RPCs
└── PlatformSession Activity, presence, recent players, names and communication policy
InviteRouter Buffers activations until account, saves and front end are ready
main.gd Synchronous suspend persistence; resume/constrain and device overlay
This is an ownership sketch, not the autoload order; see architecture. Match events feed the achievement tracker and saved history; the arena is simply the workload.
The transport is PlayFab Party, wrapped by PlayFabPartyPeer, a MultiplayerPeerExtension,
and therefore a drop-in Godot MultiplayerPeer. Every @rpc in net_manager.gd is ordinary
Godot RPC; only the peer construction is PlayFab-specific.
Full detail: Architecture.
| Page | Contents |
|---|---|
| Architecture | Platform ownership, identities, saves, lifecycle and connectivity |
| Multiplayer | Lobby discovery, Party connection/leave, voice and typed text |
| Matchmaking | Quick Match: the group lobby, its godotnr_q ticket, the arranged match and its rematches |
| Platform services | Sign-in, privileges, privacy, moderation, achievements, saves |
| Leaderboards | The standalone GlobalScore board, match submission and client-access policy |
| Configuration | Registered-PC setup, sandbox/accounts, fixed title configuration, alternate run paths |
| Walkthroughs | Prerequisites → player action → API → observable outcome and failure |
| XBOX Requirements | Each XR the sample has code for, and where that code is |
| Manual test plan | Integration acceptance and secondary gameplay regression; record actual results |
| Addon maintenance | Building addons/ from the submodule, moving the pin, the project's .gdextension overrides |
| Glossary | Every XBOX, GDK and PlayFab term used in these pages, in one line each |
| Troubleshooting | Symptoms you can see, their documented cause and the shortest safe fix |
| Known issues | The bugs we already know about, and which platform each one affects |
| Repository checks | The CI text gates, what each one enforces and how to run them locally |
Secondary maintainer references: Gameplay covers simulation, physics, tuning and presentation. Protocol covers RPCs, snapshots and reconciliation. Neither is a prerequisite for demonstrating the platform integration.
See CONTRIBUTING.md. This repository has no automated test suite for gameplay or netcode, so docs/manual-test-plan.md is the acceptance gate for any change to the multiplayer core.
- Security issues: SECURITY.md
- Getting help: SUPPORT.md
- Expected conduct: CODE_OF_CONDUCT.md
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos is subject to those third-party's policies.
