A game room, ready-made
Seats, turns, moves validated by 4 server guards (seated? phase? turn? rate?) then broadcast in one batch per microtask — arbitration stays server-side.
A ready-made game room (moves, guards, tick), serious netcode (interpolation, prediction, lag compensation, deterministic lockstep), Redis/SQL persistence — and the same component language on the server side (*.server.mjs).
Seats, turns, moves validated by 4 server guards (seated? phase? turn? rate?) then broadcast in one batch per microtask — arbitration stays server-side.
Measured demo: at 200 ms of latency, the average on-screen jump drops from ≈6.0 px to ≈1.5 px (÷4) and the hit rate goes from 0% to 100% (interpolation + prediction + lag rewind).
*.server.mjs is the same component dialect as the client — an optional typed contract shares view/moves between app.game and sock.game without duplicating types.
A move, a guard, a broadcast — game.next() hands the turn to the next occupied seat.
app.game 'morpion', seats: 2 state: (game)-> { grille: Array(9).fill(null) } moves: jouer: (game, player, p)-> throw new Error('case occupée') if game.state.grille[p.i]? game.state.grille[p.i] = player.id game.next()
Local simulation — a plain interval replays partie.next() here, no real server involved.
Figures come from the docs and the netcode demo bench — see docs/24-mjs-server.md for the full methodology.
Fixed-rate loop (up to 60 Hz) plus a per-player diff — only changed fields go on the wire.
Optional spatial index — each player only receives entities within its query radius.
µ.predict applies the intent locally, then replays on top of the server state after each update.
def.histo + partie.rembobiner validate a shot against the position the shooter actually saw.
def.mode: 'lockstep' — the server only relays orders; µ.det keeps sin/cos/atan2 reproducible.
Adapters provided (Memory/File/Bridge/Redis/SQL), debounced, loaded before the server even listens.
Inherited from MJS-WS — a room (a game's chat, say) can keep a bounded log for latecomers.
Moves applied immediately client-side (µ.predict) before server confirmation, snapped and replayed on correction.
| Criterion | MJS-Server | Colyseus | Meteor | Custom server |
|---|---|---|---|---|
| Netcode provided | ✓ | partial, via plugins | no (DDP sync) | to write |
| Determinism (lockstep) | ✓ | not built-in | not built-in | depends |
| Persistence | ✓ | via plugins | MongoDB only | to build |
| End-to-end typed contract | ✓ | typed schema, not moves | no | depends |
| Reactive front integration | ✓ | manual listeners | ✓ | depends |
Figures are indicative and meant to be honest, not promotional.
One command to get the framework.
npm install mjs-frameworkThe core + only the modules you use:
mjs.config.json"runtime": ["socket", "schema", "smooth", "game", "interp", "predict", "det", "lockstep", "optimistic"]