Dead Pedal

- Lead Programmer
- UE5
- Git
- Jenkins
- Google Cloud
Details
As Lead Programmer, I maintained an Unreal CI/CD pipeline, creating and iterating our car physics, as well as establishing the programming team's feature timeline.
The Game
In Dead Pedal you play as John D. Pedal in a post apocalyptic world fending of ruthless marauders and mutant beasts. Upgrade you car with new weapons and customizations by taking out various factions. When your ready take on THE WORM and bring peace back to the mojave.
Planned Steam release May 2023.
Timeline
Starting development in September 2022 I worked on a cross-disciplinary team of developers to create Dead Pedal for the Champlain College Game studio.
We made the decision to learn Unreal Engine 5 to utilize Chaos Physics, World Partition and leverage Unreal's rendering.
Technical Details
Google Cloud
At the beginning of the project we identified our ability to iterate as a key area of risk. To create a driving system that would be intuitive and function as players would expect we need to ensure we could test efficiently. We created the build server to drastically reduce the time and effort in creating a build.This not only saved time when putting builds together but it saved time when testing because the builds were easily accessible. Every week we knew the state of the build which built confidence in how people interacted with the build.
Overview
The build server has 5 core elements that allow for this pipeline.
- The repo(we used git)
- The Jenkins server
- Google cloud build agents
- Google cloud buckets
- Team notification
Repo
The build needs to be stored somewhere in our case it was stored in Git. However it could be upgraded to support SVN or PerforceThe build also gets cached onto the build server instance so a large repo size is not a problem.
Jenkins Server
The Jenkins server exists as the brains of this operation. It manages all the commands, artifacts and manages the build instances. This supports user authentication so you can give your team access to this to avoid any build bottlenecks. anyone with access to the jenkins server can generate a build at any time
Cloud build agents
The cloud build agents are machines with larger allocations of compute to support building the game. This is where your game will be build before the build is saved. These machines are custom images so they can support any necessary third party libraries required for compute.
Google Cloud Buckets
The builds then get saved to google cloud buckets. This gives anyone with access to the link the ability to download the game. this will reduce time to retreating your game and testing it.
Finally Team integration
This is all good but if it is not publicly available to your team it will only exist in the background. Notifying your team via discord or slack is important to automatically communicate the build status to your team
Conclusion
This approach not only will give you more confidence in your build integrity but it will allow your team to test the CURRENT version of the build much faster.This is also the starting point for more complex things like automated testing and tracking of users interaction with your game
Mission System
The Goal with the mission system was to create something that could be scaled out by the design team. Given the open world nature of our game we wanted a mission system that would not confine the player. I settled on created a C++ back end that would create a blueprint front end that could be extensible with unique behaviors.
Tutorials
In an effort to document these systems I took a visual approach as opposed to a word document. I created a series of videos that show how to set up mission blueprints and mission triggers through out the level. This allowed me to show off some of the smaller details about the system without creating a verbose document.
BP Mission
The Mission is the core of what all unique missions were built off. This allowed contained behavior that was specific to a mission type. If the goal was to drive to a location or take out key base targets that could all be defined in the mission.
/*
BP_Mission.h
*/
UFUNCTION(BlueprintCallable)
virtual void MissionComplete();
UFUNCTION(BlueprintCallable)
virtual void MissionStart();
/*
BP_Mission.cpp
*/
void ABP_Mission::MissionComplete()
{
// Flag Mission as complete
missionComplete = true;
// Callback to Mission manager
mdOnMissionComplete.Broadcast();
// Unique Mission Callback
OnMissionComplete();
}
void ABP_Mission::MissionStart()
{
// Flag Mission as not complete
missionComplete = false;
// Callback to Mission manager
mdOnMissionStart.Broadcast();
// Unique Mission Callback
OnMissionStart();
}
BP Mission Manager
The Mission Manager is responsible for keeping track of the active mission. This means keep the UI up to date and keeping track of completed missions. This allowed for common mission actions to be take care of in one place.
/*
BP_MissionManager.cpp
*/
void AMisisonManager::BindMissionToActive(
ABP_Mission* newMission)
{
// Make sure newMission is active
if (newMission == nullptr) {
UE_LOG(LogTemp,
Warning,
TEXT("Failed to bind Mission: Mission active"));
return;
}
// Set Active mission
activeMission = newMission;
// Blueprint implementable callback
activeMission->OnMissionBind((AMisisonManager*)this);
// Bind Active Mission Delegates
activeMission->mdOnMissionComplete.AddDynamic(
this, &AMisisonManager::OnMissionComplete);
activeMission->mdOnMissionStart.AddDynamic(
this, &AMisisonManager::OnMissionStart);
}
void AMisisonManager::UnbindActiveMission()
{
if (activeMission == nullptr) return; // No Mission to unbind
// Unbind Mission Delegates
activeMission->mdOnMissionComplete.RemoveDynamic(
this, &AMisisonManager::OnMissionComplete);
activeMission->mdOnMissionStart.RemoveDynamic(
this, &AMisisonManager::OnMissionStart);
// Blueprint implementable callback
activeMission->OnMissionUnbind((AMisisonManager*)this);
// Set Active Mission to null
activeMission = nullptr;
}
Access
If you are interesting in accessing this reach out to me on linkedin, via email or phone number and we can set up a meeting to go over how you might integrate this into your pipeline.