UT2004 recently became free with master servers back online. The game still has a small but dedicated competitive community, and they deserve better than browsing random public servers. So I'm building a modern competitive platform around it.
The idea
Ranked matchmaking, leaderboards, friends, voice chat — the full stack. A React frontend with an mIRC/NNscript aesthetic (if you know, you know), backed by a distributed Go backend that manages game server instances.
The platform handles the full lifecycle: queue up, get matched, a UT2004 server spins up, players connect via ut2004:// protocol handler, match results flow back for ranking.
The hard part: distributed game servers
You can't run all servers in one location — latency matters for a twitch shooter. The backend runs as a single Go binary in leader/worker mode. Leader nodes handle matchmaking and coordination. Worker nodes manage UT2004 server processes.
The nodes form a cluster using embedded NATS for messaging and Raft for consensus. When a match is made, the leader picks the best worker node based on player locations and spawns a game server there.
Game server control
Each UT2004 instance runs with a custom UnrealScript mutator that communicates with the Go backend over TCP. The mutator reports events (player joins, kills, match end) and the backend can send commands (kick player, end match, change map).
This is the jankiest part of the stack and also the most fun. UnrealScript hasn't changed since 2004, and debugging it involves reading log files that mix engine output with gameplay events.
Voice chat
WebRTC via pion/webrtc. The Go binary includes a lightweight SFU (Selective Forwarding Unit) that relays audio between players in a match. No external service needed — voice runs on the same cluster nodes as everything else.
Current state
The core platform works: queue, match, spawn server, play, record results. Ranking uses a standard Elo system. The mIRC-themed UI is surprisingly usable. Currently running on a single Hetzner node for testing, with plans to expand to multi-region once the platform opens up.