Skip to content

Networking

One player’s game is the server, the authority on what happens; the others are clients, connected to it. The server sends each client the state of the entities it should see.

function Lobby:host()
Net.startServer(7777)
end
function Lobby:join(address)
Net.connect(address, 7777)
end
  • startServer(port) hosts a game that this player also plays in; startDedicatedServer(port) hosts one with no player.
  • connect(host, port) joins one; disconnect() leaves.
  • isServer(), isClient() and peerCount() say where you stand.

startServer, startDedicatedServer and connect return false when they fail, such as when the port is taken.

Games talk over UDP, on IPv4. A host also opens port + 1 (7778 above) for players in a web browser: the web build makes the same connect call, and reaches the host there by itself.

An entity that every player should see the same gets two components:

  • Network Identity, which gives it the identity players share. The server assigns it.
  • Networked Transform, which sends its position, rotation and scale from the server to the clients, smoothed on the way.

Move it on the server, and the clients see it move.

The server can also put one into the game while it runs: Net.spawn(prefab, x, y, z) spawns the prefab, as scene.spawn does, and every client gets its own copy (a player who joins later too). Give the prefab’s root a Networked Transform so its movement follows. On a client it spawns nothing and returns an entity that is not valid.

Net.rpc(name) sends a message, Net.rpcNumber(name, value) one with a number, and Net.rpcText(name, text) one with text (Net::rpc and so on in AngelScript). A client’s goes to the server; the server’s goes to every client.

Net.on(name, handler) receives them. The handler gets who sent it, then the number or the text if there is one. On the server, the sender is the client that sent it; on a client, the server. Register handlers whenever you like, before hosting or joining too.

Net.on("score", function(sender, value)
Log.info("player " .. sender .. " scored " .. value)
end)
Net.on("ping", function(sender) end)

In AngelScript a handler is a NetHandler (just the sender), a NetNumberHandler (the sender and a number) or a NetTextHandler (the sender and a const string &in).

A behavior’s property can be kept the same on every machine. Mark it replicated; on a networked entity (one with a Network Identity, spawned by the server), the server sends its value whenever it changes and each client’s copy of the behavior gets it, a player who joins later included.

List the names on the class:

Guest.replicated = { "activity", "costume" }

Numbers, booleans, strings, colours and Float3s replicate; an entity or an asset property cannot. Clients run the same behaviors, so keep what changes a replicated property on the server (if Net.isServer()), and let clients only show it.

Each player has an id: the server is 0, and each client the number the server gives it when it joins. Net.localPlayer() is your own (-1 until you have joined).

  • Net.onJoin(handler) and Net.onLeave(handler) call the handler with a player’s id. On the server, when a client joins or leaves; on a client, once it has joined (with its own id), and if the server goes away (0).
  • Net.rpcTo(player, name), Net.rpcNumberTo and Net.rpcTextTo send from the server to one player.
  • Net.spawnFor(player, prefab, x, y, z) spawns as Net.spawn does, owned by that player. Net.isMine(entity) tells a player whether an entity is theirs, and NetworkComponent.of(entity).owner is its owner’s id on every machine.

A message’s sender is the player who sent it, so the server checks that a player may do what they ask before it does it. When a player leaves, what happens to what they owned is up to your onLeave.

  • Prediction. A client sees the server’s state as it arrives, with no prediction or lag compensation, so fast action feels the delay.
  • Security. Traffic is not encrypted.
  • Editor support. Hosting and joining happen only from scripts; the editor has no networking controls.