kerboul 32becc12f9 feat: free-roam mode + fix multiplayer sync + remote player polish
Backend (ArenaRoom.js):
- Strip race state machine (lobby/countdown/playing/round/qualify). Persistent
  "playing" phase, no rounds, no checkpoints. Free-roam multi.
- Spawn lowered to y=1.5 (was 5) + MIN_DIST raised to 5 (was 3) to avoid
  ejecting overlapping players at connect.
- Schema kept intact (handshake-safe); deprecated fields default-valued.
- npm run schema:gen wired (anti-drift codegen).

Unity client:
- C# schema generated by schema-codegen into RolldSchema namespace
  (Generated/GameState.cs, Generated/Player.cs). NetworkSchema.cs removed —
  handshake no longer scans global namespace.
- NetworkManager: typed Room<GameState>, callbacks rebound, seeds players
  already in room on join.
- RemotePlayerController:
  * Post-spawn 1.5s grace window (BumpReady) — local PlayerController.HandleBump
    ignores remotes during grace.
  * Solid SphereCollider disabled during grace, re-enabled afterwards — fixes
    the kinematic-vs-dynamic eject when a new client spawns inside someone.
  * NPCBall prefab material switched from invisible-in-URP Default-Material to
    BallShader.shadergraph.
  * TrailRenderer added, tinted with player's chosen color.
  * Name label distance-scales (1x-8x) so pseudos remain readable far away.
- GameHUD: OnGUI emptied — race UI (rounds, mode, timer, playersAlive) gone.
- GameCanvas.jsx: BUILD_PREFIX/VERSION bumped for cache-bust.

Frontend WebGL build (pretty_build): final build with all the above.
2026-05-20 12:25:48 +02:00

ROLL'D

Browser-based marble MMO — multiplayer physics, real-time leaderboards, playable directly in your browser.

Unity 6 WebGL Colyseus React Vite Tailwind

Play Now


What is ROLL'D?

ROLL'D is a multiplayer marble game that runs entirely in the browser via Unity WebGL. Players control a physics-based ball in a shared 3D arena, competing for distance, speed, and style. The game features real-time synchronisation at 60 Hz, in-game chat, and persistent leaderboards.

No install. No account. Just open the page and roll.


Features

  • Real-time multiplayer - up to 20 players per room, 60 Hz state sync via Colyseus WebSockets
  • Physics-based gameplay - Unity Rigidbody, jump charge, gel pads (speed boosts), ball-to-ball bumps
  • Room lobby - browse open rooms, create your own, choose your colour and name
  • In-game chat - accessible in-game (T key) and on the dedicated website chat page
  • Live leaderboards - distance, max speed, jumps, bumps, playtime, updated every 30 seconds
  • Spectator camera - orbiting camera while in lobby or after disconnecting
  • WebGL-native - no plugins, no downloads, runs in Chrome/Firefox/Edge

Architecture

rolld/
├── game/                  # Unity 6 project (WebGL build)
│   └── Assets/Scripts/
│       ├── Network/       # Colyseus SDK integration, schema, lobby UI
│       ├── Stats/         # StatsTracker - periodic HTTP upload
│       └── UI/            # IMGUI in-game HUD, chat, keybinds
│
├── rolld_backend/game/    # Colyseus 0.17 game server (Node.js)
│   └── src/
│       ├── rooms/         # ArenaRoom - game state machine
│       ├── schema/        # Colyseus schema (Player + GameState)
│       ├── stats/         # StatsManager - JSON persistence
│       └── chat/          # ChatManager - in-memory history
│
└── frontend/              # React + Vite + Tailwind SPA
    └── src/
        ├── pages/         # Home, Stats leaderboard, Chat
        └── components/    # NavBar, GameCanvas (Unity embed)

Network flow

Browser
  └── Unity WebGL (GameCanvas iframe)
        └── Colyseus SDK (WebSocket wss://)
              └── ArenaRoom (Node.js)
                    └── Broadcast state @60 Hz

Browser
  └── React SPA
        └── REST API (HTTPS)
              ├── GET  /stats/leaderboard/:key
              ├── GET  /chat/history?since=
              └── POST /stats/update  (from Unity every 30s)

Tech stack

Layer Technology
Game engine Unity 6 LTS, C#
Multiplayer Colyseus 0.17 (Node.js + WebSocket)
Frontend React 19, Vite 5, Tailwind CSS 3
Deployment Docker, Coolify, nginx
Self-hosted Proxmox LXC, Gitea, Traefik reverse proxy

Running locally

Prerequisites

  • Node.js 20+
  • Unity 6000.x (for game builds only)

Game server

cd rolld_backend/game
npm install
npm run dev

Server starts on ws://localhost:2567.

Frontend

cd frontend
npm install
npm run dev

Open http://localhost:5173. The frontend points to the production game server by default - edit src/pages/StatsPage.jsx and src/components/GameCanvas.jsx to switch to localhost.

Unity (optional)

Open game/ in Unity 6. The server URL is hardcoded in Assets/Scripts/Network/NetworkManager.cs. Switch to wss://game.rolld.kerboul.me for prod or ws://localhost:2567 for local testing.


Controls

Key Action
WASD / Arrow keys Move
Space (hold) Charge jump
Space (release) Jump
T Open chat
Escape Close chat
Tab Show keybindings
Backtick (`) Debug network info

Live deployment

Frontend Game server Self-hosted

The stack runs on a self-hosted Proxmox homelab cluster. Coolify handles container orchestration and auto-deployment on git push. Traefik manages HTTPS termination.


Licence

MIT - do whatever you want with it.

Description
ROLLD - multiplayer ball game
Readme 369 MiB
Languages
C# 43.1%
ShaderLab 23.4%
JavaScript 17.4%
GLSL 6.9%
HLSL 6.3%
Other 2.9%