Dead Pedal

thumbnail
  • Lead Programmer
  • UE5
  • Git
  • Jenkins
  • Google Cloud

Details

As Lead Programmer, I maintained an Unreal CI/CD pipeline, iterated on our car physics, and established the feature timeline for the programming team.

The Game

In Dead Pedal, you play as John D. Pedal in a post-apocalyptic world, fending off ruthless marauders and mutant beasts. Upgrade your car with new weapons and customizations by taking out various factions. When you’re ready, take on THE WORM and bring peace back to the Mojave.

Planned Steam release: May 2023.

Timeline

Development began in September 2022. I worked with a cross-disciplinary team to create Dead Pedal for the Champlain College Game Studio. We chose Unreal Engine 5 to take advantage of Chaos Physics, World Partition, and its rendering pipeline.

Technical Details

Google Cloud

We identified build iteration speed as a risk. To mitigate this, we created a CI/CD build server that made builds more accessible and consistent. This ensured the team had confidence in the current state of the game every week.

Overview

The pipeline consisted of:

  • Git repository
  • Jenkins server
  • Google Cloud build agents
  • Google Cloud buckets
  • Team notifications via Discord

Jenkins Server

The Jenkins server managed builds, authentication, and artifacts. Anyone on the team could trigger a build, removing bottlenecks.

Build Agents & Buckets

Builds were processed by Google Cloud VMs and uploaded to Cloud Buckets for quick access. The team received notifications once a build was ready.

Conclusion

This build system improved confidence and iteration speed and opened the door for future automation like playtesting and analytics.

Mission System

We designed a scalable, modular mission system using C++ and Blueprint. It allowed designers to create open-world missions without heavy technical support.

Tutorials

I created video walkthroughs to document the setup of mission blueprints and triggers:

Blueprint Mission

Each mission was a Blueprint class inheriting from a common C++ base. Behavior could be overridden for different mission types.

/* 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(); }

Mission Manager

Managed active missions, UI updates, and completion logic.

/* 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’re interested in using or learning more about these tools, reach out: