Skip to content

Server and client

Compiles

Knockout City is played online. A serverserver: The machine that runs the match and decides what really happened. Every player's game talks to it. runs the match, and every player runs their own copy of the game, a clientclient: A player's copy of the game. It runs the same scripts, and shows the player what the server decided.. Your script runs in all of them: the same script, the same events, on every machine. Most “why doesn’t this work online?” problems come from forgetting that.

The server’s copy is the one that counts. When something must happen exactly once and everyone must agree (a point scored, a door opened, an item granted), the server does it, and the clients are told.

let mut score: int = 0
fn add_point() {
if !$net.is_server() {
return
}
score = score + 1
}

$net.is_server() is true only on the server. Guarding with it means the clients’ copies skip the change and wait to receive the server’s value instead.

Server
Each player's game
A player steps on the pad: trigger_overlapped
Same overlap seen: trigger_overlapped
is_server() is true: score = score + 1
is_server() is false: return
score changed
replication
score arrives
field_replicated("score", previous): update the display
The server counts; every client is sent the result.

Anything a player sees or hears happens on their own machine: effects, sounds, UI, camera. The server usually has no screen at all.

$net.is_headless_server() is true on a dedicated server with no graphics. Skip purely visual work there.

Some things must run on every machine, not only the server. The clearest case is moving a player: each player’s game simulates their movement itself, so a position set only on the server is recalculated away by the client a moment later. The camera jumps and the player stays where they were. The shipped scripts that knock players back run the same move on every machine, and so must yours. See the teleport pad.

The job Who does it
Deciding an outcome: points, unlocks, match state Server only, then replicate
Moving players Every machine
Effects, sounds, UI Each client, for itself
Reading input The player’s own client
For programmers

It’s authoritative-server with client-side prediction and rollback for player movement. Scripts are the same bytecode on all peers; replicated mutables flow server→client (optionally only to the owner), and $net.queue_event_on_component sends a network event explicitly. Don’t mutate replicated state on clients; the next update overwrites it.