Jetpack FPS (2026)

Duration: October 2025 - Present

Type: Personal Project

Role: Gameplay Programmer

Engine and Tools: Unreal Engine 5, C++ & Blueprints

What is Jetpack FPS?

Jetpack FPS is a self-directed personal project built in Unreal Engine 5 using C++ and Blueprints. Inspired by the fast, expressive movement systems in games like Black Ops 3, the goal was to engineer a prototype that captures the feeling of fluid, momentum-based traversal - where every movement state flows naturally into the next.

This is a movement-focused prototype - no enemies, no objectives. The entire scope of the project is dedicated to getting traversal right: how it feels to sprint, slide, wallrun, and jetpack through a space. Movement is the soul of an FPS, and this project is built around proving that.

Mechanics and Gameplay

Combact Loop
Mechanics & Gameplay - Walkthrough (Player States)
Chained WallRuns - Airborne State
Physics-Based Slide and Ledge Slide

Summary of Contributions

Multi-State Locomotion Architecture: Designed a modular state machine with 8 locomotion states - Walk, Sprint, Crouch, Slide, WallRun, Jetpack, Prone, and Airborne. Each state transition is centralized through a single SetMovementState function with an OnMovementStateChange callback, handling side effects like capsule resizing, gravity scaling, and jump count resets. Conflict resolution logic prevents overlapping systems from fighting each other - for example, ADS cancelling auto-sprint, or jetpack cancelling an active ledge slide.

SetMovementState Function
SetMovementState Function
ResolveMovementState Function
ResolveMovementState Function
GAIT Locomotion Mapping
GAIT Locomotion Mapping

Analog Jetpack System: Implemented a curve-driven jetpack where thrust intensity ramps up based on how long the player holds the input - using a CurveFloat sampled from HoldAlpha (HoldDuration / MaxHoldDuration). Fuel drain is scaled per tick by thrust intensity so short taps consume almost nothing while sustained holds drain quickly. Timer-based update loops (rather than per-frame Tick) ensure the fuel behavior is frame-rate independent. Identified and resolved a synchronization bug where micro-tap thrust applied before the first drain tick, causing fuel to never decrement on short presses.

EventTick - Hold Duration & Thrust Curve
EventTick - Hold Duration and Thrust Curve
JetPackThrust - Root Motion Force
JetPackThrust - Root Motion Force
JetPacking Input & Jump Count
JetPacking Input and Jump Count

Custom C++ Async Root Motion Plugin: Extended a Blueprint async action plugin in C++ to wrap Unreal's FRootMotionSource_ConstantForce, exposing cancellable curve-driven movement forces to Blueprint workflows with OnComplete and OnFail delegates. This replaced LaunchCharacter impulse calls - which felt snappy and disconnected - with forces that build, sustain, and bleed off naturally, giving the jetpack and slide a momentum-based feel. The plugin stores a RootMotionSourceID for clean lifecycle management and cancellation.

Physics-Based Slide & Ledge Slide
Physics-Based Slide and Ledge Slide
Crouch & Buffered Slide Logic
Crouch and Buffered Slide Logic
Async Root Motion Constructor
Async Root Motion Constructor code
Activate() - Apply Constant Force
Activate function applying constant root motion force
Cancel() - Cleanup Root Motion
Cancel function cleaning up root motion source

FPS Animation Integration: Integrated an FPS animation pack into a third-person character Blueprint using interface-driven component access - decoupling the character from the animation components (CameraAnimator, ViewmodelController, GAIT locomotion) through Blueprint interfaces. This enables seamless first-person viewmodel transitions across all locomotion states with layered ADS, recoil, FOV, and camera tilt effects without the character Blueprint needing direct references to animation components.

WallRun Entry - Surface Detection
WallRun Entry - Surface Detection
WallRun - Plane Constraint & Camera Tilt
WallRun - Plane Constraint and Camera Tilt

UE4 to UE5 Migration: Migrated the Unreal Engine 4 ShooterGame template to Unreal Engine 5.5 via C++, resolving numerous deprecated API breakages and updating the codebase to use modern UE5 conventions. Enabled Lumen Global Illumination, Virtual Shadow Maps, Nanite, and Temporal Super Resolution - repurposing the HighRise level from the template as the playable demo environment for this project.

Process

The project started with a simple question: what makes FPS movement feel good? I began by building the state machine foundation - getting clean transitions between basic locomotion states before adding complexity. The jetpack system went through multiple iterations: starting with AddForce calls, moving to LaunchCharacter, and finally landing on root motion sources after identifying that impulse-based approaches couldn't produce the sustained, controllable feel I was after. The C++ plugin was written to solve a specific problem - Blueprint had no clean way to apply a cancellable, duration-based force with completion callbacks. Debugging the timer synchronization bug in the fuel system was a key learning moment: matching the drain timer interval to the thrust timer interval (both at 0.02s) fixed a subtle edge case where micro-taps never triggered a drain tick. The UE5 migration came later, once the core systems were stable, and unlocked the Lumen lighting and Nanite geometry that give the demo its final visual quality.

Reflection

Building this prototype taught me more about game feel engineering than any course I've taken. The gap between 'technically correct' and 'feels right' is enormous - and closing that gap requires iterating on things that are hard to quantify: does the jetpack feel weighty enough? Does the slide feel committed without feeling punishing? Working at both the Blueprint and C++ level in the same project gave me a much clearer picture of when each layer is the right tool. The C++ plugin in particular was a step outside my comfort zone and one of the most valuable things I built - it forced me to understand Unreal's movement architecture at a deeper level than Blueprints alone would allow.