Skip to content

Players

The people playing and the server’s bots: who they are, where they are, what they hold and press, and the orders that act on them. NPCs are in players too; see players, NPCs and entities.

A player’s name is what they joined with, and is not unique. Key what you keep by id during a match, and by identity across joins. identity is the same on every join from one install of the game. Only the server reads it.

While a player’s game loads the server’s files, they are on the server but out of play. The mod hears joined once they can play, and leaving as they go.

On both sides players: {[number]: Player}

The players here, people, bots and NPCs, by id: players[id], and for id, p in players do.

On a client me: Player

The player this game is of.

What a player, p, or an entity, e, reads beside the mod’s state. A field of the other side’s fails.

NameTypeSideWhat it is
p.idnumberOn both sidesTheir id, as players[id] finds them, theirs while they are here.
p.namestring?On both sidesThe name they joined with, up to 16 bytes, not unique; an NPC's its set_name.
p.teamnumberOn both sidesTheir team, a number; set_team changes it.
p.botbooleanOn both sidesWhether the server plays them, not a person: a bot or an NPC.
p.existsbooleanOn both sidesWhether they are still here; after a wait, check it.
p.identitystring?On the serverThe same on every join from one install of the game, as their name is not: key what you keep across joins by it. 32 hex digits, bot for the server's bots, nil for an NPC.
p.read_by(Group | ((Player?, Player) -> boolean))?On the serverWho is shown them; everyone for nil. Written, not read: keep what you gave it in state.
p.spectatingboolean?On a clientWhether this player watches another, as a spectator or while dead.
On the server p:net_usage() → NetUsage?

Gives what the server sent a player's game over the last second, or nil for a player with none, as a bot.

rate is the most the player’s game takes and sent the bytes sent, both a second; full is the share of the rate sent. kinds holds the bytes by what they carried: own_player, players, npcs, props, parts, sounds, effects, projectiles, damage, kills, hits_too_late, lines, file_names, rules, commands, settings, channels, player_records, state_values, mod_events, netgraph, hidden_shapes and framing; and declared those each of the modules’ declarations took, its values, its events and the state riding with entities, by its name, an entity kind’s state as kind.name; a state, a player state and an event of one name add up under it. packets and lost count the packets sent and those found lost, and left_out the entities the rate left out. The server rolls it over once a second, so read it in a handler or a timer. On an NPC it fails.

Returns
NetUsage?

To warn the players whose rate is nearly full

Section titled “To warn the players whose rate is nearly full”
for _, p in players do
local usage = if p.npc then nil else p:net_usage()
if usage and usage.full > 0.8 then
say(`{math.floor(usage.full * 100)}% of your rate is used`, { to = { p } })
end
end
On the server p:set_team(team)

Puts a player on a team, 0 being none, as everyone starts.

The team is kept through death, and every player’s game tints the player by it: 1 red, 2 blue, 3 yellow. Each player’s team reaches everyone, however far they are. On an NPC it fails.

NameTypeWhat it is
teamnumber0 to 3Needed.
Fails
  • a value of the wrong type
  • a value outside its range
local count = 0
for _, p in players do
if not p.npc then
count += 1
p:set_team(if count % 2 == 1 then 1 else 2)
end
end
On the server p:kick(reason)

Drops a player from the server, their game back at the main menu showing "Kicked:" and the reason.

The reason is cut to 100 bytes, without control characters. The player may join again at once, unlike after an admin’s /kick. On an NPC it fails: remove it instead.

NameTypeWhat it is
reasonstringNeeded.
Fails
  • a value of the wrong type
p:kick("idle for too long")
On the server on("connecting", fn)

Someone asks to join. They wait until every handler ends, and are refused if one sets e.refuse. The server's bots skip it.

NameTypeWhat it is
e.identitystringTheirs: the same on every join from one install of the game.
e.namestringThe name they join with.
e.addressstringWhere they connect from.
e.refusestring?Set it to a reason to refuse them, cut to 100 bytes.
On both sides on("joined", fn)

A player can play: their game loaded the server's files. On a client, a player came into its list, and those here as it joins.

NameTypeWhat it is
e.playerPlayerWho joined.
On the server on("leaving", fn)

A player is going. They are out of players, but their object reads their values until every handler ends.

NameTypeWhat it is
e.playerPlayerWho is leaving.
On a client on("left", fn)

A player left the client's list of players.

NameTypeWhat it is
e.playerPlayerWho left.
On the server on("screenshot", fn)

A player saved a screenshot, as their game says, which proves nothing. One a second at most.

NameTypeWhat it is
e.playerPlayerWho saved it.
On the server on("kicked", fn)

The engine's /kick or /ban drops a player. Heard before leaving.

NameTypeWhat it is
e.playerPlayerWho is dropped.
e.byPlayer?Who ran it; nil for the server's console.
e.durationnumber?The seconds they are kept out; nil for a kick.
e.reasonstring?Why, if it said.