Rooms & Actors
Model your game as rooms full of actors with a clean lifecycle. Two concepts, one mental model.
v0.x · OPEN SOURCE · MIT · NODE.JS
Build real-time multiplayer for Phaser, PixiJS, Three.js, or any browser game. Open-source Node.js framework — rooms, actors, typed binary protocol. Free for commercial use, forever.
— Daniel Kalevski, creator of Rivalis
Define your room on the server. The client subscribes to topics. Frames flow in both directions over a single binary protocol.
import { Room, type Actor } from '@rivalis/core'
type PlayerData = { name: string; score: number }
export class GameRoom extends Room<PlayerData> {
protected override presence = true
protected override onCreate() {
this.bind('move', this.onMove)
}
private onMove(actor: Actor<PlayerData>, payload: Uint8Array) {
this.broadcast('move', payload)
}
}Model your game as rooms full of actors with a clean lifecycle. Two concepts, one mental model.
Bind a topic to a handler, broadcast or unicast — no manual switch statements.
Validate any ticket — JWT, session token, anything — and attach typed actor data.
A typed { topic, payload } format keeps clients and servers in lockstep.
Strict types end-to-end. Actor data, room handlers, and the wire format share generics.
MIT licensed. Free forever, even for commercial games. No per-seat, no per-CCU. Your server, your rules.
CSWSH protection on by default — tunable per transport. 64 KiB frame cap, 30/s token-bucket rate limit, 30 s heartbeat with two-miss disconnect.
Anywhere multiple humans need to share state in real time.
Each demo is a few hundred lines — clone, run, hack.
Both work. Pick by philosophy — not features.
Both are MIT. Both are Node.js. Try both — neither is wrong.
Rivalis ships a single-file skill manifest at https://rivalis.kalevski.dev/SKILL.md. Load it into Claude Code, Cursor, or any agent with a custom-instructions slot, and the assistant will know the recipes, pitfalls, close codes, and security defaults — so the code it generates actually compiles and follows the framework rules. Same approach Phaser uses with its own AI skill files — load once, the assistant follows the rules.
A YAML-fronted Markdown file describing when to use Rivalis, the minimal server & client, the wire protocol, all four room recipes, the auth middleware pattern, close codes, and rate-limiting defaults — everything a coding agent needs in one fetch.
Without a skill, AI agents guess. They forget that __-prefixed topics are reserved, or that rooms must be defined before connections. The skill encodes those rules — your agent stops inventing APIs and starts shipping working code.
The file is served from the same domain as this page. Re-fetch it anytime to pull the latest recipes — or pin a copy into your repo if you want a frozen reference.
~/.claude/skills/# Install the Rivalis skill into Claude Code
mkdir -p ~/.claude/skills/rivalis
curl -fsSL https://rivalis.kalevski.dev/SKILL.md -o ~/.claude/skills/rivalis/SKILL.mdOnce installed, Claude Code picks up the skill on its own — no config, no restart. Project-scoped install: drop it under .claude/skills/rivalis/SKILL.md at the repo root instead.
# Drop the skill next to your repo so the agent picks it up
mkdir -p .cursor/rules
curl -fsSL https://rivalis.kalevski.dev/SKILL.md -o .cursor/rules/rivalis.mdThe format is plain Markdown — paste it into any agent that accepts custom rules, system prompts, or knowledge files.
Read the Rivalis skill at https://rivalis.kalevski.dev/SKILL.md
and use it as the source of truth when you write or review code that
imports @rivalis/core or @rivalis/browser.For chat UIs without a skills system (ChatGPT, Gemini, etc.), the simplest path is to ask the model to fetch the URL and treat it as the framework's reference. The file is small enough to paste inline if web-fetch is unavailable.
Rivalis is early but stable. The author is actively looking for feedback on API ergonomics — anything that feels off, missing, or weird. Open an issue or DM.