Exposure
Lead Programmer
A first-person horror made for my Master's, steeped in Scottish folklore and dripping with dread...
Key Achievements Quick to learn the basics of Unreal, having never used the engine before. Responsible for coding/scripting all major systems, as our only programmer. Designed the player's journal, which updates dynamically with pictures taken in-game.
Team Size 6 (3 designers, 2 artists, and me). Made With Unreal Engine 5, C++, Blueprints. Grade AExposure casts the player as a reporter exploring the lair of infamous Scottish cannibal Sawney Bean. Armed with a faulty torch and Polaroid camera, the core game loop centers around exploration, crawling through a increasingly-claustrophobic cave network and cataloguing its secrets. With the coursework brief only asking for a vertical slice, though, the demo is most focused on continuously building tension over its tight, 5ish-minute run time - with a few scripted scares along the way...
Movement Mechanics
Conscious that much of the first-person horror genre amounts to "walk around and eventually get jumpscared", our level designer wanted a more varied, more tactile experience from the off. Drawing from my own visceral hatred of caving, I was quick to prototype Exposure's crawlspaces: invisible splines that the player can hook on to and slowly inch their way along. With our environment artist then building tunnels around these paths, the overall effect is stifling.
By submission, there was time to add forking paths, plus a much-needed splash of UI. I also had fun adding damping the player's camera, restricting their field of view and making the crawlspaces that bit more constricted.
The Journal
With our UI designer dropping out of the project early on, I was quick to take responsibility for designing the in-game journal. Narrative wanted a way to log and write lore about their environmental storytelling; I chose to present this diegetically, to best keep the player immersed in Exposure's atmosphere. It might not be a formal approach to UI - and my artistic skills leave much to be desired - but it certainly reflects the player's role as a reporter.

Rough Notes An early prototype of the journal, that could recognise the most prominent object in a Polaroid and pair it with the appropriate text entry.
The journal, therefore, is filled in dynamically. Maybe it's just my interest in procgen, but rather than force our narrative designer to manually create each entry as a separate UI widget, I used Blueprints to construct these at runtime. This better allowed for redrafting (all entries being encoded in a single .json file) and better creates the feeling of putting together a scrapbook of handwritten scrawlings and Polaroid pictures.
The Camera
Of course, to actually log an environmental curio in their journal, the player must first take a picture of it. If the curio is clearly visible, the image is captured in a RenderTarget2D object, then displayed in the journal alongside its pre-written caption. It might not be mechanically significant, but I like that the player ends up with a unique set of their own, in-game photos.
The real challenge, though, was integrating these photos into my save system. While it wasn't strictly necessary for such a short demo, I (foolishly?) decided saving and loading the player's progress would be a nice touch. In theory, accounting for photos just means making space for some fixed number n of textures (dimensions 1024 x 1024) and storing each of their 4 RGBA values as floats in an array (size 4 x n x 1024 x 1024). In practice, doing so in UE5's C++ syntax without allocating memory incorrectly required a ridiculous amount of Googling.1
1 As if to illustrate my point, the clearest explainer I could find on saving screenshots and byte data in Unreal Engine has since been deleted. For the benefit of any programmers in the same position as I was, it is luckily still available on The Internet Archive.
Polish, Polish, Polish...
The end result was, of course, a collective effort. For any of my individual contributions, my main responsibility was just doing justice to the rest of the team's fantastic work. That'd mean making a dynamic heartbeat Metasound to our sound designer's specs one day, setting up fully responsive Animation Blueprints the next. I even found the time to add some tech art, porting my old work on a procedural eye-strain shader from DirectX to UE5 - why not cannibalise a past project, eh...