March 24, 2023

Gunfight

A Team-based muliplayer shooter coming to Steam

A Top-Down 2D shooter where two teams fight each other to advance in a tournament-style online game. Each player spawns with the same weapon and whichever team is last standing wins that round. Games go on for a best of 5 rounds to see who advances. There is also a free-for-all game mode where random weapons spawn around the map and you have to fight to survive.

Design

I was the solo designer and project manager for this game. I made the overall design decisions like art styles and sprite designs. I also programmed the entire game myself.

Art

I wanted this game to have a cohesive art style so I decided to go with a 70's vector art color palette and style as seen below.

Controls

In this game, the player has a variety of inputs available to them in order to navigate and interact with the game world. The player uses WASD to move while simultaneously aiming their character with the mouse.

Game Feel

One of the main technical challenges in game development is creating a sense of “game feel.” This refers to the tactile and responsive nature of the game’s mechanics, which can greatly affect the player’s experience. By optimizing camera movement, animation, and gunplay, we can create a game that feels responsive, immersive, and satisfying to play.

Camera

The first thing I started with was the camera. Having a smooth top-down camera that could easily follow both the player and the mouse was extremely important. I opted to program the entire system myself, having the camera track a midpoint between the player and the mouse position. That midpoint is then allowed to interpolate within a specified radius to smooth out the movement.

Animation

There is very little animation in this game right now. Most of it surrounds firing bullets and throwing weapons. Firing bullets was done with multiple particles systems that are layered to create a speeding bullet effect. Throwing weapons is a physics based animation that applies momentum and angular velocity to a weapon.

Gunplay

When making any shooter game there are typically two ways you can go about firing bullets. The first way is firing an actual projectile out of the guns and having it fly through space and then detect when it collides with something. This way can be very visually pleasing because you get to see the bullets on screen; however, it can limit the speed at which the bullet travels depending on how collisions are calculated and the speed of the network. For this reason I opted for the second way of firing bullets which is to not fire a bullet at all. Instead you do a 2D Raycast in the direction the gun is facing. This calculates a line from the tip of the gun to whatever is in front of the gun almost instantly. Then you take whatever the 2D Raycast collides with and determine what you hit. This all happens with no visual on the screen so I added particles to make it look like a bullet is firing out at super sonic speeds. This way is optimal because it makes shooting bullets extremely fast and exciting.

									if (PlayerModel.GetComponent().nAmmo > 0)
{
	Vector2 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
	Vector2 direction = (mousePos - (Vector2) shootPoint).normalized;
	RaycastHit2D hit =
		Physics2D
			.Raycast(shootPoint,
			PlayerModel.transform.up,
			PlayerModel.GetComponent().range);
	...
}
								

Networking

Online multiplayer is the core to the gunfight experience. I had never done any networking or online game development prior to this project so there was a bit of a learning curve. This was the main reason I started this project however. I wanted to push myself to learn networking and online matchmaking.

Steamworks & Mirror

I decided to go with the Steamworks and Mirror API's for this project. Steamworks allows easy integration with the Steam platform and Steam multiplayer services. Mirror builds upon the Unity networking system to allow for easy creation of things like network transforms and client/server communication.

Here is an early version of the lobby system where you can easily join anyone's lobby through Steam. It also obtains your username and profile picture from Steam.

									public override void OnServerAddPlayer(NetworkConnectionToClient conn)
{
	if(SceneManager.GetActiveScene().name == "Lobby")
	{
		PlayerObjectController GamePlayerInstance = Instantiate(GamePlayerPrefab);

		GamePlayerInstance.ConnectionID = conn.connectionId;
		GamePlayerInstance.PlayerIdNumber = GamePlayers.Count + 1;
		GamePlayerInstance.PlayerSteamID = (ulong)SteamMatchmaking.
						GetLobbyMemberByIndex((CSteamID)SteamLobby.Instance.CurrentLobbyID, 
												GamePlayers.Count);

		NetworkServer.AddPlayerForConnection(conn, GamePlayerInstance.gameObject);
	}

}
								

After getting lobbies and Steamworks setup, I needed to get the players to sync across the network. This was done with ClientRPC's and Commands. These are functions used to send messages and run code between the server and the client. So things like firing a bullet, spawning a weapon, detecting a hit, and even moving the player all need to be synced across the network with these functions.

Art & Post Processing

My friend Lucas Li did all of the art for this game. He used Aseprite to create various sprite sheets and a sprite map.

He also implemented post processing using Unity's built-in systems. This really helped solidify the look of the game.
Before
After







Retrospective after 10 weeks

The goals for this game that I wanted to accomplish were to create two game modes, team and free for all, implement different weapons, and have shooting mechanics all while being networked. I was not able to implement the team game mode but I did implement a free for all game mode with rounds, multiple weapons, and the shooting mechanics with fully online multiplayer. In the free for all game mode, weapons are randomly spawned throughout the map and the players fight to survive. From the playtesting survey, I found that playtesters were pleased with this game mode and the overall quality of the game. They were pleased with the overall art style, the intuitiveness of the controls, and the fairness of the game. The playtesters also enjoyed the multiplayer aspect of the game, where they could play with their friends. Overall I am so proud of this game and how I was able to push myself to make a networked game.

Future Plans

The game is slated to release by the end of 2023 in Steam. I plan on fleshing out the team-based gamemode, adding a random matchmaking system, and more game mechanics like grenades and armor. Stay tuned to this page for more updates and the eventual release!