Skip to content

Press counter

Compiles

A pad that counts how many times players have stepped on it. The count is the kind of thing everyone must agree on, so the server keeps it and replicates it to every player’s game. It’s the smallest complete example of the pattern behind scores, unlocks and match state.

Put it on an entity with a box_trigger, like the teleport pad.

Server
Each player's game
trigger_overlapped: is_server, count it
trigger_overlapped: not the server, ignore
presses = presses + 1
presses (0–9999)
presses updated
field_replicated: print the new count
press_counter.vscript
// press_counter.vscript: counts how many times players have stepped on a
// pad, and tells every player's game when the count changes.
//
// The server owns the count. Players' games never change it; they are sent
// each new value and react to it.
//
// Sits on the same entity as a box_trigger.
// Seconds between counted presses, so standing on the pad counts once.
let cooldown_seconds: float = 1.0;
// The count. Replicated: the server's value is sent to every player.
let mut presses: int = 0;
// Server only: when the last press was counted.
let mut last_press_ms: int = -100000;
event export fn type_created() {
// Components of this script replicate.
$net.set_replicated(true, false);
// `presses` replicates as a whole number from 0 to 9999, and players'
// games get a field_replicated event each time a new value arrives.
$net.set_field_replicated("presses", true, false, false, false, false, "", false, 0, 9999, 1, true);
// `last_press_ms` is the server's own bookkeeping; keep it off the wire.
$net.set_field_replicated("last_press_ms", false, false, false, false, false, "", false, 0, 0, 0, false);
}
event export fn trigger_overlapped(other, unused) {
// Every machine sees the overlap; only the server counts it.
if !$net.is_server() || !other {
return;
}
let player: Component = $entity.get_hierarchy_singleton("catch_player.vscript", $component.get_entity(other));
if !player {
return;
}
let now: int = $time.get_gameplay_time_ms();
if now - last_press_ms < $time.seconds_to_ms(cooldown_seconds) {
return;
}
last_press_ms = now;
presses = presses + 1;
$debug.print_line("[press_counter] server counted press {}", [presses], false);
}
// On each player's game: a new count arrived from the server.
event export fn field_replicated(field, previous) {
if field == "presses" {
$debug.print_line("[press_counter] count went from {} to {}", [previous, presses], false);
}
}
  1. One setting, two pieces of statelines 9-16

    presses is the count everyone sees. last_press_ms is the server’s own note of when it last counted.

  2. Set up replicationlines 18-28

    Replicate this script’s components; send presses as a whole number from 0 to 9999 and fire field_replicated when it arrives; keep last_press_ms off the network entirely.

  3. Count, on the server onlylines 30-45

    Every machine sees the overlap. Only the server passes the first guard. Then it checks that it’s a player and that the cooldown has passed, and counts.

  4. React on each player's gamelines 47-52

    field_replicated runs when a new value arrives, with the field’s name and its previous value. The field already holds the new one.

  • Show the count to players instead of printing it: in field_replicated, send an event to a UI component.
  • Count per team or per player: keep a list of counts, and replicate the numbers you need to show.
  • Reset the count at the start of each round: on the server, set presses = 0, and every client is told.