Multiplayer

Building is host-authoritative: players see their own preview at once, but every change is a request the host checks with the same rules as single player, charges for, and sends to everyone. Clients can't build what the host wouldn't allow, place where they aren't, or spend what they don't have.

Needs Netcode for GameObjects 2.x (Package Manager). Without it, the multiplayer parts don't compile and everything else works as before; the kit never installs packages itself.

Try the sample #

  1. Install Netcode for GameObjects 2.x. Open Samples/Multiplayer/RBK_Multiplayer.
  2. Play, then Host. In a second player (a build, or Multiplayer Play Mode), Join with the host's address. Tick Owner only before hosting to let players change only their own pieces (the host may change everything).
  3. Build as in the single-player sample: costs come from each player's own amounts, refusals say why, Z undoes only your own actions. Players who join later see everything built so far.

Command line (for quick tests with two builds): -rbk-host, -rbk-join 192.168.1.20, -rbk-port 7777, -rbk-owner-only.

Your own game #

  1. On the Build World's object add a NetworkObject and Netcode Build Authority (the world must be in the scene, so the NetworkObject is an in-scene one).
  2. Give the Network Manager a player prefab with your Builder on it. Only the owner's Builder should be enabled (the sample's SampleNetworkPlayer shows how), and its Requester Id must be the owner's client ID.
  3. Host and clients need the same Piece Catalog.

That's all: while a session runs, the world's authority is a NetworkedBuildAuthority. When it ends, the world goes back to single-player building (and a client's copy of the pieces is cleared, unless you turn Clear On Leave off).

What the host does #

  • Checks every request again with the same rules: snapping, grid, support, overlaps, distance, costs, permissions. It works out socket and grid positions itself; a client's pose is only used for free placement, within limits.
  • Uses the connection's client ID, never the ID a message claims, so a client can't act as someone else.
  • Checks where the player is: requests claiming to come from further than Max Origin Offset (3 m) from the player's player object are refused ("Your request doesn't match where you are").
  • Charges and refunds through the Build World's Resource Provider, by client ID. A client's copy of a Simple Resource Inventory (or any IResourceMirror) gets the player's real amounts after each answer, so the preview shows the right "Needs 4 Wood (you have 2)". The host's Sandbox setting reaches every client.
  • Answers each request once: a repeated request ID (a client retrying) gets the first answer again, never a second piece.
  • Sends every change to every client as piece records (the save format's): new, changed and removed pieces, with their links and support, in small messages. Changes your own code makes on the host (loading a save, spawning pieces) go out too, at the end of the frame.
  • Sends the whole world to late joiners before anything else, in chunks.
  • Keeps each player's undo history: Z undoes only your own actions, on the host. A row, an area or a stamped blueprint is one entry.
  • Checks rows, areas and blueprints piece by piece: each is its own request, checked and charged like any other. Stamped pieces are checked at their exact spot and must be joined to a socket or stand on something.
  • Paints with the same reach and permission checks, and sends every piece's look to everyone.
  • Sends its grid switches and build limits (Grid Enabled, Allow Off Grid, Category Limits, Max Pieces Per Player), so clients' previews match.

Refusals reach the client as the same plain reasons as single player, through the Builder's rejected event.

Who may change what #

Assign a Permission to the Build World: any component implementing IBuildPermission:

public string CanChange(uint requesterId, BuildPiece piece, BuildRequestKind kind)
    => piece.PlacedBy == requesterId ? null : "That isn't yours";

Owner Only Build Permission is ready-made: players may remove, move or upgrade only the pieces they placed; the host (client 0) may change everything unless Host Can Change All is off. The preview shows the reason before the click.

The host sends its rules to the clients so their previews match: sandbox, structural mode, refund %, the permission and its Build Zones (with any changes made while playing). A client uses its Build World's component of the same type (adding one if needed). For your own permission's settings to travel too, also implement IBuildPermissionSync.

Other networking libraries #

The host logic doesn't depend on Netcode for GameObjects. Implement IBuildMessenger (send byte arrays to the server or to one client, reliably and in order, and raise Received) and create a NetworkedBuildAuthority(world, messenger); call SendSnapshot(clientId) when a client joins and Flush() once a frame on the host. IPlayerLocator tells it where players are.

Limits #

  • One authority: a host or dedicated server. Netcode's distributed authority mode isn't supported.
  • Clients' worlds are copies: build through the Builder (or requests), never by spawning pieces on a client.
  • The host's resource amounts are what count; Simple Resource Inventory doesn't save them.

Something unclear or wrong? Tell us · Get help