Inspired by the likes of Crossy Road, Frogger and Giant Margarita’s party franchise, this game pits players against time and each other to see who will survive the longest in a procedurally generated world filled with hazards.
The key objectives for this project were to create a casual couch co-op party game that integrates with Discord’s rich presence and the Steamworks SDK. It should have lots of menu options for players to customize (and save presets of), have procedural world generation and be available for download from Steam. As we were a small group, we also experimented with Unity Collaborate, PlasticSCM and Git/Azure DevOps and build/deployment pipelines.
- Version Control
- DevOps, CI/CD, Pipelines
- Player input and local lobby management
- Player controls
- World generation
- UI Logic
- Handling of the game and player state between various scenes
- Saving/Loading of various world generation settings to allow players to create their own presets
- Organizing Steam integration through the Steamworks SDK
- Implementing Discord Rich Presence through the Discord Games SDK
The title screen (and any of the menu screens) have the world generator running in the background to give the player an idea of what the current generator settings look like.
Given that this game is designed with an ever growing list of customizable options, it would be tedious for us to add each setting as a manual UI element and hooking up relevant events when those settings change. Instead, I implemented a dynamic settings system using ScriptableObjects. The game dynamically loads all settings objects and instantiates any UI elements with a prefab for the type of setting (toggles for boolean settings, sliders for float settings etc) and dynamically hooks into our ScriptableObject event system to provide real-time updates as those settings get changed as seen in this example.
Settings vs Presets
There are settings that affect gameplay, and settings that are only relevant to the individual player's experience. Because the presets system was written agnostically, I was able to re-use it for specific player-only settings as well. These don't make as much sense in local multiplayer as that is a shared-screen experience, but for online play only the preset settings need to be networked.
Gameplay & Lobby
The lobby is the staging area for the game - it's here where players can join with various input devices (Keyboard, Controllers), select a skin and ready up. We decided against having a massive player object with a representation of a lobby player and a game player, and instead have them as separate prefabs that both accept a playerState object. This way there is no dependency between scenes and no need for keeping objects as DDoL. Once everyone readies up in the lobby, the playerStates get stored in a static gameState class, which is then read from in the game scene to instantiate each player with their respective controls, skins and names.
- Settling on version control, we ended up trying them all (and settled on git)
- Two team members dropping out of the project
- Scope creep at every corner because no clear goal was defined
- Completing the project — it was worked on post assignment but never finished