Final Major Project
Not in My Neighbourhood! - Online multiplayer game
As part of my final major project I decided to make a simple online multiplayer game.
I thought it would interesting to test myself in terms of programming and working in engine through this project.
Idea Generation
The idea came to me since recently I have been engaged in various online multiplayer games with my friends. So I thought about something that we could potentially play together and have fun doing so.
​
Part of the inspiration to make this type of game came from indie games like Phasmophobia (2020) and Lethal Company (2023). These games are online games relatively simple mechanics and game loops which were initially made by single developers.
​
Given the limited time I have to work on this project I had to make something simple with a relatively small scope.
There was a very popular game mode called "Prop Hunt" originally created for Counter-Strike: Source (2004) and ported by Andrew Theis (2023) to Garry's Mod (2006).
​
The premise of prop hunt revolve around two different teams, the "Props" team which can disguise as different props found around the map and the "Seekers" team which uses a variety of weapons to attempt to find and eliminate the prop team.
​
Using the premise of Prop Hunt I considered a game where there is a reversal of roles, a game where the Prop team hunts the Seeker team instead. The dynamics would be relatively different and I imagine it would be funny to have something like a park bench chasing you around.
​
With this in mind I had a pretty good idea of what kind of game I could attempt to make as my project, as for a project game "Not in My Neighbourhood!" sounded like a solid and funny name for the nature of the game.
​
References
Counter-Strike: Source. (2004). PC [Game]. Valve
Garry's Mod. (2020). PC [Game]. Valve
Lethal Company. (2023). PC [Game]. Zeekerss
Phasmophobia. (2020). PC [Game]. UK: Kinectic Games
Theis, A. (2023) andrewtheis/prophunt. Available at: https://github.com/andrewtheis/prophunt (Accessed: 13 February 2024).
Not in My Neighbourhood! - GDD
Materials
For the purpose of this project the materials and resources that I am going to use are as following:
​
Game Engine: Unity
Programming: Rider, Visual Studio Code
Image Editing: Photoshop
3D Assets: Maya
Audio: FMOD, Game Synth Tool
​
For the game assets (3D and audio) they mainly will be online sourced from either free or paid sources. I have included Maya as my 3D software in the case I may need to create some of my own assets to include should I not be able to procure suitable assets.
​
Networking
As an online game the first thing I needed to think about is what are my options for networking in my chosen game engine.
​
For the game engine I chose to use Unity, I looked at some networking options for Unity which included:
​
- Unity Netcode (https://unity.com/products/netcode)
​
-Photon (https://assetstore.unity.com/packages/tools/network/pun-2-free-119922)
​
-Mirror (https://assetstore.unity.com/packages/tools/network/mirror-129321)
​
I looked into a few online tutorials on how to implement each of these networking options and opted to try using Photon.
​
Photon allows me to use their free plan which allows for 20 players connected simultaneously, during the development stage I reckon I wouldn't have more than 5 to 10 players at any given time so it suited my needs for the project.
There are also quite a few online tutorials when using photon in Unity that I can use as a basis when making my first playable prototype.
​
​
GDD - Game Design Document
Given that I had already made a game concept of the game I needed a simple Game Design Document to help guide me through the development of the game.
​
I made an initial draft for the design document to include the concept and which mechanics/dynamics of the game i should make.
​
The main takeaway is that the game is an asymmetrical multiplayer game where players are divided into 2 teams, the prop team and the survivor team.
The prop team's objective is to eliminate the survivor team.
The survivor team's objective is to escape the area by unlocking the exit while avoiding being eliminated.
A time limit would be imposed to force the players to move around, and if no team has completed their objective before the time limit then the game would end at a draw.
​
As form of balancing I limited the number of players in the prop team to one player as they have the advantage of passing off as a regular prop in the map as well as limiting their weapon range to melee range, meanwhile the survivor team does not handle any weapons.
Not in My Neighbourhood! - Assets and Network: Player Lobby
Assets
Before actually starting working on the network I had a look through Unity Asset Store for some initial 3D assets to use, I came across a couple demo packages that I could use.
They are low poly and the character assets already include the basic animations that I need for a prototype.
Toony Tiny People
Toony Tiny City
Available at: https://assetstore.unity.com/packages/3d/environments/urban/toony-tiny-city-demo-176087
Network - Player Lobby prototype
With the help of an online tutorial I started making my connection and lobby scenes, it mainly uses 2D elements and default unity assets.
The server is hosted by photon. I had to make an account in photon and created a new cloud app.
I then added Photon to my project and set it to use the App ID from the photon dashboard app.
With the game project connected to the photon cloud services I could then start making the connections and lobby in the game.
Connecting to Lobby
In the first scene I wanted to prompt the players to choose their own nickname prior to connecting, I also set a character limit on the input field to 16 characters.
Then I wrote a script that takes the input information and saves it under Nickname on the Photon Network then connects the user, and sending them into the next scene.
Connect to lobby script
Lobby Scene
List of rooms with no open rooms
In the Lobby scene the users can create their own rooms or join existing rooms.
They can set a name for the room or if no input has been made then a default name room will be set for them by using the username they chose in the first scene followed by "'s room".
List of rooms with an available room
For testing purposes I made a build and ran it alongside running the game in unity, and on the second user I created a room.
​
To join a room users would just have to click on the room from the list
When a user has entered the room a player card with their username shows on the list of players, there users can modify their player avatar.
Panel when entering an existing room
Host player's panel with two players connected
If more than 2 players are connected then the room's host is able to initiate play. The play button only shows up when 2 or more players are connected.
Lobby Manager script
Lobby Manager
The Lobby Manager script handle's most of the events in the lobby.
When the scene starts the users Photon network's lobby for the game application.
Clicking Create room essentially creates a joinable room in the Photon Network with a limit of 5 players.
This enables the Room panel and disables the Lobby panel then sets the room name text to the room name created in the input (or uses the default "username's room" when no input has been created) and updates the player list panel by taking the UI PlayerItem prefab which includes the player's nickname.
​
A function keeps the Room list updated at fixed intervals.
​
In the Room panel the player list is updated whenever a new player joins or leaves the room (it updates when a player presses leave room or disconnects from the photon server)
​
The Play button is set to be active under the circumstances that the number of players is 2 or more and only appear to the player that is the master/host of the room. In the case the previous host disconnects the host changes to the second player that has joined.
Lobby Manager on the inspector
The Player Item script is made to manage and display information about individual users/players.
It also saves player-specific information and references to the player.
Arrow buttons where the player can change their avatar, the arrow buttons will only be displayed to the local player while the avatar changes will be seen by all the players currently connected to the room.
​
PlayerItem, RoomItem scripts
A1 Pre-vis Presentation (Week 4)
Not in My Neighbourhood!
This assignment was a presentation and form of pre-visualisation of the project.
Using the concept I created as a basis I made the following slides and presented them during the lecture on Week 4.
I used the 3D assets I picked in the previous week and inside unity put together a few scenes to help visualise the feel and concept of the game itself.
Presentation Slides
Not in My Neighbourhood! - Network part 2
Network architecture
While working with Photon PUN I have encountered several hurdles, learning how to work with network and implement it in games proved relatively challenging to me.
So I experimented using Photon Fusion which seemed to have been optimised for and offered a lot of pre-made scripts to supposedly make it easier to work with.
​
I picked the current project's assets and created an entire new project to implement Fusion with, Fusion's scripts did indeed eased synchronization over the network but it uses a whole different method for scenes in which it loads and unloads scenes rather than changing scenes all-together, which I found very confusing to use.
On Fusion's tutorials also introduced me to a player controller that works over the network, setting the player a network object and each keypress is sent over the network essentially moving the player character. What I found in terms of issues from this method is the delay between keypress and action, but the most frustrating issue was the camera being extremely shaky, during testing it just didn't feel good to play no matter how much I adjusted settings of the camera following the player character.
​
Given that Fusion is relatively new I found it hard to find enough content and tutorials for the specific logic I wanted to use in the making of the game so after careful consideration I opted to return to the old PUN architecture and update the build with the fixes and some of the logic I gained from working on the Fusion build.
​
​
​
Player Spawning
While in and out of PUN and Fusion I addressed player spawning.
The script is relatively simple, it gets the int value of the local player's custom properties avatar and spawns the player prefab from the list which has been setup in the inspector to match up with the player's choice of avatar.
In this case I set that the player avatar with value of 0 is the prop player (which I then adjusted the playerItem script to handle as well)
Various spawn points have been setup on the game area and added to a list of Transforms, and have players spawn randomly within the spawn points with the prop player spawning at a specific location in the map.
​
Player Spawner Script
Player Controllers, Issues
With players being spawned successfully I thought about trying different types of player controllers and seeing how it would work with at least 2 players connected into the game encountering a few issues.
First issue being with cameras.
I am using cinemachine cameras, and whenever a players were initiated into the scene the camera would assign the player that loaded in last as the target player.
I tried assigning a camera to the player prefab but then I did not want to have too many cameras on the scene as it could cause issues.
So I just allowed one camera on the scene and assigned the player a simple script that finds the camera in the scene and if the player is the photon view owner then change the camera settings to make it the target of the camera. in this manner it would only affect the local player.
Player Camera Script
The other issue being with player controllers and another issue that the only thing that was being changed over the network was the rotation of the player. Which I found out was because I had the animations set to apply to root and this working together with photon's animation viewer caused issues.
I tried 2 different types of player controllers each with its own pros and cons:
-
Controller that registers the input onto the network and waits for network response to move
-
Regular using update method to process controls with Photon tracking the game object's transform position.
1 - Input processed over the network
With the first type of controller it would accurately position the player in the world but the movement delay was too great, and movement wasn't smooth for the local player. This also affected the camera that is actively following the player, making it "laggy" as the transform position had a big delay between updates. My experience testing the camera with this type of controller was head ache inducing.
​
2 - Input on Update
Controller on Update method, network tracking not as accurate and delays in getting the player position over the network. Could be an issue with synchronization when prop player is trying to attack survivor players.
​
​
In the end I opted with a controller using the Update method for movement, simply because it would be a much better experience for the local player.
Test Player Movement Scripts (Fusion/PUN)
Not in My Neighbourhood! - Core Gameplay Mechanics part 1
Gameplay Mechanics
After having implemented the fixes and returning to PUN architecture I tried to tackle the player character.
up to this point I had a functional lobby that can be connected to and it is correctly spawning the player character I configured to spawn based on selection as well as the game object moving around and the movement being applying over the network.
​
However instead of using the models from the Toony Tiny Citizens package I used another 3rd party asset, reasons why is because the Toony Tiny Citizens models did not have the animations set up, and I wanted to focus on the actual gameplay mechanics.
​
While working the mechanics I made a test player character using a Third Person Character Controller from the starter assets in Unity's asset store. ( https://assetstore.unity.com/packages/essentials/starter-assets-thirdperson-updates-in-new-charactercontroller-pa-196526 )
​
I also purchased the Toony Tiny City Extended pack to use as the game area (https://assetstore.unity.com/packages/3d/environments/urban/toony-tiny-city-extended-170772 )
​
Survivor Player Mechanics
For survivor player mechanics the main idea was for the survivors to find items scattered around the map in order to use them to unlock the exit.
Based on mechanics I had work with previously in other game projects I made an inventory system for the local player and a template Key Item script as well as a template Exit Item
The inventory system saves String values and displays them on the player's HUD
When the survivor player enters a trigger capsule on the Key Item object it lets them pick the item by pressing the E button, the Key Item's string value can be set on the inspector.
When interacting with the Exit Object it can check if the player has the specified string value in its inventory when the player presses E, if the player has the correct string value then it will trigger the "debris" to be cleared out revealing the exit.
In order for certain changes to be applied over the network I used Remote Procedure Calls, in short RPC's.
RPC's are method-calls for clients in the same room. In the case of clearing "debris" to have the exit cleared for all players a player could trigger the RPC method that triggers the debris game object to be set as inactive for all players connected in the room therefore applying it for every player.
Exit Behaviour, Iventory System, and Key Item Behaviour scripts
Not in My Neighbourhood! - Gameplay Mechanics part 2
Control Panels
Even though with a working inventory and use of item system in place I thought about doing something a bit different but working in the same manner as it would make it more clear to the players what to do.
I made a lever system consisting of a master control panel near the exit of the area and 4 small control panels with each own levers.
In order to operate the master lever all 4 levers need to be operated, supposing that the small control panels reroute power to the master control panel to allow the survivor players to use it and expose the exit.
Control Panel and Exit Control Panel Behaviour
Survivor Player Interactions
for the player to interact with the items I made a script to handle such, it is separate from the controller to make it more modular and easier to add different characters to the playable characters pool.
​
The interactions serve to try and control the properties of the objects the survivor player can interact with, I have separated them by tags, and added a verification for the owner of the PhotonView component of the gameObject in the network to avoid conflict with other players in the scene.
​
There definitely is a better way to handle these interactions but I found that these work in the context of this game, exploring player interactions with the environment is something I would like to develop further in future projects.
​
Survivor Player Interactions script
Not in My Neighbourhood! - Gameplay Mechanics part 3
Prop Player
With a functional Survivor Player Character in place I moved to make the Prop Player.
The mechanics that this player requires is a way to eliminate the Survivors, the ability to change prop and rotate the prop.
​
I used the survivor player template character, removed the scripts related to survivor player mechanics and made new scripts to handle the prop player mechanics.
I made one script to handle the prop changes, and rotation.
I made prefabs for each of the meshes I wanted the prop player to turn into and created an empty object which includes them all in deactivated status. When pressing the key button F then it deactivates the current and activates the following prop on the list in the script. I used an RPC to make sure the changes applied over the network.
To handle rotation the script handles the rotation of the parent object that holds the props, for the rotation I set it as Q and E buttons.
Prop Player Mesh handler
Attack, survivor player health, survivor player status
Then I created few scripts to handle the prop attack and the survivor player health.
The prop can attack using the left mouse button which then triggers an RPC of the attack. the attack is an animation which makes the attacking weapon visible and slices in an arc in front of the prop player.
The weapon is in its own layer, and set to be able to only allow collision with survivor players that are on their own layer, once the weapon enters collision with the survivor player then a script in the weapon game object will handle the damage by interacting with the health script on the survivor player.
Once the survivor player reaches zero health then the SurvivorPlayerStatus script will handle elimination process by adding a custom property to the player setting them as eliminated.
The SurvivorPlayerStatus script also handles escape status.
it is an important script to keep that of each of the network player's status through the game. All these will be used in the GameRoundManager script that handles the round status and winning conditions for the game.
PlayerHealth, PropPlayerAttackHandler, SurvivorPlayerStatus, WeaponDamageZone
If the video does not load please refresh the page or try the youtube link above
Resources
Sound Effects from Pixabay - https://pixabay.com/
Font source - https://www.dafont.com/evil-empire.font
Particle Effects - https://assetstore.unity.com/packages/vfx/particles/hit-impact-effects-free-218385
Not in My Neighbourhood! - Game Round Manager
Game Round Manager
The Game Round Manager script handles everything related to the round.
It keeps track of active players, escaped players and the status of the round and links the stats to HUD items as well
The round only starts once all players have loaded in.
Then whenever there are changes to the player properties and whenever players leave the game and/or get disconnected it will trigger an evaluation of the round on the Master Client, which is the room's leader/host player.
The on evaluation it gets the status from the survivor players and prop player and if the conditions are met then it triggers the end of the round and just displays the end results to all players.
​
I was working on a spectator mode but wasn't successful in making it work in time.
Game Round Manager script
Not in My Neighbourhood! - Testing Alpha Build v0.001
Online test
I ran an online playtest for the game that lasted roughly an hour to test the game for bugs and network stability.
We played the game whilst on voice call on Discord, which of course makes for a more fun experience
Overall the game played well, there were a few issues encountered but none game breaking.
There was an OK balance of wins between the survivor players and prop player.
​
More importantly the attacks, interactions and positions were being properly applied over the network. They could do with some optimisation but the essential aspect that I was looking to develop through this Final Project was to successfully create a multiplayer experience.
​
If the video does not load please refresh the page or try the youtube link above
Issues at the time of test
Lock Cursor to Window
Room List Not Updating On Start (PUN 2 does not seem to have a callback to directly update the list, it does update whenever a new room is created or closed)
Winning Conditions not always giving the correct result (need to double check the conditions set up)
Same player being marked as eliminated more than once (some issues with the collision and delay on marking a player eliminated over the network causes this issue)
active players list not updating properly (was calling the wrong RPC with the incorrect value)
Suggestions
FullScreen - Windowed modes
Spectator Mode
crouch
Not in My Neighbourhood! - Debugging and Script bulk
Debugging and added changes
After the online test I debugged some of the issues found, did some changes to the HUD to display the usernames of the other survivor players while playing as a survivor, and some slight visual changes on the lobby and room screens.
​
I also included a means to choose which region to connect to, saved the Player's username to the player preferences and created a quick match button so the players wouldn't be forced to create a room.