Arena Protocol

2-Player Co-op Multiplayer Survival Arena

Real-Time Multiplayer • Netcode for GameObjects (NGO) • Windows

Unity 2022 LTS Netcode for GameObjects Server-Authoritative State Machines Session Reconnection

Project Overview

Arena Protocol is a real-time 2-player co-op survival arena built with Unity Netcode for GameObjects (NGO). Two players fight through wave-based enemies together, using a modular ability kit — dash, projectile, and heal — while the server maintains full authority over combat, AI, and scoring.

The project was built to deeply understand host-client networking fundamentals: NetworkVariable-driven state replication, server-authoritative combat validation, and — the hardest part — building a session system robust enough to survive a real disconnect and reconnect without losing player progress.

My Role & Responsibilities

Engineering & System Design

Networking Model — Host-Client (NGO)

The host acts as both server and Player 1; all authoritative gameplay logic runs on the host. The client sends input to the server and renders the resulting replicated state.

Modular Ability System

Every ability extends an abstract BaseAbility (itself a NetworkBehaviour) with a server-authoritative cooldown tick and a shared TryActivate() pattern. New abilities only need to extend the base class and implement Activate() — no changes required elsewhere.

Server-Authoritative Enemy AI

Enemy behavior runs exclusively on the server as a Patrol → Chase → Attack state machine, eliminating any possibility of enemy desync between clients. Positions replicate to clients via NetworkTransform interpolation.

Challenges & Solutions

Challenge: Reconnection with a shifting clientId

NGO assigns a new clientId to a client on every reconnect, so any session state keyed directly on clientId breaks the moment a player rejoins.

Solution: Built a SessionManager using a static, slot-based dictionary instead of a clientId-keyed one. Health and ability cooldown state are saved on disconnect and restored once the player object respawns after rejoin — regardless of the new clientId assigned.

Challenge: Bridging scene UI to dynamically spawned player prefabs

Prefab Inspector references can't point at scene objects directly, but health bars and ability UI needed to react to a player prefab that only exists at runtime.

Solution: A one-time GameObject.Find() wiring step on player spawn bridges the scene UI to the spawned prefab, with zero runtime performance cost since it only fires once.

Engineering Tradeoffs

Impact & Results

Gameplay & Source

🎥 Gameplay Video
💻 GitHub Repository