Commands

A player acts by sending one of the game's own commands. Gamehoster.Command(name, params) is generated for your game, so it validates the call against that command's schema, then encodes and sends it. A command runs on the server's next tick and you see the result in a later frame; there is no return value.

Sending a command

MemberDescription
Gamehoster.Command(name, params, predict) Validate params against the named command's schema, then encode and send. The optional predict patch is applied over the view at once and retired when the server acks the command — see optimistic overrides.
Gamehoster.Input.Set(name, value) Feed the local prediction input your predict body reads.

Validation runs before anything goes on the wire:

Gamehoster.Command('fire', {})
Gamehoster.Command('aim', { angle: 1.2 })
Send a no-param command, and one with a checked param.

Throttling

A high-frequency command, aim that follows the pointer, does not need to send on every event. A rate map in gamehoster-frontend-settings.json coalesces a command to the latest value at that many times per second.

{
  "rate": {
    "aim": 20
  }
}
Coalesce the aim command to its latest value, 20 times a second.

Feeding prediction

To make your own object respond the instant you act, feed the same value into the local prediction with Gamehoster.Input.Set(name, value). Call it from the input body alongside the command; the gamehoster-player-predict.js body reads it each tick.

var a = Gamehoster.Mouse.angle
Gamehoster.Command('aim', { angle: a })
Gamehoster.Input.Set('angle', a)
The aim input body: send the command and feed prediction the same angle.

Optimistic overrides

Prediction with Input.Set is the continuous tool: it re-simulates your own object every tick. For a discrete action — a chess move, a card played, a door opened — pass a predict patch as the third argument to Gamehoster.Command. The patch is laid over the world the moment you act and retired automatically once the server acks the command, whether it accepted it or not; an ignored (illegal) action simply snaps back on the next update.

The patch is an object addressing the world by each object's stable id. Only the fields you name change; everything else keeps its authoritative value. The fields you write are the same top-level view fields the renderer reads, so an override rides on top of any smooth shaping of that field.

KeyPatches
instancethe instance view's fields.
playersa map of player id to the fields to override.
entitiesa map of entity id to the fields to override.
// chess: show the move at once — the piece jumps, the captured piece leaves, the turn passes
var patch = { entities: {}, instance: { turn: Gamehoster.Instance.turn === 'white' ? 'black' : 'white' } }
patch.entities[moverId] = { file: file, rank: rank }
if (capturedId != null) patch.entities[capturedId] = { file: -1, rank: -1 }
Gamehoster.Command('move', { from: from, to: to }, patch)
An optimistic move: the third argument patches the moving and captured pieces and the turn.

A patch may instead be a function (view) => void for richer edits, but the function form runs only on the lower-level Gamehoster.connect frame; through Gamehoster.Command use the object form above.