ROLE: GAMEPLAY PROGRAMMER
ROLE: GAMEPLAY PROGRAMMER
TEAM SIZE: 17
DURATION: SEPTEMBER 2025 - APRIL 2026
On this project I was tasked with creating a movement system that enabled diverse traversal through our world. This involved a dash and glide ability, speed boosts, and a boost system that controlled how speed influenced Revna. Each one of these mechanics was accompanied by documentation that was written for the team's designers. While these features were implemented into the project within the first two months, they underwent several iterations throughout the course of the project, which saw my abilities as a gameplay programmer grow.
My goal for this ability was for it to be responsive and consistent, with the same distance traveled whether the dash was activated in air or on the ground. This would give it use for traversal, as well as combat. This feature went through the most iterations out of anything else that I worked on.
Initially our playtests indicated that the dash felt floaty and inconsistent, with its usefulness decreasing the faster the player moved. I fixed this by storing the magnitude of the previous velocity before dashing, and reinstating it once the dash completed. I also converted the dash to be input based, rather than based on the direction Revna was moving. These two elements combined allowed for the magnitude of the pre-dash velocity to be applied in the direction of the dash.
The glide was meant to be used in tandem with the dash, to cross large gaps, rise above combat to set up devastating aerial attacks, and break up the movement sandbox. While implementing a natural feeling glide was simple at first, the challenge came from preventing players from boundary breaking by flying away without totally nullifying the fun of a gliding mechanic.
To solve this issue, I implemented a glide drop off feature. This was a timeline that gradually lerped the gravity scale and air control of the player to a more reasonable value. The designers could control how long it would take for the drop off to complete, a float curve that allowed for non-linear progression, and what values were desired at drop off completion (for example, halfway between gliding values and default in-air values).
The speed boosts were used to unlock the players maximum movement speed, allowing for engaging, fast-paced traversal. There were two types of speed boosts used in the game, a normal version that allowed Revna to run faster, and a directional version that launched her into whatever direction it was facing.
When picking up a speed boost, Revna’s max walk speed increased by an amount desired by the designers and would last for an easily adjustable duration. If the player managed to pick up another speed boost before the time was up, they’d get an extra boost and the timer would reset. This system allowed players to chain together dashes and glides to maintain high speeds (up to an adjustable cap). To sell this effect, and indicate to the player that they were boosting, I increased the field of view and moved the camera closer into Revna, based on how fast they could go.
The rune puzzles were a mechanic that encouraged the player to explore their surroundings. This was done by showing them their next required path alongside inactive puzzle stones. The player would seek out runes that, upon collecting, would spawn a trail of particles guiding them through the level. When all runes were collected, a message was sent out to all connected objects listening for the puzzle complete state. In creating this mechanic, I collaborated heavily across disciplines. I took inspiration from a prototype created by one of the designers, and had to add a designer/artist friendly selector for use of the correct rune assets.
I knew from the beginning that I wanted there to be an arbitrary amount of runes per puzzle. This meant that I needed to keep the runes themselves as simple as possible, with no dependency on the other runes existing in the scene. The only thing one rune needed to know was its destination, and its manager object. Upon being collected, it would fire off a timeline component that sent particles along a spline to its destination. When the timeline finished, it called the activation function on its destination, and notified its owner that it had completed, and should check the completion state of the puzzle.
Getting it working under the hood was only half the work, I needed to expose the necessary variables to the artists and designers without over complicating things. Each placed rune had a spline attached, as well as a travel duration, to indicate how long it would take for the particles to travel along it. While the intended effect is for the spline to be drawn into its destination object, the logic does not depend on the particles reaching the destination, so any path is valid as it would still call the destination’s activation function upon reaching the end of the spline.
As art assets came in and could replace my temporary white cubes, I crafted a simple way to select the desired rune. The runes were particle effects created by our VFX artist that each had their own idle and active state, as well as a trail for the particles travelling along the spline. I added a drop down in the details panel of the rune object that allowed the user to select which rune type this one should be. Once selected, the rune assigns all of its necessary assets when it’s loaded in.
The manager object was only visible in the editor and was used to handle the completion logic of the puzzle. Upon starting, the manager searches for and stores all runes in the scene that have that manager selected as their owner. When a rune is activated, it checks the overall state of the puzzle to see if it is complete.
The only value to set in the editor for this manager was an array of actors that would listen for the puzzle complete message. By using Unreal Engine’s Blueprint Interfaces, I was able to implement this system seamlessly. As it was set up, any number of actors could be hooked up to the completion states. For example, completing a puzzle could just open a door, or it could spawn enemies, play music, and spawn cool visual effects, all with an arbitrary amount of runes.