<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://taylorhetherington.dev//feed.xml" rel="self" type="application/atom+xml" /><link href="https://taylorhetherington.dev//" rel="alternate" type="text/html" /><updated>2026-07-13T11:39:43+00:00</updated><id>https://taylorhetherington.dev//feed.xml</id><title type="html">Taylor Hetherington</title><subtitle>Gameplay &amp; UI Programmer</subtitle><entry><title type="html">They Came From the Woods</title><link href="https://taylorhetherington.dev//personal-projects/they-came-from-the-woods" rel="alternate" type="text/html" title="They Came From the Woods" /><published>2026-07-11T00:00:00+00:00</published><updated>2026-07-11T00:00:00+00:00</updated><id>https://taylorhetherington.dev//personal-projects/PersonalProject-TheyCameFromTheWoods</id><content type="html" xml:base="https://taylorhetherington.dev//personal-projects/they-came-from-the-woods"><![CDATA[<h1 id="they-came-from-the-woods">They Came From the Woods</h1>

<p><a href="/assets/playables/TheyCameFromTheWoods/index.html" target="_blank">Play here</a></p>]]></content><author><name></name></author><category term="personal-projects" /><category term="Unity" /><category term="C#" /><summary type="html"><![CDATA[They Came From the Woods]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://taylorhetherington.dev//assets/images/PersonalProjects/TheyCameFromTheWoods/TheyCameFromTheWoods.png" /><media:content medium="image" url="https://taylorhetherington.dev//assets/images/PersonalProjects/TheyCameFromTheWoods/TheyCameFromTheWoods.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">DeathSprint 66</title><link href="https://taylorhetherington.dev//games/DeathSprint-66" rel="alternate" type="text/html" title="DeathSprint 66" /><published>2026-07-07T00:00:00+00:00</published><updated>2026-07-07T00:00:00+00:00</updated><id>https://taylorhetherington.dev//games/DeathSprint-66</id><content type="html" xml:base="https://taylorhetherington.dev//games/DeathSprint-66"><![CDATA[<h2>Overview</h2>

<p>From 2022-2024 I worked on <strong><a href="https://store.steampowered.com/app/1273560/DeathSprint_66/" target="_blank">DeathSprint 66</a></strong>.</p>

<p>I was on this project from early prototyping all the way until release and post-launch.
<br />In my role I took on <strong>Gameplay</strong> and <strong>UI</strong> code.</p>

<p>Primarily I was responsible for implementing the <strong>in-game HUD</strong>.<br />
Some of my other responsibilites included:</p>
<ul>
  <li><strong>Emoji</strong> System</li>
  <li><strong>Cosmetics</strong> implementation</li>
  <li>Creating the <strong>Momentum System</strong></li>
  <li>Various character ability work (<strong>GAS</strong>)</li>
  <li><strong>Animation</strong> and <strong>VFX</strong> implementation</li>
  <li><strong>Optimization</strong> work</li>
</ul>

<hr />

<h2 id="features">Features</h2>
<p>Here’s a closer look at some of the features mentioned above.</p>

<h3 id="in-game-hud">In-Game HUD</h3>
<p>I created various widgets for the HUD, using various techniques to achieve some cool effects. 
The entire HUD was completely <strong>event-driven</strong> except for where it made sense otherwise (race timer, for example).</p>

<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_HUD.png" width="900px" alt="" />
        </div>
        <figcaption>DeathSprint 66 In-Game HUD</figcaption>
        </div>
    </div>
</figure>

<p>On the image above you can see the following elements I created:</p>
<ul>
  <li>Lap Number and Time tracker</li>
  <li>Leaderboard</li>
  <li>Killfeed</li>
  <li>Lives Counter</li>
  <li>Ability Container</li>
  <li>Surge Bar</li>
  <li>Emoji Feed</li>
  <li>Name Tags</li>
</ul>

<p>Below I’ll explain a little more about some of the more complicated
<br />
<br /></p>
<h3 class="green">Emojis</h3>
<p>DeathSprint 66 is canonically a game show, and to sell that effect we wanted to have emojis that burst from the bottom of the screen that respond to your characters in-game actions, to mimick viewers watching at home.
Originally, we had a small number of emoji widgets that’d burst onto the screen, which was slow and costly. Using a widget pool didn’t help too much either, since the bulk of the cost was the overhead of the widgets themselves, so in the end I decided to use an <strong>SMeshWidget</strong>.<br />
This essentially allowed me to instance widgets and draw all emojis in a <strong>single drawcall</strong>, meaning instead of a handfull of slow emojis on screen, we could have had thousands, and they were lightning quick too!</p>

<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_Emojis.gif" width="500px" alt="" />
        </div>
        <figcaption>Emojis</figcaption>
        </div>
    </div>
</figure>

<h3 class="green">Ability Container</h3>
<p>The ability container was really fun to implement, it’s a 3d coin-flip animation that travels up the screen, fading away to reveal the ability you have randomly received!
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_Coin.gif" width="300px" alt="" />
        </div>
        <figcaption>Coin flip animation</figcaption>
        </div>
    </div>
</figure>
<p><br />
<br /></p>
<h3 class="green">Surge Bar</h3>
<p>The surge bar is all material based, I worked on it together with a really talented Tech Artist, it consists of three separate bars that fill up, and turn a different colour upon filling up, all on a radial meter.
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_SurgeMeter.gif" width="500px" alt="" />
        </div>
        <figcaption>Radial Surge Meter</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h3 id="cosmetics">Cosmetics</h3>
<p>I was also one of a few programmers who worked on cosmetics implementation, mainly responsible for reading the data given to us from backend. The indexes for skins, emoji packs, and banners would be sent from the server and I created the system that read that data and displayed the correct cosmetic.
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_Cosmetics.png" width="900px" alt="" />
        </div>
        <figcaption>Cosmetics menu (I did not make the menu itself)</figcaption>
        </div>
    </div>
</figure>
<p><br />
<br /></p>
<h3 id="character-controller-work">Character Controller Work</h3>
<h3 class="green"> Momentum System </h3>
<p>We faced a problem with our racing game in that the characters all ran at the same speed, meaning you could only overtake someone if they messed up and died. To remedy this, I came up with a system where doing well at the game (chaining up wallruns, ziplines, drifting, etc.) would allow you to build ‘momentum’. <br /> Your momentum score was then used to increase your maximum speed, allowing you to travel faster. This ended up working really well as it created a sense of ‘flow-state’ to the player.
<br /><br />
One thing I’m really proud of is the way I set this system up. 
<br />It allowed designers to:</p>
<ul>
  <li>Define which game actions increased momentum</li>
  <li>How long it’d add momentum for (instant or continuous)</li>
  <li>How the momentum would be added (instantly, linearly, custom curves)</li>
  <li>How much momentum would be added</li>
  <li>How long the momentum takes to decay</li>
  <li>How the momentum decays (instantly, linearly, custom curve)</li>
</ul>

<p>They could do all of this <strong>without <em>any</em> code support</strong>.</p>

<p>The system itself managed your momentum modifiers, calculated your momentum score, and then calcualted your new max speed based on a Momentum -&gt; Max Speed curve, injecting the new max speed into the movement code.
<br />
<br /></p>
<h3 class="green"> Character Abilities </h3>
<p>Towards the beginning of production I also helped in setting up and learning about the <strong>Gameplay Ability System</strong> which was new to us at the time. Using it, I implemented a few character abilities, some of which are still in the game (although they were built upon by another programmer after me!)
<br />
<br /></p>
<h3 class="green"> Leaning </h3>
<p>Whilst on ziplines and grindrails the character can lean to either side to dodge traps. <br /> I worked together with <strong>Animation</strong> to achieve this effect using <strong>blend-spaces</strong>. 
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/DeathSprint/DeathSprint_Leaning.png" width="900px" alt="" />
        </div>
        <figcaption>Leaning left and right</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h3 class="green"> Animation Masking </h3>
<p>The character can be hit with other players’ abilities, one ability causes the player to grab their head with both hands. Obviously, while the player is ziplining or wallrunning, one of their hands is preoccupied, so I looked into <strong>Skeletal Animation Masking</strong>. This allowed us to mask off part of the animation if the hands were pre-occupied, meaning their hand on the wall or zipline would stay there, and only the other hand would play the animation.
<br />
<br /></p>
<h2 id="misc-work">Misc Work</h2>
<h3 class="green">ImGui</h3>
<p>I added ImGui into our custom version of Unreal Engine, and used it to make some nice debug tools for DeathSprint, including a graph which showed speed over time and momentum over time. 
<br />
<br /></p>
<h3 class="green">Optimization Work</h3>
<p>Part of implementing the UI was making sure the UI was performant. I used an array of techniques to diagnose and optimize the HUD, such as:</p>
<ul>
  <li>Only invalidating widgets when necessary, and avoiding widget setups that frequently invalidate widgets</li>
  <li>Used phased <strong>retention boxes</strong> to load-balance the UI</li>
  <li>Lots of <strong>widget pooling</strong></li>
  <li>Converting Emoji system into an <strong>SMeshWidget</strong></li>
  <li>Ensuring all HUD elements were <strong>event-driven</strong></li>
</ul>

<p><br />
Through this I managed to get the entire HUD under 1ms/tick, even under worst-case scenario.<br />
<br /></p>
<hr />

<p><br /></p>
<div class="steam-embed">
    <iframe src="https://store.steampowered.com/widget/1273560/" frameborder="0" width="646" height="190"></iframe>
</div>]]></content><author><name></name></author><category term="games" /><category term="UE5" /><category term="UI" /><category term="Gameplay" /><summary type="html"><![CDATA[Overview]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://taylorhetherington.dev//assets/images/DeathSprint-66.png" /><media:content medium="image" url="https://taylorhetherington.dev//assets/images/DeathSprint-66.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Enginefall</title><link href="https://taylorhetherington.dev//games/Enginefall" rel="alternate" type="text/html" title="Enginefall" /><published>2026-07-07T00:00:00+00:00</published><updated>2026-07-07T00:00:00+00:00</updated><id>https://taylorhetherington.dev//games/Enginefall</id><content type="html" xml:base="https://taylorhetherington.dev//games/Enginefall"><![CDATA[<h2>Overview</h2>

<p>For around 2 years, I have been working on <strong><a href="https://store.steampowered.com/app/2437390/Enginefall/" target="_blank">Enginefall</a></strong>.</p>

<p>I have taken on a number of roles, such as <strong>Gameplay Programmer</strong>, <strong>UI Programmer</strong>, and <strong>Strike Team Lead</strong>.</p>

<p>Here are some of my responsibilities:</p>
<ul>
  <li>Lead the <strong>Social Gameplay</strong> and <strong>PvP</strong> strike teams
    <ul>
      <li>Organized meetings, drove team initiatives</li>
      <li>Owned, Concepted, Designed, Proposed, Implemented, and Maintained several features</li>
    </ul>
  </li>
  <li><strong>Gunplay</strong> and <strong>Combat</strong> code
    <ul>
      <li>Recoil System</li>
      <li>Recoil Spray Patterns</li>
      <li>Interruptible Shotgun Reloads</li>
      <li>Riot Shields</li>
      <li>TRACE System</li>
    </ul>
  </li>
  <li><strong>Ladders</strong> (harder than it sounds!)</li>
  <li>UI Work
    <ul>
      <li>World-to-Screen transforms for grenade and waypoint indicators</li>
      <li>Inventory System &amp; slots work</li>
    </ul>
  </li>
  <li>Tools
    <ul>
      <li>I’ve also worked on several tools, including a recoil visualization tool</li>
    </ul>
  </li>
</ul>

<hr />

<h2>Features</h2>

<p>I got to work on lots of really cool stuff on Enginefall, here’s a more in-depth look at some of the highlights.
<br /><br /></p>
<h2 class="green">Combat and PvP</h2>

<h3 class="green">Recoil System</h3>

<p>The recoil system was set up to be <strong>physically realistic</strong> (as reasonably possible), the chief inspiration for the system was Counter-Strike 2.
<br /><br />
The recoil system involved a few moving parts:</p>
<ul>
  <li>Simulating the force a bullet imparts on a player, and moving the crosshair accordingly</li>
  <li>Returning the crosshair back to center once the player stops firing (using some fancy spring equations)</li>
  <li>Measuring the mouse movement of the player whilst firing, and offseting the recovery value</li>
  <li>Random variance per shot, dictated using GAS Attributes</li>
</ul>

<p>These elements together created a system where a designer could assign <strong>per-bullet forces</strong> on the weapon, allowing them to create <strong>spray patterns</strong>. Then when a player fires, the recoil is simulated accurately, and once they stop firing the character recovers from the recoil. The player themselves could also try to offset the recovery and become more accurate.<br />
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <div class="image-container">
            <image src="/assets/images/Enginefall_Screenshots/RecoilPatterns.png" width="900px" alt="" />
        </div>
        <figcaption>Spray Patterns of various Rifles.</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h3 class="green">Recoil Visualization Tool</h3>
<p>The recoil system was set up to be very flexible, but as a result of this flexibility, it now took quite a long time to create and tweak patterns. 
Every time a designer wants to change a spray pattern, they’d have to open the weapon, go to the bullets, change the forces, load the game up, get a weapon, and finally fire it against a wall. Each iteration could take several minutes, which is obviously too slow.
<br />
To remedy this I created the Recoil Visualization Tool. 
<br /><br />
This tool did a few things:</p>
<ul>
  <li>Allowed you to select a weapon</li>
  <li>Displayed the spray pattern for that weapon</li>
  <li>Updated in <strong>real-time</strong> as you edited the weapon bullet array</li>
  <li>Allowed you to scrub through the pattern per-bullet</li>
  <li>Display the old pattern as reference</li>
  <li>Adjust the recoil system variables to see the effects it has on the pattern</li>
</ul>

<p><br />
It did all of this in <strong>Editor time</strong>, meaning you didn’t even have to launch the game to iterate on spray patterns!
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <image src="/assets/images/Enginefall_Screenshots/RecoilVisualizer.png" width="900px" alt="" />
        <figcaption>Recoil Visualization Tool.</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h3 class="green">Interruptible Shotgun Reloads</h3>
<p>This was mostly <strong>animation work</strong>, helping to set up the animations so the sections run in the correct order, loop appropriately, and then transition out of it smoothly afterwards. The system also needed to support animation cancelling, which was allowing the player to shoot before the gun was fully reloaded.</p>

<p>The animation work I did here was also used on other weapon reloads to allow anim cancelling, and for looping animations for consumable items.</p>

<p><br /></p>
<h3 class="green">Riot Shields</h3>
<p>Implementing the Riot Shield involved allowing items to use their parent’s Ability System Component for Combat logic, but use their own attributes for tracking health. This work also involved setting up <strong>Gameplay Cues</strong> for audio.
<br /></p>
<figure>
    <div class="embed-image">
        <div>
        <image src="/assets/images/Enginefall_Screenshots/RiotShield.png" width="900px" alt="" />
        <figcaption>Riot Shield in action.</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h3 class="green">TRACE System</h3>
<p>This is a system I owned, designed, and implemented, that aimed to solve “toxic PvP”. The idea is that the more you kill people, the more difficult the game becomes. We did this by giving each player a trace score. When a threshold was passed, the game would introduce a challenge, such as revealing your location briefly when you kill someone. At extreme levels, the TRACE System would send NPC Guards to hunt you down (though I did not implement the bots).</p>

<p>The thresholds for TRACE were fully customisable and very flexible, they could be changed per-carriage, per-train, or for the whole game. This also came with some <strong>UI work</strong>, <strong>audio work</strong>, and some <strong>tech art implementation</strong> for player outlines. I also created a range of <strong>cheats</strong> and <strong>debug information</strong> for this system, allowing QA to test very easily.
<br />
<br /></p>
<h2 class="green">Ladders</h2>
<p>I was responsible for implementing ladders, and spent a while iterating and making them feel smooth. They needed to support the player moving up and down, restrict lateral movement somewhat to prevent falling off, traverse facing the ladder or facing away. <br />They needed to dismount and mount smoothly, catch the player at the top, but don’t catch the player too well otherwise they’d get sucked in accidentally. 
They also needed to support curved and kinked ladders.
And finally, they needed to have a satisfying jump-off and re-attach, to allow jumping between ladders.</p>

<p>All of this was difficult to do, but the end product felt amazing (or at least I thought so, others probably thought “they’re just ladders, what’s the big deal?”)</p>
<figure>
    <div class="embed-image">
        <div>
        <image src="/assets/images/Enginefall_Screenshots/Ladders.png" width="900px" alt="" />
        <figcaption>All types of ladders available in Enginefall.</figcaption>
        </div>
    </div>
</figure>
<p><br />
<br /></p>
<h2 class="green">Inventory Work</h2>
<h3 class="green">Coverage System</h3>
<p>Enginefall had lots of clothing items, and Art asked for a system that allowed for interactions between these clothing items.</p>

<p>I created a system that detected when clothes were covering each other and then would allow artists to select from some default behaviour, or create custom behaviour per-item.</p>

<p>For common operations, I implemented a solution where we could create generic blueprints to apply operations to clothing items, the system allowed multiple effects to be chained up. This meant the system was very flexible, allowing us to create effects like hiding items, swapping out meshes, applying VFX, and more!
<br />
<br /></p>
<h3 class="green">Filtered Slots</h3>
<p>The filtered slots system allowed us to enforce item-types per slot. We wanted a clothing column and a utility column, but both had to point to the same inventory component, so as not to create extra work for the coverage system detailed above. In the end this was a pretty simple change, but I was happy with it nonetheless.</p>

<figure>
    <div class="embed-image">
        <div>
        <image src="/assets/images/Enginefall_Screenshots/Filtered_Slots.png" width="500px" alt="" />
        <figcaption>Filtered Slots in the Player's inventory.</figcaption>
        </div>
    </div>
</figure>
<p><br /></p>
<h2 class="green">Misc UI Work</h2>
<h3 class="green">Object Tracking</h3>
<p>The objective of this task was simple, convert world object locations into screen space, add a waypoint above them, and clamp them to the screen in an oval shape.</p>

<p>The task involved doing some pretty funky maths to manipulate world objects into screen space, since the default <code class="language-plaintext highlighter-rouge">ProjectWorldLocationToWidgetPosition</code> can fail, if the object is directly behind the player. After getting it in screen space, it was as simple as clamping to various shapes to prevent it going off the screen, or beyond the radius we set.</p>

<figure>
    <div class="embed-image">
        <div>
        <image src="/assets/images/Enginefall_Screenshots/Waypoints.png" width="1200px" alt="" />
        <figcaption>Various waypoints clamped to an oval shape, with distance marker and conditional arrows.</figcaption>
        </div>
    </div>
</figure>
<p><br />
This was just a condensed list of all the awesome stuff I got to do on Enginefall, but hopefully it provided some insight into my role in bringing this title to life.
<br />
<br /></p>
<hr />

<p><br /></p>
<div class="steam-embed">
    <iframe src="https://store.steampowered.com/widget/2437390/" frameborder="0" width="646" height="190"></iframe>
</div>]]></content><author><name></name></author><category term="games" /><category term="UE5" /><category term="C++" /><category term="UI" /><category term="Gameplay" /><category term="Leadership" /><summary type="html"><![CDATA[Overview]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://taylorhetherington.dev//assets/images/Enginefall.jpg" /><media:content medium="image" url="https://taylorhetherington.dev//assets/images/Enginefall.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>