Steel Effigy

Image 1

Steel Effigy Steam Link

Intro

During my internship at Campground Interactive, I worked as a gameplay programmer on Steel Effigy, a 4 player online co-op hack and slash roguelike built in Unreal Engine 5 using the Gameplay Ability System.

I worked on creating gameplay content like weapons and upgrades. I also worked on tracing improvements and general multiplayer bug fixing across the project. Towards the end of the internship, I started taking on more tech art related work to help reduce the workload on the art team, and also because it was something I enjoyed like the cutout effect shown bellow.

The portfolio contains the most fun and rewarding work I did at Campground Interactive.


Image 1




Cutout Effect

Image 1


Objects between the camera and the player would sometimes block the view, especially in areas with a lot of props like Boxes, Pillars or Street lights. Using camera collision to solve this wasn’t ideal, since the camera would constantly move in and out, which could feel disorienting.

The existing solution used a simple depth-based dithering effect that gradually removed objects between the camera and the player. It worked by defining a fade range where objects would go from fully visible to fully dithered out. In practice, this was difficult to tune. A short fade range made the dithering feel abrupt and unintentional, while a longer fade range would either leave objects still blocking the view, or cause them to start dithering while they were still in front of the player in order to fade out in time.
No cutout Image 1 Cone Mask Image 1

To fix these issues, I replaced the depth fade with a cone-shaped mask between the camera and the player. I added a depth mask so only geometry between the camera and the player is affected, along with noise to make the fade less uniform and more visually interesting. This gave more control over how much of the area around the player is cut out, and allowed a more aggressive fade without it feeling like camera clipping.

One issue was that fully dithered objects could disappear completely, which meant the player could lose awareness of what was blocking their movement. In some cases, parts of the floor could also be cut out when it shouldn’t be. To address this, I added a height mask that keeps anything below knee height. This prevents the ground from being cut away and leaves a small stump of the objects, helping with readability of the environment while still keeping the player visible.
Depth Mask Image 1 Stump Mask Image 1




Weapon Upgrade Workflow Improvements

I was tasked with buffing all sword upgrades, which ended up being time consuming due to the current setup. Upgrade values and logic were hardcoded across multiple files, and the UI text had to be updated manually as well. Even after going through everything, it was easy to miss parts.


To address this, I moved all upgrade values into curve tables, one per weapon, where each upgrade effect and its values were stored in a single place. This made it much easier to update and balance without having to track down scattered logic.

Curve Table Image 1

To access the data, I created a Get Rank Power node that takes an upgrade tag and returns the current rank along with its values from the curve table. These values could then be used directly for things like damage multipliers or other upgrade effects.

Blueprint Usage Image 1

I also updated the UI to use the same data. A Rank Power array defines which values are available, and the UI text references them through simple formatting. It also supports formatting like converting stored multipliers into percentages when needed like 0.25 as 25%.
UI Usage Image 1




Gun Tracing Improvements


The original weapon tracing worked by doing a ground trace based on the camera direction. If this hits the ground, a second trace would be fired forward from the player to compensate for the typical camera angle, which is usually tilted down around 15–30 degrees. This worked well on flat terrain, but became inconsistent when dealing with elevation changes or ramps.

The issue was that small height differences could cause the trace to hit the wall or steps leading up to the elevated surface instead of the target itself. From the player’s perspective, the shot should pass over these and reach the top surface, but the trace would often stop short.

Forward Trace Image 1

To address small elevation changes, I added logic where if the forward trace hits something close enough to the player, a third elevation trace is fired slightly higher up. This allows the shot to pass over minor obstacles and better match the player’s intention of hitting elevated targets.
Elevation Trace Image 1

For ramps, the player's intention is usually to shoot up along the slope. However, the current tracing would only reach a short distance up the ramp, and fail on taller ramps where the shot feels like it should continue further.

To solve this, I check if the forward and elevation traces hit surfaces with similar hit normals, and if they do, I treat it as a ramp and continue the trace along the surface instead of stopping.
Ramp Trace Image 1

Image 1
I am part of The Game Assembly's internship program. As per the agreement between the Games Industry and The Game Assembly, neither student nor company may be in contact with one another regarding internships before April 15th. Any internship offers can be made on April 27th, at the earliest

LinkedIn

Philip Bäcklund

Location

Malmö, Sweden
Willing to relocate