NET FORGE DOCS

Turning a Socket.IO multiplayer prototype into a Net Forge game

Last updated Checked against @netforge/engine 0.2.0View as Markdown

Net Forge, the open-source multiplayer browser game engine built for AI coding agents, is published on npm under @netforge with source at github.com/netnetdev/net-forge.

Socket.IO is a library for "low-latency, bidirectional and event-based communication" between a client and a server, with rooms, broadcasting and automatic reconnection (Socket.IO docs), and it is a quick way to get two browsers talking. When a prototype outgrows hand-written events, move it to Net Forge: the room host steps one simulation, each browser predicts its own player with the same code, and your rules live in one declarative file.

npm create netforge@latest my-game -- --template arena --yes
cd my-game
npm run play -- --players 2

Why prototypes move

A typical Socket.IO prototype broadcasts each player's position and lets every browser draw what it receives. That is the right way to start. As the game grows, the same questions come up: who decides a hit, how to stop a client from teleporting, how to hide the wait for the server, and how to keep two copies of the rules in step. Net Forge answers them with one design:

In the prototypeIn Net Forge
socket.emit("move", { x, y })Sequence-numbered input commands (move, aim, buttons), quantized so client and server read identical values
io.to(room).emit("state", players)Quantized delta snapshots per player, 20 a second in local play
Rules in the client, the server, or bothRules once, in the shared simulation, decided by the room
Drawing whatever arrivesThe local player predicted and reconciled; others interpolated
socket.join(roomId)A room per game. Locally every tab joins the open room; on the hosted service a link with ?room=<id> joins a specific one
Reconnect handlingThe room client's connection, on Colyseus

1. Pick the template nearest your prototype

PrototypeTemplate id
Top-down shooter or .io arenaarena
Co-op against waves of enemiessurvivor
Racingracer
Platform raceplatformer
Turn-based or card gamecards
Party minigamesparty
npm create netforge@latest my-game -- --template arena --yes

2. Move rules, not messages

You do not port your events. Port what they meant: the things in your world and what happens to them, as declarations in src/game.ts.

src/game.ts
import { prefab } from "@netforge/engine";

// What your server used to spawn and broadcast is now declared once.
prefab("drone", { model: "style.lowpoly.bat", health: 20, speed: 4.5, radius: 0.35, damage: 5, ai: "chase" });

3. Check it with bots, then with people

npm test
npm run play -- --players 2

npm test plays the game headless with bots and reports kills, rounds, softlocks and the cost per tick. The second line opens two tabs in the same room.

When to keep Socket.IO

Keep Socket.IO for the parts that are messages rather than simulation: chat, presence, notifications, dashboards or anything outside the game's rules. It also suits games whose state is small enough to send whole. Net Forge's src/game.ts may import only @netforge/engine, so side channels like chat belong in a service of your own.

FAQ

Is Socket.IO a WebSocket library?

Socket.IO can use WebSocket as its transport, but its docs say it is "NOT a WebSocket implementation": it adds metadata to each packet, so plain WebSocket clients and Socket.IO servers do not interoperate (Socket.IO docs).

What does Net Forge use for transport?

Rooms run on Colyseus over WebSocket. The local host in @netforge/kit-play uses @colyseus/core with @colyseus/ws-transport, and the browser connects with the Colyseus SDK.

Do I need to write prediction myself?

No. The template predicts the local player with the shared simulation and reconciles against the room's snapshots. See Netcode and prediction.

Can I keep my own server?

Net Forge games run on Net Forge rooms. If your game logic must stay in your own server, a room framework such as Colyseus is the better step up from Socket.IO (Net Forge and Colyseus).