Snowpainters
3D arcade racer with up to 4-player split-screen couch co-op gameplay. As a penguin, you battle it out with other fellow penguins in a colorful race.
Role
AI + Performance Programmer
Technology
Unreal Engine
Team Size
40
(14 programmers)
Development Time
~3 months (270 hrs)
Contents
Roles and Responsibilities
-
AI Team: During the initial development, I was part of the AI team responsible for creating the prototype for our game's racing AI
-
Performance: Midway through development I took over the responsibility to monitor and improve the project's performance. Towards the end of development, I was leading a team of programmers to tackle our performance problems.
Racing AI Prototype
We wanted the racing AI to feel competing and reactive which meant the AI needed to make decisions based on its surroundings on the track. After exploring multiple solutions, we decided on using a spline-based system with the help of Unreal's built-in behavior trees and AI stimuli features
Spline-based system
For our AI prototype, we used splines as our main navigation tool. We laid a single spline along the path of our tracks and used it as a reference to determine where the penguins had to go. The single spline would act as a global reference that was used by the AI to dynamically generate their own splines during the race along their own chosen paths.
Behavior Tree
Since the beginning we had the idea of having personalities in our AI in the back of our heads. This is why we chose behavior trees during the prototyping stage because we believed it would help us down the road when we would want to add more complex and interesting behaviors. This proved to be prudent as the game shipped with four different AI personalities, each with their own behavior trees.
AI Perception
Unreal has a feature that allows an AI to "perceive" stimuli such as sight, sound, smell, etc. We decided to use this feature and the sight stimuli so that the AI can "see" if they have any items, pickups or competitors around them and possibly adjust their course based on an internal decision making scheme.

Dynamic spline generation

Initial behavior tree mock up for the AI

Configuration of the AI Perception Component
Helper function utilizing AI perception
Improving Performance
Our game was graphically demanding because we wanted to have four-player split-screen gameplay as well a lot of shiny and translucent materials. This meant that performance was going to be a big factor in our ability to ship the game.
Performance Pipeline for Artists and Level Designers
During the middle of development, it became apparent that we needed to distribute some of the performance work load across departments. Many of the bottlenecks were diagnosed and solved but those problems would continue to persist because the solutions were not conveyed to the departments responsible for the bottlenecks. This is why we created checklists for each department to go through to ensure older problems did not continue to persist.
Instance Meshing
One of the challenges we faced was to reduce draw calls because in split-screen the draw calls would increase substantially. One of the primary source of draw call were our props in each track. We decided on using Unreal's instance meshing capabilities which allowed us to render hundreds of props within only a few draw calls. This helped us gain approximately 10-20 frames a second during four-player split-screen gameplay.
Distance Culling
Our final challenge with performance was the paint trails left behind by the racers. Since the paint trails were persistent, they would accumulate over time and the game's performance would worsen over time. To solve this, we used distance culling to make sure any paint trails that the player could not see themselves would not be rendered and this check was made using the distance between the players and the paint trails.
Blueprint for instant meshing
Retrospectives
What went well
-
We were able to work together as a team and successfully shipped a game on steam while
-
Asked for help and more resources when I got overwhelmed with the performance work load
-
Inter-department communication was good and pipelines were followed properly
-
Our communication did not suffer when people had to work remotely due to covid and other illnesses
What went wrong
-
Got overwhelmed with work during the Alpha sprint which affected personal productivity poorly
-
We didn't prioritize our features properly which lead to compromises on other quality-of-life features
-
Working remotely lead to feeling of isolation and reduced productivity
What I learned
-
Do not be afraid of asking for help. It benefits both the project and yourself
-
Establishing pipelines early on and enforcing them allows for a smoother development process
-
Writing code that is simple and easy to modify makes it easier to add new features later on
-
Paying a big performance cost at the beginning of the level to ensure smooth gameplay for the rest of it is better than having laggy gameplay throughout the level