The stock mod
The stock mod is the game’s own: its weapons, its HUD and its game modes. Every mod sits on top of it, so a mod can use any of its modules, replace one file of them, or leave them be.
What it holds
Section titled “What it holds”main.server.luau gives every player the AK-47, the USP, a frag and a smoke grenade. The AWP and the axe in weapons/ are there for a game mode to give.
| Module | What it does |
|---|---|
teams |
puts players on teams, tints them and gives them the team chat channel; teammates never hurt each other |
spawns |
picks the markers players come back at |
score |
each player’s kills, deaths and points, the teams’ scores and the clock |
damage |
turns the engine’s hits and falls into one damage event, which a game mode may change or stop |
screen |
the HUD: the team scores, the player’s kills and points, the clock, and the scoreboard while Tab is held, or toggled on |
killfeed |
the last kills at the top right, while match.killfeed is true |
use_hint |
Press [F] <hint> under the crosshair in a use trigger with a hint, and a bar while the key is held |
pm |
/pm <player> <text>, and the reply channel |
admins |
/mute and /unmute; tells everyone who was kicked |
names |
a player’s name, or #<id> for none |
roster |
the players and NPCs, by id, for a loop over a horde |
The helpers
Section titled “The helpers”A module’s <name>_lib.server.luau holds helpers the others require. They keep no state of their own: state and events are how modules talk.
| Helper | Gives |
|---|---|
teams_lib |
set(p, n), members(n), balance(p), the smallest team, and same(a, b) |
spawns_lib |
cycle(prefix), random(prefix) and near_team(prefix, p), each a marker whose name starts so, or nil; and respawn(p, marker) |
score_lib |
player(field, p, amount) and team(n, amount), which emit scored; reset(field), clock(name, seconds) and left(name) |
damage_lib |
deal(data), a game mode’s own damage, and from(hit, source, at), which fills in where it landed |
names_lib |
of(p) |
admins_lib |
ids(but) and shadow(from, text) |
roster_lib |
playing(), the people and bots by id, and split(), which also gives the NPCs |
Read a score as state: p.kills, match.team_scores[n].
Writing a game mode
Section titled “Writing a game mode”To write one, copy gametypes/tdm/. A game mode:
- declares its
bumps; - sets
match.team_countandmatch.killfeedas it starts; - puts a player who joins on a team;
- preloads the files it uses at its top;
- ends its match and calls
start_match()a few seconds later, which plays the rotation’s next.
Its handlers run before the modules’, whose own take { after = true }, so a game mode may change an event or stop it.
A player who joins in the middle of a round may have to wait for the next, as in search and destroy:
local waiting = {}
on("joined", function(e) waiting[e.player] = true e.player:hurt(1000)end)
on("killed", function(e) if waiting[e.victim] then waiting[e.victim] = nil return false -- not counted as a death endend)