Physics graduate turned aspiring game programmer with a strong background in C++ and experience in gameplay and systems programming.
On leaving university, I set my sights on a career in the games industry.
I'm looking forward to creating innovative gameplay experiences, bringing insights from a lifetime of playing and thinking about games across various genres.
This portfolio contains a selection of game-focused projects.
For the best showcase of my C++ ability and an optimisation focused project, see
For some quicker to view content, see the VIDEO DEMOS tab in the nav bar.
And for the most novel and interesting project, see all Slay the Spire work, particularly
Multi-Threaded Game Engine (C++)
A multi-threaded game engine implemented in C++ using SFML, applied to an extended version of Asteroids with a novel visibility mechanic.
The goal of the project was to build out complex game engine systems and to practise extensive profiling and optimisation.
- Concurrent programming: a custom job system, use of mutexes, atomics, lock-free data structures, wait-free systems
- Rendering & Shaders: line-traced occluded glow, texture atlasing, batching draw calls, particle system
- Collision: intersection testing using GJK, spatial partitioning, support for various collider shapes
- Code optimisation: SIMD, cache-aware programming, memory optimisation and much more
- Scalable systems: Component-based architecture and a lock-free object pool with dynamic management
Slay the Spire - Recreation (C++)
A faithful recreation of the popular roguelike deckbuilder game, implemented in C++ with a focus on OOP and design patterns.
The video shows a fully playable version of Ironclad, the first class, and includes all cards, relics, potions and acts in the game for a complete experience in a text-based format.
View Full ProjectSlay the Spire - Machine Learning (C++ & Python)
A Reinforcement Learning project to build an AI capable of autonomously playing and beating Slay the Spire.
The game was successfully beaten with a combination of 3 different models, each focusing on different macro and micro areas of decision-making, which were carefully interwoven.
View Full ProjectKey features demonstrated in the video:
- Niagara particle system using scene depth and edge detection to outline geometry, creating a distinct visual style (and early versions of this - not finalised).
- Dynamic, freezable Niagara rain system enhancing atmosphere.
- Immersive MetaSounds implementation for spatialised audio, including context-sensitive effects (e.g. rain sound changing near open/closed windows).
- Environment colour shifts to red as time progresses, followed by a rewind of the player's path and transition to the frozen scene.
Obra Dinn-Inspired Prototype (Unreal Engine, WIP, Current Project)
In Return of the Obra Dinn, the goal is to complete a journal, logging the identities and causes of death for each crew member on a ship - the Obra Dinn. You do this by reliving scenes in the past: a black screen audio-only sequence leading up to a frozen-in-time 3D environment to investigate for clues. This prototype explores a twist on the idea. It allows the player to navigate a low-detail environment during the audio phase, discovering spatialised sound clues to add a new avenue for piecing together the events.
The video shows the progress so far and the setting for future work. The level will revolve around a heist gone wrong, a team of 4, split two upstairs, two downstairs:
- Frozen Scene: Explosion in the middle of the lower room, blasting the two robbers, police barging in the main door. Upstairs, one dead next to grate, one leaping out of smashed window.
- Audio Sequence: Various dialogue - hostages muttering, muffled police voices, two downstairs guys about to turn on each other. Upstairs two allude to betrayal, metal sounds, command issued, then gunshot, window smash, door smashes open downstairs, explosion.
- Payoff: Trace the path of a grenade tumbling through a vent, connecting upper and lower floors, only audible in close proximity. Spatialised audio is used as a core mechanic for solving the scene and the source of the explosion.
Slay the Spire - Custom Class (C++)
A fully designed and balanced custom class for Slay the Spire: two new major mechanics with relics, potions and a complete card pool. Sample cards are shown, where (text in brackets denotes the upgraded effects).
View Full Class









Seamless Split-Screen Demo (Unity, C#)
Implemented a feature to allow a seamless transition between a joint screen and split-screen as the players move apart.
The colour of the separating beam tends to purple when the ships are close, and red/blue as they veer further apart, to help the players gauge distance.
Occlusion Culling Tool (Unity, C#)
Editor tool to bake occlusion data by assigning unique colours to each static occluder. Allows for fast runtime culling of occluded objects (as well as frustum culling). See images for the step-by-step method.
Additional Features:
Cell Exclusion:
Options to exclude cells which are beneath the floor (looking up at a back-facing triangle) or more than a given height above an occluder.
Downsampling:
Highly detailed bake converted to a lower resolution volume, reduces memory requirement for runtime occlusion data. Example: For each 3x3x3 of baked volume, output a single cell in which you render objects seen in any of those 27 cells.
Merging:
After baking, can look at either orthogonally adjacent cells or orthogonally and diagonally adjacent cells for visible occluders. Each cell adds the visible occluders of nearby cells to its own list.
Note: Downsampling and merging are similar but noticeably different: Downsampling aims to reduce the size of the data required at runtime, while merging aims to smooth the transition between cells as the camera moves and avoid pop-in.
Transparent Renderers:
This is possible in a single pass but with two constraints: a limit to the number of transparent renderers in the scene and a limit to the number you can see through in sequence. The requirement is that given a blended pixel in your texture, you can extract from its RGBA the 2, 3, 4... unique colours which were blended to create it.
There is a rabbit hole of looking at altered Sidon Sequences for pair-sums, triplet-sums and so on, where you arrange your colours to be taken from these sets. This approach works but does not seem like a good solution. The only viable other option is to do a new pass of cubemaps for each transparent renderer and make it opaque. (View some of the compute shader work).
Bake time was reduced from >100 ms/cell to 3 ms/cell through careful assignment of colours and handling of data, streamlining and fine-tuning the rendering process and optimising the compute shader work.
Test scene with static occluders.
Each object's material is stored and a new material with a unique colour is assigned to all objects. (Allows for GPU instancing)
The yellow wire frame shows the occlusion volume. The blue filled cell is occupied by the camera. Each cell is either green (valid) or red (invalid). Red cells will not be sampled. Each cell has a small sphere at its centred to aid visibility in the editor and shows the location where each cubemap will be rendered from.
By converting each cell's cubemap to a 2D render texture and processing using compute shaders, you can extract all visible colours and hence renderers from each cell.
Frustum culling is ignored to focus on occlusion culling. Each object's original material is also reassigned.
Colours changed for easier visibility, objects which are culled are shown by their wire frame instead.
Persective closer to the camera. The baked data is stored in an asset and loaded by the camera at runtime for lookup with low overhead.
Retro Games in a Day (C++)
A series of arcade/retro games created using a custom 2D pixel engine. Each project was completed in a single day to practice working under time constraints.
Including: Tetris, Retro Racer, Asteroids, 2D Platformer, Breakout & Minesweeper.
At the end is a rendered 3D landscape from an extended version of the same pixel engine including uni-directional lighting.
Procedural Terrain Generation (Unreal Engine, C++)
A tool which uses Perlin noise to procedurally generate terrain and vary texture based on height using a tile-based system.
A wide range of configurations are possible:
- Adjustments to major and minor noise for the terrain elevation
- Tile number and size
- Terrain textures
- Heights and band size for texture blending in terrain material
Top-Down Action Demo (Unity, C#)
Ability-driven combat where enemy AI is controlled by a Behaviour Tree, uses object pools for Bullet Hell elements and Unity's particle effects for most abilities. A prototype level for the following concept:
- Start with an abundance of abilities, at each stage sacrifice one and upgrade another.
- As the game progresses, the result is a very literal increase in depth and decrease in breadth, allowing players to discard abilities they don't enjoy, and fully engage with and master the ones they do.
- Upgrades could be a traditional upgrade tree for each ability or maybe something more Transistor-like, and the sacrificed ability determines the nature of the upgrade (some sort of infusion).
- This demo shows a version of this concept. Here you are given three cards and asked to sacrifice one and then upgrade one to its A or B variant.
- This repeats twice more such that with 10 starting abilities, you then have 7 total, 3 of which are upgraded, in preparation for a 3-phase fight.
- Each ability is designed to incorporate some kind of movement/damage mitigation mechanic to avoid something like a dash becoming a crutch.
Old Projects (Unreal Engine)
An end of Uni project to make Monopoly in C++ (not UE).
Older projects made in Unreal Engine using Blueprints including:
- A simple block puzzle memory game.
- A card game template for Magic: The Gathering. Allows playing and organising lands, tapping for mana and undoing, searching the library for certain cards and moving cards around in hand.
- A 3rd Person Shooter, implementing simple wall-running, AoE effects, weapon switching, AI targeting (which I have no footage for).

Game Analyses & Critiques
I may or may not add some critiques and analyses that I've written about various games into this section. They are currently far too long for a portfolio but include:
- Elden Ring: My favourite game - A focus on boss design (combo extenders, delayed attacks, the player's learning experience) and the stellar exploration sequences. Also discussion about bloat, enemy/boss repetition and where I disagree with some common criticism.
- Elden Ring: Shadow of the Erdtree: A discussion on the challenge of designing a 40 hour DLC to be fair, rewarding and challenging when players likely have complete builds and most importantly extensive healing resources.
- Divinity: Original Sin II: Largely a comparison to Baldur's Gate 3 and where each exceeds the other. Also an in-depth analysis of DOS2's combat and the idea of balancing difficulty in preparation (gear, temporary buffs, pre-fight surfaces and positioning etc.) vs execution (in-fight decisions).
- Persona 3 Reload: A comprehensive critique and specific look at the failings of its 'rogue-lite'ish gameplay, as well as the good and bad of its combat mechanics and complexity curve.
- Star Wars Jedi: Survivor: Another comprehensive critique, discussing potential improvements to combat, its disappointing metroidvania abilities, a general 'great but unfinished' theme and more.
- Senua's Saga: Hellblade II: A discussion of the successes and shortcomings of the game's combat as well as getting the most out of graphical realism and thematic puzzles in terms of the player's experience.
- Neon White: The importance of discretising progress in improving your times in a speedrunning game.
- 12 Minutes: My least favourite game - A discussion about interesting premises with poor execution, continuity, consistency and time loop games.
Future Projects
A list of likely future projects that interest me:
- A prototype for something similar to Return of the Obra Dinn - before each frozen-in-time scene in Obra Dinn, there is a black-screen audio-only phase. I wanted to explore what you could do by allowing the player to move around a static, low-detailed scene and spatially explore the audio clues.
- Maybe something with a clockwork solar system like Outer Wilds or small planets like Super Mario Galaxy to experiment with gravity-based gameplay mechanics (also maybe a camera system for a platformer like this or like Psychonauts).
- Physics-based project, likely water simulation or destruction to more directly use the knowledge from my degree.
- Simple RTS framework with strategic zoom like Supreme Commander.
- Something with network programming to gain experience.