Modules & Imports
Split a gamemode into modules and share exported functions.
A module is a normal .sa file with a module header that other files can import. Modules keep large gamemodes organised and let you drop in community-written systems without touching the main file.
1. Write a module
Create Gamemodes/modules/economy.sa, next to your gamemode (a modules folder inside the gamemode folder also works).
knight
module "economy" {
version: "1.0.0";
author: "Knight";
};
let balances = {};
function economyAdd(int id, int amount) {
balances[id] = at(balances, id) + amount;
return at(balances, id);
}
export function economyBalance(int id) {
return at(balances, id);
}
export function economySpend(int id, int amount) {
if (at(balances, id) < amount) { return false; }
balances[id] = at(balances, id) - amount;
return true;
}
Note
module metadata is optional. export is documentation for humans: every top-level function in the program can be called from any file.2. Import it
knight
import "economy";
system::start() {
AddPlayerClass(0, 1958.4, 1343.2, 15.4, 270.0, 24, 50);
economyAdd(0, 100);
};
player::command("/bal") {
SendClientMessage(playerid, "Saldo: {economyBalance(playerid)}");
};
player::command("/spend", int amount) {
if (economySpend(playerid, amount)) {
SendClientMessage(playerid, "Berhasil.");
} else {
SendClientMessage(playerid, "Saldo kurang.");
}
};
3. Hooks and vetoes
Modules can register event hooks with on. Returning false vetoes the event: no later handler runs and the default action is skipped. This is how a chat filter blocks a line without the main gamemode knowing about it.
knight
module "anticheat" { version: "1.0.0"; };
const MAX_WARNINGS = 3;
const BANNED = ["cheat", "hack", "aimbot"];
let warnings = {};
on player::chat(string message) {
let low = lower(message);
for (let word in BANNED) {
if (contains(low, word)) {
let n = at(warnings, playerid) + 1;
warnings[playerid] = n;
SendClientMessage(playerid, "Peringatan {n}/{MAX_WARNINGS}");
if (n >= MAX_WARNINGS) { Kick(playerid); }
return false;
}
}
return true;
};
4. Where modules are found
| Search order | Example |
|---|---|
| Gamemode folder | Gamemodes/economy.sa |
| modules/ next to the gamemode | Gamemodes/modules/economy.sa |
| modules/ one level up | modules/economy.sa |
| working directory | modules/economy.sa |
Each module is loaded once. Circular imports are reported as an error at startup, before any player can connect.
5. Errors you may see
| Message | Meaning |
|---|---|
module not found: x | No x.sa in any search location. |
circular import: a -> b -> a | Two modules import each other. |
expected ';' after event block | An on hook block must end with ;. |