Volley Guns (2025)
Sport
Local
Online
2-4 Players
Team
Shooter
Released
Game Trailer
Role:
| Network Engineer
Team Size:
| 11 (Todd's Team)
Time Spent:
| 1 year, 2 months
Engine:
| Unity
V
O
L
L
E
Y
G
U
N
S
Overview
Volley Guns is a 2-4 player local-online sport-turned-shooter game that combines elements of volleyball with fast-paced shooter gameplay,
creating a unique twist on a familiar sport.
I was onboarded onto this project after the team had about 4 months of time working on it, and tasked with introducing networking.
I was recruited by my teaching assistant after he reviewed my previous project, Ancient Olympics, recognizing
my experience with multiplayer systems.
Since then, I've been working with a talented team to bring this interesting game concept to life and expanding it to multiplayer.
Steam Compatibility
Immediately when I joined the team, they let me know they were planning to release the game on Steam. This required me to implement multiplayer compatibilities with Steam's API. This is very notable for the online lobby system I created.
I've designed online lobby systems before, however, creating one that's compatible with steam required a slightly different approach than the
types of implementations I developed before, so I quickly got to work on designing the new implementation.
Steam's lobby API comes with it's own callbacks that makes it easy to hook to a lobby's OnCreated,
OnEntered, and OnDisconnected.
Creating a lobby involved obtaining a Steam ID for the lobby and pairing it with the
host's address. However, Steam’s generated lobby IDs are not user-friendly for direct sharing.
I used a RealTime Database hosted by Firebase to store a joinable lobby code
that was easy and readable for players. What I did was generate a 6 character code, mapped it to a Steam Lobby ID,
and created some functions to grab that code whenever necessary.
When a player enters a lobby code, the system queries Firebase, retrieves the corresponding Steam Lobby ID,
and connects the player to the host. This streamlined the join process and made the system more accessible for players.
Player Data Management
When a new client connects to the server, a player object is created to store essential information about that player. I designed a structure that ensures each player’s details are properly tracked and synchronized across the network.
I implemented this using a PlayerData class, responsible for storing a player’s
ClientID (identifies the client),
UserID (identifies the player),
TeamID (identifies the team), and
ModelIndex (identifies the chosen character).
The class and its attributes are serialized on the network to ensure compatibility across clients.
When a player joins, a PlayerData instance is created and assigned to the first available slot in a
networked list for efficient retrieval. Since the game supports up to four players, each entry is stored sequentially and kept in sync
with its corresponding player object.
When a player disconnects, their data is retrieved from a map and safely removed, ensuring the system remains consistent.
Reconstructing Pre-existing Systems
When I joined the team, the game was already in development with core gameplay implemented locally. My role was to understand the existing systems, collaborate with the developers, and help adapt these systems for networking.
The two core systems of the game are the GameManager and RallyManager.
The GameManager controls match flow—starting games, tracking scores, and beginning rallies—while the RallyManager handles ball spawning/serving,
relocating players, and detecting when the ball hits the ground. Together, these managers maintain smooth gameplay cycles and include their
own timer systems for match and round duration.
Part of syncing these systems across the network was first identify which elements needed to be synced on the server and which
should be kept on clients. A general rule of thumb I went by was "If everyone needs to see or access it, sync it." This helped in
finding which parts needed to be synced.
The more difficult task was separating overlapping responsibilities—determining what logic belonged exclusively on the server versus what
should be distributed to clients. I tackled this by reorganizing systems into a clearer structure before layering the network.
After integration, came play-testing, refactoring, and more play-testing.
What I've Learned
Networking an already established local game is challenging. Many systems had to be reconstructed from the ground up.
It took a lot of time to both study and identify those systems. Though, working with a great team can make the process far easier.
The hardest part was deconstructing large, interwoven scripts into smaller, manageable components.
Looking back, there are strategies I would approach differently if I tackled a similar challenge again.
It was all worth it in the end though. Seeing this game come to life across a network was a very rewarding and fun experience. I hope the ship
to Steam is very successful!