Self-hosted multiplayer VR β your own metaverse server. WebRTC SFU Β· Real-time pose sync Β· Spatial audio Β· Asset CDN Β· Unity + Unreal SDKs.
Photon costs money. Mirror requires you to host. Unity Multiplayer keeps shutting down. Building your own VR multiplayer from scratch takes 3 months.
vrcollab is the open-source, self-hosted answer:
- π Up to 50 concurrent users per room (tested on a single 4-vCPU VPS)
- ποΈ Spatial voice via WebRTC (LiveKit-compatible SFU)
- π€Έ Sub-60ms pose sync at 90Hz for hand + head tracking
- π¦ Built-in asset CDN with on-demand streaming
- ποΈ Drop-in SDKs for Unity, Unreal Engine 5, and WebXR
- π End-to-end encryption optional
- π‘οΈ Anti-cheat hooks built into the protocol
git clone https://github.com/kasimmj/vrcollab
cd vrcollab
docker compose up -dYou now have:
- Signaling/room manager at
:7880 - SFU media servers at
:50000-50100/udp - Asset CDN at
:8080 - Admin dashboard at
:7881
Unity:
# Add via Unity Package Manager
git+https://github.com/kasimmj/vrcollab.git?path=/sdks/unityusing VRCollab;
var room = await VRCollabClient.JoinRoom("metaverse-hilla", playerName: "Kasim");
room.OnUserJoined += user => Debug.Log($"{user.Name} joined");
room.OnUserPose += pose => UpdateAvatar(pose);Unreal Engine 5:
Drop the VRCollab plugin into Plugins/, then:
#include "VRCollabSubsystem.h"
auto* VRC = GetGameInstance()->GetSubsystem<UVRCollabSubsystem>();
VRC->OnUserJoined.AddDynamic(this, &AMyGameMode::HandleUserJoined);
VRC->JoinRoom("metaverse-hilla", "Kasim");WebXR:
import { VRCollab } from '@vrcollab/client';
const room = await VRCollab.join('metaverse-hilla', { name: 'Kasim' }); ββββββββββββββββββββββββββββββββββββββββββ
β SIGNALING LAYER (Go) β
β Room manager Β· auth Β· token issuance β
βββββββββββββββ¬βββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
βββββΌβββββββ ββββββββΌβββββ
β SFU #1 β ... N β SFU #N β
β (Pion) β β (Pion) β
ββββββ¬ββββββ βββββββ¬ββββββ
β β
ββββββΌββββββββββββββββββββββΌββββββ
β VR Clients (Unity/UE) β
βββββββββββββββββββββββββββββββββββ
ββββββββββββββββ ββββββββββββββββ
β Asset CDN β β Postgres β
β (S3/MinIO) β β (rooms/users)β
ββββββββββββββββ ββββββββββββββββ
- Signaling: custom Go service over WebSocket β issues JWTs, manages room state
- SFU: Pion (Go) β relays audio + low-bandwidth pose streams between peers
- Asset CDN: MinIO + on-the-fly transcoding for textures and meshes
- DB: Postgres for room metadata, user accounts, and audit logs
Audio is positioned in 3D space using HRTF (Head-Related Transfer Function) on the client. The server only routes streams β it doesn't process audio.
Configuration:
audio:
spatial: true
hrtf_dataset: "ircam-2024" # or "mit-kemar"
max_distance: 30.0 # meters before silence
rolloff: "inverse" # "linear" | "inverse" | "exponential"
voice_codec: "opus" # 16kHz mono, 32kbpsvrcollab uses a custom binary protocol over WebRTC data channels for pose sync. Every 11ms (90Hz), each client sends:
PoseFrame {
user_id: u32
timestamp: u64 (microseconds since session start)
head: Pose (position + rotation)
left_hand: Pose
right_hand: Pose
body_ik: [16 Γ Pose] (optional, for full-body)
voice_amp: f32 (for lip sync)
}
Total: ~120 bytes per frame, ~88 Kbps per user. The server uses dead reckoning to predict missed packets and delta encoding to reduce bandwidth by ~60%.
vrcollab provides protocol-level hooks:
- Server-side teleport validation β refuse poses with sub-second jumps > 5m
- Voice amplitude clipping β prevent voice volume exploits
- Rate limiting per RPC, per user
- Replay protection via sequence numbers + timestamps
Game-specific anti-cheat (aimbot detection, animation cancels) is up to your SDK integration.
Benchmarked on a 4-vCPU 8GB VPS (single node):
| Metric | Value |
|---|---|
| Max concurrent users in one room | 50 |
| Max simultaneous rooms | 200 |
| Total bandwidth at 50 users | ~5 Mbps |
| End-to-end pose latency (LAN) | 22ms |
| End-to-end pose latency (WAN US-EU) | 95ms |
| Audio glass-to-glass latency | 110ms |
For larger deployments, vrcollab supports horizontal SFU scaling β add more sfu containers.
config.yaml:
server:
signaling_port: 7880
admin_port: 7881
jwt_secret: "${JWT_SECRET}"
sfu:
rtp_ports: 50000-50100
ice_lite: false
external_ip: "${PUBLIC_IP}"
rooms:
default_capacity: 30
max_capacity: 100
idle_timeout: 5m
assets:
cdn_url: "https://assets.your-domain.com"
storage: "s3://your-bucket"
cache_ttl: 24h
auth:
provider: "jwt" # or "oauth", "anonymous"
oauth:
providers: [google, github]- Collaborative design β architects walking clients through buildings
- Remote education β instructors teaching in shared 3D spaces
- VR film production β directors blocking scenes with remote crew
- Multi-user training simulations β medical, industrial, military
- Social VR communities β your own VRChat/Rec Room alternative
- Real-time motion capture β sharing performances between studios
- Core signaling + SFU
- Unity SDK
- Unreal Engine 5 SDK
- WebXR client
- Avatar system (Ready Player Me integration)
- Full-body IK over the wire
- Recording + playback (.vrcap files)
- Federation (rooms across multiple servers)
Apache-2.0. See LICENSE.
Star β to build your own metaverse.