Ski Not So Free started from the simple idea "what does the classic 90s game Ski Free look like with multiplayer?" and grew into a multiplayer game in Unreal Engine.


Each race consists of 3-6 players racing down a procedurally generated ski slope. The last place player steadily loses health until they are out of the race. Then, to make things interesting and keep to the Ski Free roots, the former last place player spawns in as yeti and can now attack the remaining players. The race continues until there is only one player remaining.


To help get players right in the action, the game uses Steam matchmaking via the Online Subsystem. This simplified finding and joining sessions and Steam user integration. Having integrated with Steam SDK directly in the past, it was straightforward to set up the usual "OnCreateSession", "OnFindSession", "OnJoinSession" callbacks.
The game uses a listen server model (due to the small race sizes) with one player being the host and other players joining on the host. Since the ski slope is generated dynamically, it is created on the server and replicated to the clients to keep consistent level geometry (so clients don't hit invisible trees). The only other data needing to be replicated (that isn't handled by the Gameplay Ability System) is player transforms and movement. The Character Movement Component did the heavy lifting on that front. While the component incurs a cost, the limited number of characters made it an easy choice. If you wanted to make the next 100 person skiing battle royale, though, you're going to have to make some changes.
I wanted to use this game as an opportunity to finally dig into the Gameplay Ability System. After the initial setup, it was relatively trivial to implement the following:
- Networked player health
- Yeti attacks
- Last place damage over time
- Collision damage
While I could have solved these problems directly using RPCs, the immediate benefit I see is the simplicity of adding other common game mechanics such as:
- Speed buffs and debuffs
- Player items and abilities (think the various attack items in Mario Kart)
- Other player statistics such as speed and turn rate
All supporting replication from the get go while using a common structure and interface.