Designing a seat
The player row is the thing the seat plays as, never a row it spawns.
A seat possesses one row, its player row, and every act it sends is that row's. This page covers building that row, on its own or holding rows of other kinds.
Choosing the path
- If the seat plays one thing for its whole visit and nothing of it outlives the seat (a gun, a hero, a plane, a poker chair), the
playerrow is that thing. Every field of the thing is a field of theplayerrow. - If the seat gets in and out of things (a vehicle, a mount, a turret, a crane), plays a row that must outlive the seat, or sometimes only watches, the
playerrow is the driver or rider and takes hold of rows of other kinds with player's hold functions.
What a seat is sent
- Every seat is sent every
playerrow, which is how other seats see your car. - The seat's own row carries
mine: true, which no other seat is sent. Find it withpossessed(rows), never the firstplayerrow. - A field only its own seat may read, such as a hand of cards, is listed in the scene's
securityblock,{ "player": { "hole": "me" } }, withmasks: []on the player prefab. - The row's
seatfield is its slot. Find astartor anything else per player byme.data.seat.
The simple path
- Put every changing field of the thing on the
playerprefab (position, velocity, health, ammo, laps) and its fixed numbers in theplayerdefinition. - In
before, stand the row once on its slot'sstartactor and mark it placed. Never spawn a row for it. - Run the thing in its hooks. A rule shared with another kind, such as a rival that drives like the seat's car, is a function of a game plugin each kind calls on its own row.
- Respawn by resetting the same row's fields.
- Give
playeran entry in any plugin table keyed by kind, such asworld.box2d.kinds.
One thing, several modes
A thing that walks and swims, or is a fighter and a ghost, is one player row with a mode field. Each hook runs that mode's rule, each act does nothing in a mode it is not for, and the mode changes only in a rule or an act of the row.
Holding rows of other kinds
- Give the
playerprefabheld,nullwhen it holds nothing. The held row stands in the scene'sactorsor is made by another rule; theplayerrow never spawns it. - Write the act that takes hold: it checks what the game cares about (in reach, slow enough) and calls
take(me, w, row), which refuses a row anotherplayerrow holds. The same act callsletGo(me)to get out. - Pass the controls on with
relay({ box3dvehicle: ['pedal', 'steer', 'brake'] })among theplayeracts. The held kind's control acts are never in itsopen. - In the held kind's rule, ask
holderOf(w, me)each step and rest its controls when it has no holder. - Where the
playerrow is a body, set its position from the held row every step while it holds. - In the drawing, read
holding(rows)each frame and switch the bound keys and the camera on the frame it changes.
import { holding, letGo, relay, take } from '#plugins/player/player.sim.ts'
export const player: Kind = {
acts: {
use(me, w) {
const car = holding(w, me)
if (car) { if (slowEnough(car, w)) letGo(me); return }
const it = nearest(me, w)
if (it) take(me, w, it)
},
...relay({ box3dvehicle: ['pedal', 'steer', 'brake'] }),
},
}
slowEnough and nearest are the game's own functions.
Acts a seat can send
A seat may send any act its player row has. An act other kinds call to change the row (hurt, award, heal) does nothing when a seat sent it, if (seat >= 0) return, or is a game plugin's function instead. Every act a seat does send checks its arguments' type, finiteness and range.
The drawing
player.client.ts is loaded once for every player row the page is sent. It draws the thing for every row, and binds keys and moves the camera only for the row that is mine.
let ours = false
export function setup(row: Row, plugins: Plugins) {
// the model, for every seat's row
ours = row.data.mine === true
if (ours) plugins.player.bind({ ... })
}
export function remove(plugins: Plugins) {
// drop the model
if (ours) plugins.player.unbind()
}
The scene sets world.predict and client.html wraps its link in predict, so the seat's own thing moves on the frame after its key.
Checking it
- Run the server and open
client.html: press a key and your thing moves on the next frame. - Open a second
client.html: each seat sees the other's thing, and each one's keys move only its own. - For a held row: getting in, driving and getting out work, and the row rests the step after it is let go or its seat leaves.