Skip to content

Who sees what

The server sends each player only what they are shown. A group picks those players. You give one wherever the API asks who: read_by on a sound, an effect, a model, an NPC, a value or an event, and run_by on a command.

Group Picks
everyone every player; what you get without a group
owner the thing’s owner
team the players on its owner’s team; none for team 0
spectators dead players watching its owner play
admins the players the server’s admins setting lists

Combine them with + and -: owner + spectators is the owner and whoever watches them, everyone - owner all but the owner.

on("joined", function(e)
-- A sound only this player, and those watching them, hear.
play_sound("zombie_punch", { owner = e.player, read_by = owner + spectators })
end)

owner, team and spectators pick players by the thing’s owner:

  • A player owns their own body and state.
  • A sound, an effect, a model or an NPC is owned by the player you give as its owner.
  • An event is owned by the player in its player field, or else by its entity’s owner. An NPC’s owner owns an event naming that NPC.

Using owner, team or spectators on something with no owner is an error: at the call for a sound, an effect, a model or an NPC, and as the module loads for a value or an event.

A function is a group too. It is given the owner and a player who might see the thing, and returns true to show it:

local same_team = group(function(owner, viewer)
return owner ~= nil and owner.team == viewer.team and owner.team ~= 0
end)

It picks the viewer for any value but nil and false; one that fails picks no one. group(fn) makes it a group you can combine, as same_team + admins.

The engine asks the function again at once when a value the mod declared that it read changes, or a player’s name or team, or someone joins or leaves. Anything else it reads, such as viewer.health, waits for the next ask, at least once a second.

The function may only read. It gives no orders, writes no state and does not wait. Make it once, at a module’s top: a function made anew on every call is a new group each time.

x.read_by = group changes who is shown a player, an NPC, a model or a looping sound. p.read_by = owner hides a player from everyone else. nil shows it to everyone again. A player the new group no longer picks has it taken away.