Skip to content

NPCs

Characters the server moves for the mod, such as zombies. spawn makes one on the navmesh, the map’s walkable floor, and the mod tells it where to go: walk to a point, chase a player, attack. It stops with stop and goes with remove, as a model does.

An NPC finds its own way around walls and closed doors. When a door opens or a crate moves, the navmesh changes with it within a tick or two, and every NPC finds its way again.

An NPC is listed among the players, so its orders are methods of a player’s object; on a person or a bot they fail. NPCs have no health of the engine’s. A mod that lets players kill them keeps its own count, and removes them.

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.npcbooleanOn both sidesWhether they are an NPC the mod spawned.
On the server x:attack({ animation?, length? }?)

Plays an NPC's attack: a jab, or the clip it names, so each of an NPC's attacks may have its own.

It hurts no one: the mod hurts whom the attack reaches, as it likes. On a player it fails; on an NPC gone it does nothing.

NameTypeWhat it is
optionstable?A table of the options below. It, and each option, may be left out.
animationanimation?The .anim file it plays; punch_jab without.
lengthnumber?0 to 3600How long it lasts, in seconds, above 0; the clip's own without.
Fails
  • a value of the wrong type
  • an option it does not have
  • a value outside its range
local zombie = spawn({ at = vector.create(0, 0, 1) })
zombie:attack()
wait(0.5)
zombie:attack({ animation = "punch_cross", length = 0.6 })
On the server spawn(options?) → Player

Spawns an NPC on the navmesh, standing still, and gives it as a player's object.

It is listed among the players, and takes the orders an NPC takes whether held from players or entities. It has no health nor weapons of the engine’s: a mod that lets players kill it keeps its own count, and removes it.

NameTypeWhat it is
optionstable?A table of the options below. It, and each option, may be left out.
atvector?Where it stands, on the navmesh's point nearest; the map's origin without.
owner(Player | number)?The player it is about, whom owner, team and spectators pick by.
read_by(Group | ((Player?, Player) -> boolean))?Who is shown it; everyone without.
kindstring?Its kind, one entity_kind declared on its base; the base's own without.
Returns
Player
Fails
  • a value of the wrong type
  • an option it does not have
local zombie = spawn({ at = vector.create(0, 0, 20) })
zombie:set_name("Zombie")
zombie:chase(p)
local boss = spawn({ at = vector.create(0, 0, 20), owner = p, read_by = owner })
boss:set_speed(2)
On the server x:walk_to(point)

Walks an NPC across the navmesh to the point nearest a point, finding its way around walls and closed doors.

It walks there and stands, until another order. On a player, a model or a part it fails; on an NPC gone it does nothing.

NameTypeWhat it is
pointvectorNeeded.
Fails
  • a value of the wrong type
local zombie = spawn()
zombie:walk_to(vector.create(12, 0, 4))
On the server x:chase(player)

Makes an NPC chase a player across the navmesh, following them as they move, until another order.

NameTypeWhat it is
playerPlayer | numberNeeded.
Fails
  • a value of the wrong type
local zombie = spawn({ at = vector.create(0, 0, 15) })
zombie:chase(p)
On the server x:set_speed(speed)

Sets how fast an NPC walks, in meters a second.

NameTypeWhat it is
speednumber0 or moreNeeded.
Fails
  • a value of the wrong type
  • a value outside its range
local zombie = spawn()
zombie:set_speed(6)
On the server x:set_name(name?)

Names an NPC, so it passes as a player: every player's game lists it with the players, as a scoreboard does, and shows its name, as in chat and a kill feed.

The name is cleaned and cut as a player’s is. Nil, or a name empty once cleaned, takes the name away. On a player it fails: their name is their own.

NameTypeWhat it is
namestring?May be left out.
Fails
  • a value of the wrong type
local boss = spawn()
boss:set_name("The Butcher")
On the server bumps(kind, kinds)

Declares which kinds of body a kind bumps into: a player's body, or an NPC's.

Bodies are round, stop a move as a wall does, can be stood on, and are never pushed. Without it nothing bumps, and NPCs only steer clear of each other. Each kind’s is declared by one module, at its top as it loads: a second module’s fails at load, naming both, and a module declaring it again replaces its own.

NameTypeWhat it is
kind"player" | "npc"Needed.
kinds{"player" | "npc"}Needed.
Fails
  • a value of the wrong type

To make players and zombies block each other

Section titled “To make players and zombies block each other”
bumps("player", { "player", "npc" })
bumps("npc", { "player", "npc" })