Skip to content

Players, NPCs and entities

A player is a person playing, or one of the server’s own bots. An NPC is a character the server walks across the map for the mod, such as a zombie: the mod makes one with spawn, and removes it.

Both have a body: the shape in the world that walks, stands on things, collides and is shot. Both are in players, so one loop reaches them all. Here every NPC turns on whoever just joined:

on("joined", function(e)
for _, p in players do
if p.npc then
p:chase(e.player)
end
end
end)

p.bot is true for anyone no person drives, the server’s bots and every NPC. p.npc is true for NPCs alone. NPCs have no health of the engine’s: a mod that hurts them keeps its own count.

An entity is anything else in the world the mod can name: a model it placed, a shape, a looping sound or effect, a camera, or a part of the map. entities[id] gives the ones alive.

A player or an entity is an object the engine holds. The same thing is always the same object, so == compares them and they work as table keys:

local kills = {}
on("killed", function(e)
if e.killer then
kills[e.killer] = (kills[e.killer] or 0) + 1
end
end)

An object outlasts what it names. Once a player leaves or an entity is removed, exists is false, and orders to it do nothing. Check exists after a wait.

Orders are methods on what they act on: p:hurt(30), npc:chase(p), door:move_to(at, 2). Every object has every order. One given to the wrong kind of thing fails at its line: chase: prop 300 is not an NPC.

Orders are given in handlers, timers and commands. One given at a module’s top, as it loads, fails.

Names tell you what a call does:

  • An order that sets a value starts with set_: p:set_health(50).
  • A question starts with is_, has_ or can_: p:is_inside(trigger).
  • A value you read without a call is a field: p.health.

Every player and entity has a number, id, which is how the server names it to players’ games.

Ids What
0 to 255 players: people and the server’s bots
256 to 57343 NPCs, models, shapes, cameras, looping sounds and effects
57344 to 61439 the map’s parts
61440 and up grenades and rockets in flight, as a damaged event’s projectile names them

An option that names a player or an entity, such as follow, owner or by, takes its object or its id. Naming a player by an id from 256 fails; naming one who left does nothing.

The server reads every player and entity. A client script reads only what its game is shown:

  • me is the player this screen shows: the player, or while they are dead, the one they watch.
  • players[id] gives each player the game lists, the dead and those out of sight among them.
  • entities[id] gives each entity the game draws.

Some fields are the server’s alone, such as identity. Reading one in a client script fails, naming it.