Skip to content
Logo

Getting Started

This guide walks you through installing the RedSpaceM SDK packages and writing your first gamemode resource.

Prerequisites

  • Bun 1.3+ (the SDK is built and tested with Bun). Install from https://bun.sh. The repository does not use npm/yarn.
  • A RedSpaceM server core to run your resource. The core is a separate, closed-source product — this SDK only needs it at deploy time. For local development and unit tests you can develop fully against the SDK's mocks.

1. Create a project

mkdir my-resource && cd my-resource
bun init

2. Install the packages you need

bun add @redspacem/server-types @redspacem/rpc @redspacem/di
bun add -d @redspacem/testing
PackageWhen to use it
@redspacem/server-typesType your access to the injected mp.* host API
@redspacem/rpcAdd type-safe request/response calls in your gamemode
@redspacem/diWire your gamemode's services with a tiny container
@redspacem/client-typesType client-side (in-game) scripts
@redspacem/browser-typesBuild CEF/NUI-style UI bridges
@redspacem/testingUnit-test resources without a running server

3. Write a minimal resource

// server/src/index.ts
import type { Mp, MpPlayer } from "@redspacem/server-types";
import { createContainer } from "@redspacem/di";
 
export function main(mp: Mp): void {
  const services = createContainer();
  services.registerValue("mp", mp);
 
  mp.events.on("playerJoin", (player) => {
    mp.log("info", `[freeroam] ${player.name} (id=${player.id}) joined`);
  });
 
  mp.commands.register("hello", (player: MpPlayer, args: string[]) => {
    mp.log("info", `Hello, ${player.name}!`);
  });
}

The mp object is not something you construct — the RedSpaceM server core injects a conforming mp global into every resource sandbox at runtime. The types describe that contract.

4. Test without a server

// server/src/index.test.ts
import { expect, test } from "bun:test";
import { createMockMp } from "@redspacem/testing";
import { main } from "./index.ts";
 
test("greets joining players", () => {
  const mp = createMockMp();
  main(mp);
 
  mp.emit("playerJoin", { id: 1, name: "ada", pingMs: 20, connectedAt: 0 });
  expect(mp.logLines).toContainEqual({
    level: "info",
    msg: "[freeroam] ada (id=1) joined",
  });
});

Run with bun test.

5. Package your resource

Resources are packed into signed bundles by the server tooling (outside this repo). Locally you can build the server entrypoint:

bun build server/src/index.ts --target=bun --format=esm --outfile=server/dist/index.js

Example

A complete, working example lives in examples/freeroam in this repository — it is a Bun workspace member and is verified by CI (bun run build, bun run typecheck).

Next: Architecture · API reference