← Selected Work
2023 - 2024 Multiplayer Lead engineer

Real-time multiplayer on the Nova runtime

Seven first-party multiplayer titles ship on Nova - the most-played is Daily Fishing, a multi-player arena game where 4 players in a shared room shoot projectiles at fish for in-game currency. Real-time gameplay plus money in a wallet means there is no room for "eventually consistent." This is the netcode model behind it.

Titles shipped
7
Players per room
4
Server tick rate
30 Hz
Targets
Android · WebGL · Standalone

Why server-authoritative was non-negotiable

Every fish kill is worth money. A client-authoritative model - where the player's device decides who hit what and how much it paid - would be exploited within hours of release. The server owns the world: fish HP, fish positions, projectile trajectories, hit registration, kill attribution, and payout. The client's job is to render the server's state and forward input.

That decision cascades. Server-authoritative means the server runs the authoritative simulation and broadcasts state at NGO's 30 Hz network tick, and clients interpolate between those snapshots. Input latency has to feel acceptable on mobile networks where 80–200 ms RTT is the median, not the tail. Hit feedback (the satisfying "kill flash") is rendered optimistically client-side and reconciled on the next server tick - if the server says you missed, the flash is rolled back.

sequenceDiagram
    participant C as Client
    participant S as Server
    participant W as Wallet
    C->>S: Fire(input, clientTime)
    S->>S: Spawn projectile (server-sim)
    S->>C: ProjectileSpawned(id, traj)
    Note over S: simulate at tick rate
    S->>S: Hit detected · fish HP -= dmg
    S->>S: Kill · attribute to player
    S->>W: CreditPayout(player, amount)
    W-->>S: Ack
    S->>C: KillEvent(fishId, killer, payout)
    C->>C: Render kill VFX · update HUD
            
Authoritative kill & payout flow

Cross-platform parity: one server, two transports

The same NGO server logic accepts Unity Transport from native clients (Android, standalone) and WebSocket from WebGL clients in the same room. WebGL can't open raw UDP, so the transport split was forced; the alternative was forking the netcode, which would have doubled the bug surface for every multiplayer feature forever.

The transport setup itself is part of the Nova platform; for the architecture, see the Nova case study.

Deployment

Multiplayer game servers run on Edgegap with regional deployments and prewarmed scaling policies. The migration from Unity's deprecated DGS hosting and one notable bug in Edgegap's scaling-policy monitor (which they fixed in 0.0.7) are covered in the Nova case study.

← Back to Selected Work