Weapons
What players carry and how it fires. A weapon is a file of the mod’s, <path>.weapon.luau, which returns its numbers as a table: damage, rate, a burst, spread, range, its magazine and times, aiming, its bash on V, a projectile for a rocket or a grenade. The server and every player’s game read the same file, so a shot feels the same on both.
To make one, copy one of the stock mod’s, such as weapons/ak47.weapon.luau; weapon files lists every key. The mod hands weapons out with loadout and give, tunes one a player carries with tune_weapon, fitting parts on it and naming its sounds, plays a clip on the one in hand with animate_weapon, scales all of a player’s with tune, and can put one down, hide it or take it away.
A player carries up to four weapons, in slots 1, 2, 3 and 5 by the keys that take them, and grenades apart, which keys of their own throw. Each weapon carried is a value, {weapon, rounds, reserve, tune}, which p.slots lists, p:take returns and p:give gives back as it was, so a weapon handed from one player to another keeps its rounds and its tune. The orders name a weapon by its file, a tuned one by its base’s.
Fields
Section titled “Fields”What a player, p, or an entity, e, reads beside the mod’s state. A field of the other side’s fails.
| Name | Type | Side | What it is |
|---|---|---|---|
p.weapon | string? | On both sides | The weapon in their hand; on a client, the shown player's alone. |
p.slots | {[number]: Carried}? | On both sides | The weapons they carry, by slot, as carried still while killed runs; on a client, the shown player's alone. |
p.ammo | number? | On a client | The rounds in the shown player's weapon. |
p.reserve | number? | On a client | The rounds the shown player carries for their weapon beside those. |
p:give(weapon, slot?)p:give(carried, slot?)Gives a player a weapon by its file's name, its magazine full and its reserve the weapon's reserve stat.
p:give(weapon, slot?)
It goes in slot, 1, 2, 3 or 5, or else where the player already carries it, or else in the first empty slot, or
else in hand, taking what was there. A player carries one weapon of a file at most, tuned or not, so one of the same
file in another slot is taken. It comes up when it is given in hand, to empty hands, or in place of the same weapon
in hand. A grenade is carried apart from the slots, in place of the one its key throws. A name of no weapon’s file
fails at the call.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
slot | number? | May be left out. |
- Fails
- a value of the wrong type
p:give(carried, slot?)
Gives a player back a weapon as it was carried: its rounds, its reserve and its tune.
carried is a value of p.slots or p:take, so a weapon taken from one player and given to another keeps its
rounds. It goes where a weapon given by name goes. Nothing stops one value being given twice. A reserve above 0 on a
melee weapon or a grenade, which reload nothing, fails at the call.
| Name | Type | What it is |
|---|---|---|
carried | table | A table of the options below. Those marked needed may not be left out. |
weapon | string | The weapon's name, its base's if it is tuned. Needed. |
rounds | number | The rounds in its magazine; more than it holds are left out. Needed. |
reserve | number0 to 9999 | The rounds its reloads draw from. Needed. |
tune | Tune? | Its tune, if it has one. A table of the options below it. |
tune.stats | ({[string]: any})? | Stats laid over the weapon's file, by name, each as the file writes it; false takes an optional one away. |
tune.attach | ({[string]: string})? | The model drawn at each marker of the weapon's model, by the marker's name. |
tune.sounds | string? | The name the weapon's sounds take in place of its model's: <sounds>_fire and the rest. |
slot | number? | May be left out. |
- Fails
- a value of the wrong type
- an option it does not have
- a key it needs left out
- a value outside its range
To give a player a pistol in their second slot
Section titled “To give a player a pistol in their second slot”p:give("weapons/usp", 2)To hand a player’s rifle to another, rounds and all
Section titled “To hand a player’s rifle to another, rounds and all”local rifle = p:take("weapons/ak47")if rifle then q:give(rifle, 1)endp:take(weapon) → Carried?p:take() → {[number]: Carried}Takes a weapon away from a player and returns its value, which p:give gives back as it was; nil if they do not carry it.
p:take(weapon) → Carried?
The value is the weapon as carried when the handler was called: orders are carried out after it, so p:give(x)
then p:take(x) in one handler returns nil. The weapon in hand taken, the first left comes up. A name of no
weapon’s file fails at the call.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
- Returns
Carried?- Fails
- a value of the wrong type
p:take() → {[number]: Carried}
Takes every weapon away from a player, grenades too, and returns the values of those in slots, by slot number.
Each is as carried when the handler was called, as p:take(weapon) returns it; a grenade taken returns none.
- Returns
{[number]: Carried}
To trade a player’s rifle for a pistol with as many rounds in reserve
Section titled “To trade a player’s rifle for a pistol with as many rounds in reserve”local rifle = p:take("weapons/ak47")if rifle then p:give("weapons/usp") p:set_ammo("weapons/usp", nil, rifle.reserve)endTo take a player’s weapons through a cutscene and give them back after
Section titled “To take a player’s weapons through a cutscene and give them back after”local kept = p:take()wait(5)for slot, carried in kept do p:give(carried, slot)endswitch
Section titled “switch”p:switch(weapon)Switches a player to a weapon they carry, as its slot's key does; nothing happens if they carry none of it.
A name of no weapon’s file fails at the call.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
- Fails
- a value of the wrong type
To bring up a player’s pistol as they climb a ladder
Section titled “To bring up a player’s pistol as they climb a ladder”p:switch("weapons/usp")set_ammo
Section titled “set_ammo”p:set_ammo(weapon, rounds?, reserve?)Sets the rounds in a carried weapon's magazine and in the reserve its reloads draw from, each left as it is if nil.
More rounds than the magazine holds are left out. A reserve above 0 on a melee weapon or a grenade, which reload
nothing, fails at the call, as does a name of no weapon’s file. Nothing happens for a weapon the player does not
carry. For an endless reserve, set it again every tick.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
rounds | number? | May be left out. |
reserve | number?0 to 9999 | May be left out. |
- Fails
- a value of the wrong type
- a value outside its range
To refill a player’s rifle from an ammo box
Section titled “To refill a player’s rifle from an ammo box”p:set_ammo("weapons/ak47", 30, 90)To empty a player’s pistol magazine
Section titled “To empty a player’s pistol magazine”p:set_ammo("weapons/usp", 0)disable_weapon
Section titled “disable_weapon”p:disable_weapon()Puts a player's weapon down, as for a sprint, until p:enable_weapon: no firing, aiming nor reloading.
It stays down through a respawn.
To keep players from firing through a countdown
Section titled “To keep players from firing through a countdown”for _, p in players do p:disable_weapon()endwait(3)for _, p in players do p:enable_weapon()endenable_weapon
Section titled “enable_weapon”p:enable_weapon()Brings a player's weapon back up after p:disable_weapon.
To let a player fire again once a stun wears off
Section titled “To let a player fire again once a stun wears off”p:disable_weapon()wait(2)p:enable_weapon()hide_weapon
Section titled “hide_weapon”p:hide_weapon()Draws the weapon in a player's hand nowhere until p:show_weapon: not before their eyes, not in their body's hands for everyone, and with no muzzle flash.
They keep it, its slot and its rounds, and it still fires and is heard, as a mounted gun’s gunner fires while the gun on the map shows. It stays hidden through a respawn.
To seat a player at a mounted gun
Section titled “To seat a player at a mounted gun”p:hide_weapon()show_weapon
Section titled “show_weapon”p:show_weapon()Draws a player's weapon again after p:hide_weapon.
To give a player their own weapon back as they leave a mounted gun
Section titled “To give a player their own weapon back as they leave a mounted gun”p:hide_weapon()wait(10)p:show_weapon()loadout
Section titled “loadout”loadout(weapons)Names the weapons a player carries on joining and after every respawn, in slot order: up to 4, but grenades, carried apart. Without it, none.
One module declares it, at its top as it loads: a second module’s fails at load, naming both, and a module declaring
it again replaces its own. A weapon named twice, or one no file of the mod is, fails at load. p:respawn() gives
the loadout again, so give after it; a weapon disabled or hidden stays so.
| Name | Type | What it is |
|---|---|---|
weapons | {string} | Needed. |
- Fails
- a value of the wrong type
To start every player with a rifle, a pistol and a grenade
Section titled “To start every player with a rifle, a pistol and a grenade”loadout({ "weapons/ak47", "weapons/usp", "weapons/frag_grenade" })stats_of
Section titled “stats_of”stats_of(weapon) → {[string]: any}Gives a weapon file's stats as it writes them, with the defaults it is read with filled in, its model too.
The table is frozen, nested tables kept. The file is read again only once it changes, and nothing is loaded by
players for it, so a mod may look up any weapon it has: a part adds to a stat,
stats.damage = (stats.damage or stats_of(weapon).damage) - 3, and a HUD shows a magazine’s size. A name of no
weapon’s file fails.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
- Returns
{[string]: any}- Fails
- a value of the wrong type
tune_weapon
Section titled “tune_weapon”p:tune_weapon(weapon, { stats?, attach?, sounds? }?, { clip? }?)Tunes a weapon a player carries, as a mod's parts or a burst switched on do: its stats, the parts on it and its sounds.
Each call replaces the weapon’s whole set of changes; nil, or no changes, takes them all off. changes.stats takes
any of a weapon file’s stats but model and name, laid over its file as written and read as the file is, so it fails as the
file would: burst = false takes a burst away, but automatic is true or false, and a pattern is only another of
the engine’s. A tune may not set offhand nor projectile, nor move magazine to or from 0, and a grenade is not
tuned. changes.attach draws up to 8 models at markers of the weapon’s model, on the weapon in hand in first person
alone, a shot’s flash leaving from a part’s own muzzle marker if it has one; the stock guns have muzzle, rail
on top and under below the handguard. changes.sounds names the weapon’s sounds in place of its model’s,
<sounds>_fire and its _reload, _melee and _hold, each the name lacks the model’s own.
The tune belongs to the weapon carried: its rounds and reserve are kept, its name stays the base’s in p.weapon,
p.slots and the events, and its value’s tune is the changes, so p:give of the value tunes it again; a give by
name or a respawn gives it untuned. options.clip plays on the weapon if it is in hand, busy for the clip’s length
as in a reload, which a sprint or a switch drops; the changes land at once, but its owner sees the parts only once
the clip ends. It fails for a weapon the player does not carry, this handler’s gives and takes before it
counted, and for a model, a marker, a sound or a clip of no file.
| Name | Type | What it is |
|---|---|---|
weapon | weapon | Needed. |
changes | table? | A table of the options below. It, and each option, may be left out. |
stats | ({[string]: any})? | Stats laid over the weapon's file, by name, each as the file writes it; false takes an optional one away. |
attach | ({[string]: string})? | The model drawn at each marker of the weapon's model, by the marker's name. |
sounds | string? | The name the weapon's sounds take in place of its model's: <sounds>_fire and the rest. |
options | table? | A table of the options below. It, and each option, may be left out. |
clip | string? | A clip of the weapon's model played as the changes are fitted, <model>_<clip>.anim. |
- Fails
- a value of the wrong type
- an option it does not have
To switch a pistol to three-round bursts
Section titled “To switch a pistol to three-round bursts”p:give("weapons/usp", 2)p:tune_weapon("weapons/usp", { stats = { burst = { count = 3, interval = 0.05 }, interval = 0.35 } })To take every change off a pistol
Section titled “To take every change off a pistol”p:tune_weapon("weapons/usp", nil)animate_weapon
Section titled “animate_weapon”p:animate_weapon(name)Plays a clip on the weapon in a player's hand, <model>_<name>.anim of the weapon's model: before their eyes, and in their body's hands for everyone.
It plays until it ends or the weapon fires, reloads, bashes, is switched or goes down for a sprint or a grenade;
the weapon stays free to do so meanwhile. It fails for a name of no file, and with no weapon in hand, this
handler’s gives and takes before it counted: p:animate_weapon("silencer_on") plays usp_silencer_on.anim on
the stock pistol in hand.
| Name | Type | What it is |
|---|---|---|
name | string | Needed. |
- Fails
- a value of the wrong type
on("fired")
Section titled “on("fired")”on("fired", fn)A player fired a shot or let a grenade go: once a shot, whatever its pellets.
| Name | Type | What it is |
|---|---|---|
e.player | Player | Who fired. |
e.weapon | string | What they fired. |
e.origin | {x: number, y: number, z: number} | Where the shot started. |
e.dir | {x: number, y: number, z: number} | Which way it went, a unit vector: the view, turned by a spray pattern; 0 for a grenade bursting in the hand. |