Players

Gamehoster.Players is a Map of the player views you can see, keyed by netId. Your own player is Gamehoster.Players.self, always netId 1. Only the players relevant to you appear, so read it as a live set that changes as players come and go.

The map

MemberHolds
Gamehoster.Players.get(netId)the view for that netId.
Gamehoster.Players.selfyour own player, netId 1.
Gamehoster.Players.values()iterate every player view.
Gamehoster.Players.sizehow many players are in view.

A player view

MemberHolds
fields each player schema field, eased for this frame, at the top level (x, y, angle, score).
.currentthe newest authoritative sample, un-interpolated.
.prevthe previous sample.
.datathe view's front-end bag, kept for the player's whole visible life.
.ida stable id for the player's whole visible life.
.selftrue for your own player.

The netId is the map key. It is reused as players come and go, so a departed player's netId can later name a different player. The .id is stable for one player's whole visible life, so key your own per-player front-end state on .id.

var me = Gamehoster.Players.self
if (me) drawShip(me.x, me.y, me.angle, true)
for (var p of Gamehoster.Players.values()) if (!p.self) drawShip(p.x, p.y, p.angle, false)
Draw your own ship, then every other player.

The player bodies

Four client-only bodies sit beside the player schema. Each is optional.

BodyWhen it runsFor
gamehoster-player-enter.js a player appears Seed that view's .data bag.
gamehoster-player-smooth.js each frame Shape how the view eases between authoritative samples.
gamehoster-player-exit.js a player leaves your view Tidy up anything the bag held.
gamehoster-player-predict.js each tick, for your own player Predict your own object from live input so it moves the instant you act, then reconcile toward the authoritative state as it arrives.

Only your own object is predicted. Everything else on screen is interpolated. The predict body reads the live input you feed with Gamehoster.Input.Set and runs every tick.