Recipes & GuidesSetup Server from Scratch with TypeScript

Setup Server from Scratch with TypeScript

A step-by-step guide for creating a Colyseus server with TypeScript, without the project template. Prefer npm create colyseus-app@latest unless you need full control over every file.

Requirements

Setup

Create a new empty directory.

Terminal
mkdir colyseusServer

Go into the directory.

Terminal
cd colyseusServer

Initialise npm with default options

npm init

Change the "main" and "scripts" property of the package.json.

package.json
{
  "main": "dist/main.js",
  "scripts": {
    "build": "tsc",
    "start": "tsx watch src/main.ts",
    "start:prod": "node dist/main.js"
  }
}

Install Dependencies

npm i colyseus

Install Dev Dependencies

npm i --save-dev typescript tsx

Create a new file called tsconfig.json in the root of the project

tsconfig.json
{
    "compilerOptions": {
        "outDir": "./dist",
        "target": "ESNext",
        "module": "CommonJS",
        "moduleResolution": "node",
        "strict": true,
        "allowJs": true,
        "strictNullChecks": false,
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "useDefineForClassFields": false
    },
    "include": [
      "src"
    ]
}

Create a new src/rooms directory

Terminal
mkdir -p src/rooms

State and Room

Define the synchronized state for your room.

src/rooms/MyState.ts
import { schema, t } from "@colyseus/schema";
 
export const Player = schema({
    x: t.number().default(0),
    y: t.number().default(0),
}, "Player");
 
export const MyState = schema({
    players: t.map(Player),
}, "MyState");

Create a room class that uses the state.

src/rooms/MyRoom.ts
import { Room, Client } from "colyseus";
import { MyState, Player } from "./MyState";
 
export class MyRoom extends Room {
    state = new MyState();
 
    onJoin(client: Client) {
        this.state.players.set(client.sessionId, new Player());
    }
 
    onLeave(client: Client) {
        this.state.players.delete(client.sessionId);
    }
}

Entrypoint

Create a new file called main.ts in the src directory. It registers the room type and starts listening.

src/main.ts
import { defineServer, defineRoom } from "colyseus";
import { MyRoom } from "./rooms/MyRoom";
 
const port = parseInt(process.env.PORT, 10) || 2567;
 
const server = defineServer({
    rooms: {
        my_room: defineRoom(MyRoom),
    },
});
 
server.listen(port);

Congrats, you finished the setup for a Colyseus server. Clients can now join it via client.joinOrCreate("my_room"). See Joining Rooms.

Commands

Start the server in development with:

npm start

tsx watch automatically restarts the server when you change a file.

For production you first create a build.

npm run build

After that you can start the server with the start:prod command. This command uses the files which are created from the build command in the dist folder.

npm run start:prod