Alone in the Dark
Alone in the Dark (2024) is my first professional project which I worked on during my internship and while employed at Pieces Interactive.
The game is a re-imagining of the classic survival horror game from 1992. I joined the team at Pieces Interactive fairly late in the development process and worked through all the hurdles up to release as well as on a couple post launch updates. I had a very generalist programming role and worked on a number of things across gameplay, engine modifications and tools.
The game was made in Unreal Engine 4 and released on Steam, Playstation 5 and Xbox Series X|S.
​Some stuff I did:
Input system upgrade & Key Rebinding
One of my first big tasks was to update the input system we used to the Enhanced Input system which played nicer with how we had set up gameplay related abilities and would also make it easier to handle input from different contexts such as in puzzles. The upgrade was primarily advocated for by a technical designer who I worked closely with throughout the process to make sure the new implementation would work well for our needs.
​
Another reason for the upgrade was to better accommodate a system for rebinding player input which I was also responsible for implementing. The UE5 demo project Lyra has an implementation for rebinding input also built using the enhanced input plugin, which I used as a base for our implementation while also adapting it to our needs since the one Lyra used also had a bunch of other things that were not relevant to us.
Difficulty system
I implemented the system for the various difficulty settings in the game. The difficulty is split in two separate options, combat difficulty and player guidance.
The combat difficulty simply affects some numeric values like how deadly the enemies are and the amount of consumables found.
​
The guidance setting is a bit more involved, it enables or disables certain extra mechanics that can help guide the player, allowing a choice for how much the player needs to figure out themselves. The player guidance setting includes a subset of settings that can be toggled individually.
​
-
The ability to see all objects that can be interacted with in the same room that the player is currently in.
-
Highlighting of important words and passages in clues that are found.
-
Added functionality for the map to show when the player has the required items or information to open/solve doors and puzzles.
-
Additional hints being given in the form of extra objectives to aid with tricky puzzles and other progression.
When implementing these systems I worked very close with the design team to come up with suitable guidance aids that would fit with the game. It was also important to implement them in a way that would be easy to work with from their side, such as marking important parts of texts in a way that would work with localization and the ability to set up logic for when a puzzle is considered "solvable".
Dynamic consumables
The player can find items scattered around the world in the form of health pickups and ammo for the various guns that can be unlocked.
These pickups are spawned in using a dynamic system that randomizes the type and amount of items based on the current state of the player. It is biased to prioritize items which the player currently has a lower amount of in comparison to a set target amount and it will give more items the further away from the target that the player is. This system can also be overridden by specifying the type and amount on the pickup instances.
The randomization happens in two steps. The pickup decides which kind of item to spawn when it comes within the players view or the player comes too close, this is to ensure it can spawn the correct mesh before the player sees it. The amount of items given however is decided when the player actually picks up the item, that way it can be decided using more up to date information about the players state. If the type is decided to be pistol ammo when it is spotted but the player is already carrying a lot of it, and then shoots a bunch before picking it up, it will likely give a larger amount.
The system also allows the settings for targets and amount-distribution for the different item types to be changed during runtime if the designers wants to change the intended experience in specific sections of the game, for example ramp up all the values in preparation for a difficult combat encounter, or drastically lower all ammo values except for a specific weapon to encourage use of that weapon in a certain area.
​
This whole system required a lot of testing and tweaking the algorithms to make it feel good. The goal was to give the player the satisfaction of finding just what they need at the right time without it feeling too obvious that the system is “rigged” by always finding whatever item is currently lowest, and I think we managed to get there in the end.
Achievements
I was responsible for implementing the achievements in the game, as well as everything surrounding them.
That includes the implementation of the APIs for the platforms that were missing parts of or all of it out of the box (PS5 and XSX), wrappers to easily unlock and check status of achievements in the game, and actually adding the logic for unlocking the achievements themselves to the game. Many were simply unlocked by a specific story event or other simple gameplay moments but others required more complex tracking of data across save games.
I also created a way to define the achievements and their related data in a datatable in the engine and the ability to export these definitions to files that were ready to upload for the different platforms setup-pages, that way we could have a single source of truth for the achievement data in the engine itself which made it easier to update them when needed.
Console Development
I also did a decent amount of work on console specific development and troubleshooting. The biggest problem area for us in this regard was compatibility with the Xbox Series S, the performance was simple enough to adjust for but its limited memory caused many issues. Me and the others on the tech team therefore had to do a lot of work to try and minimize memory usage. Some of the things included was a whole lot of level streaming optimization, more specific control of loading and unloading assets in C++, and breaking up reference chains in blueprints to avoid unnecessary assets being loaded.
​
Another thing I had to do was to split up our built packages into smaller pieces, since Playstation requires that the initial installed payload can't be larger than a certain size and the user should be able to start playing the game while the rest is being downloaded. Unreal has a way of assigning assets to chunks which allows building separate packages, and it allows a fairly automatic process of assigning just a few core assets and then all other assets that are referenced directly or indirectly by those core assets will be placed in the same chunk.
Unfortunately, because of the way that the project was set up, we had way to many references between assets that was not necessary which meant that there was no easy way to assign just the assets we wanted in the first chunk without the rest of the game being pulled in as well. To avoid having to assign every single asset manually, I created a python script that could be run from the editor which would go through all of the assets and assign them according to some more specific rules. I also made it so that this script was run during our build process so that any new assets or changes in references would automatically be reflected in the new builds.