Competitive multiplayer quickstart guide
Install the competitive quickstart sample to get started with a server-authoritative competitive multiplayer game.
Read time 6 minutesLast updated 2 days ago
This quickstart uses Netcode for GameObjects and the Multiplayer Services SDK to run a server-authoritative 1v1 competitive game against a dedicated server. Players connect by quick-joining a Multiplayer Session that the server creates and publishes. Clients send their gameplay inputs to the server. All gameplay relevant movement is calculated on the server and transmitted to the client. This is the pattern to build on for any game where players compete against each other and client-side cheating (speed hacks, teleports, wallhacks) would ruin the experience.
You can use Multiplayer Play Mode to simulate a dedicated server and two clients locally to test the implementation. Install the sample via the Multiplayer Center to quickly add it to your project.
Required components
When creating a multiplayer game using Netcode for GameObjects, there are some core components that must always be present to enable basic network functionality:
- NetworkManager: specifies global network settings and must be initialized before any network-related processes can occur (such as spawning objects). The Multiplayer Services SDK starts and configures NetworkManager for you as part of session creation, so you don't call yourself.
NetworkManager.StartServer() - Transport: the sample uses the default Unity Transport package, configured for a direct connection, a fixed IP address and port. The client connects directly to the server, rather than using Relay, because a dedicated server has a known, reachable address.
- Multiplayer Roles: a component that tags which scripts and components run in the Server role versus the Client role, so a single project can represent both a dedicated server and a client build.
MultiplayerRolesData - Dedicated Server package: a server build target support so the same project can be built as a headless dedicated server binary.
Set up the project
Unlike the sample's scenes, scripts, and prefabs, a few settings live at the project level and don't update automatically with the imported sample.
To ensure your project runs properly complete the following steps before entering Play mode.
- Import the Competitive Sample sample through Multiplayer Center
- Navigate to Project Settings > Multiplayer > Samples > Competitive Sample to apply the define and set your service account in the Editor.
- The Apply all button on the settings page applies the define, roles, and scene list changes for you; the service account fields are saved separately.
- Select the Multiplayer Play Mode scenario if it's not already selected and select Play.
NetworkObjects and network prefabs
To synchronize a GameObject over a network so that multiple clients can interact with it, you need to attach a NetworkObject component at the root of the GameObject. The NetworkObject component provides the properties and methods required to manage the GameObject’s state. When you create a GameObject prefab that contains a NetworkObject component, it’s referred to as a network prefab.
Netcode for GameObjects provides other components to manage networked GameObjects, such as NetworkTransform, which synchronizes a GameObject’s Transform, and NetworkBehaviour, which allows you to add network-aware scripts to a GameObject. Refer to the Netcode for GameObjects documentation for a complete list of available components.
The sample's prefab has a NetworkObject and a NetworkTransform. The Player prefab's NetworkTransform is server-authoritative, meaning only the server writes to it and every client, including the owning client, receives and interpolates the result. A client never moves its own cube directly which prevents player cheating.
PlayerConnecting to a multiplayer session
Instead of a single connection script, the sample has one script per role, both living on the persistent and objects in the Bootstrap scene, gated by Multiplayer Roles so only the relevant one runs.
ConnectionSetupNetworkManager- (server role only) signs in and creates the session. Once signed in, the script creates a session using the server API and a direct network connection
ServerConnection - (client role only) waits for the
ClientConnectioncomponent'sPlayerAuthenticationevent, then Quick Joins an existing session; it never creates one.SignedIn
Setting guarantees a client only ever joins the dedicated server's session and never becomes a host itself if no session is available yet. Refer to Match players for more on quick-join matchmaking.
CreateSession = falseBoth scripts compute a matching value, the local device ID in the Editor, or in a build. Use the scope value as a session property (server) and filter (client), so a client only ever connects to the server it's meant to, rather than any public session that happens to be running.
scope"CompetitiveSample-1v1-{Application.version}"Loading the game scene
The competitive sample splits a persistent Bootstrap scene, connection and NetworkManager objects that must survive scene loads, from a separate Game scene. Once the dedicated server's session is created, a component network-loads the Game scene through NGO's own scene manager.
NetworkSceneLoaderMovement scripts
The competitive sample uses server-authoritative click-to-move so a client can never assert its own position, direction, or speed.
PlayerMovementMoveCommandPointThe server clamps the requested destination to the arena bounds and the player's current height before accepting it, then moves the object toward that target itself every frame with . Because the object's NetworkTransform is server-authoritative, writing to on the server replicates the result to every client, which interpolates it. A client can request where it wants to go, but only the server decides if and how it actually gets there.
Vector3.MoveTowardstransform.positionMultiplayer Services SDK
This sample uses the Multiplayer Services SDK from both sides of a client/server split: the server-side API (, ) to create and authenticate the session, and the client-side API (, ) to sign in anonymously and quick-join it. Refer to Create a session and Game server hosting support for background on both sides of this API.
MultiplayerServerServiceServerAuthenticationServiceMultiplayerServicePlayerAuthenticationTesting
Test the sample with Multiplayer Play Mode using its pre-configured Session (Multiplayer Services) Play mode scenario, which launches the Main Editor in the Server role and two clone Player instances in the Client role. Select it from the drop-down menu next to the Play button and press Play.
The service account you enter under Project Settings > Multiplayer > Samples > Competitive Sample must have the Unity Environments Viewer and Multiplayer Session Details Viewer roles. Without both, the Main Editor instance can authenticate but fails to create or read back the session, and the scenario won't connect the clients. Refer to Create a service account for how to assign roles to a service account.
Modify the quickstart
You can use the competitive quickstart as the basis of your own server-authoritative implementation. When imported via the Multiplayer Center, it's installed as an embedded package. You can either modify the package directly, or copy assets from the package into your project to edit them. Common starting points are raising and the scene's spawn logic beyond 1v1, replacing quick-join with advanced matchmaking for skill-based matches, or adding backfilling so a session refills a slot when a player disconnects mid-match.
MaxPlayers