Skip to content

Your first gamemode

A gamemode is a Node.js program that creates a Server, listens to its events and calls listen().

Set up a project

mkdir my-gamemode && cd my-gamemode
npm init -y
npm install /path/to/sagl/node      # @sagl/server

In package.json, make it an ES module and give it a start script:

{
  "type": "module",
  "scripts": { "start": "node index.ts", "dev": "node --watch index.ts" },
  "dependencies": { "@sagl/server": "file:../sagl/node" }
}

The server

index.ts
import { Server, Color, Weapon } from "@sagl/server";

const server = new Server({
  port: 7777,
  name: "My first server",
  startMoney: 500,
  time: { hour: 12, minute: 0, frozen: true },
});

server.on("playerJoin", (player) => {
  player.send(`Welcome, ${player.name}!`, Color.Green);
  server.broadcast(`${player.name} joined`, Color.Grey);
});

server.on("playerSpawn", (player) => {
  player.setPosition({ x: 2495.3, y: -1687.4, z: 13.5 }, 0); // Grove Street
  player.giveWeapon(Weapon.Pistol, 100);
});

server.on("playerDeath", (player, killer) => {
  if (killer && "name" in killer) {
    server.broadcast(`${killer.name} killed ${player.name}`, Color.Red);
    killer.giveMoney(100);
  }
});

server.on("playerQuit", (player, reason) => {
  server.broadcast(`${player.name} left (${reason})`, Color.Grey);
});

server.listen();

npm start runs it. The terminal is an operator console: type help.

Commands

There's no built-in chat command system yet. Gamemodes usually take commands over a client script channel, or add console commands for operators:

server.console.command("car", "car <id> <model>", ([id, model]) => {
  const player = server.player(Number(id));
  if (!player) throw new Error("no such player");
  server.createVehicle(Number(model), player.position, player.heading);
});

A car for everyone

server.on("playerSpawn", (player) => {
  const old = player.data.car as Vehicle | undefined;
  old?.destroy();
  const { x, y, z } = player.position;
  player.data.car = server.createVehicle(411, { x: x + 4, y, z }, player.heading, {
    colors: [1, 1],
    plate: "MYSERVER",
  });
});

Every Player, Vehicle, Ped and Zone has a data object for your own per-object state.

Ambient life

The world is empty by default. Turn on single-player's population:

server.population = { peds: true, traffic: true, gangs: true };

Police, ambulances, fire trucks and wanted levels from crimes are off until you turn them on: see worlds, zones and population.

Next steps