Select Page

FPS Prototype

Level Design, Level Scripting

Platform: PC

Genre: FPS/Horror

Engine: Unreal Engine 4

Production Time: About 3 weeks

Project Type: Personal Project

Team Size: 1

Players take on the role as an explorer who stumbles upon a seemingly abandoned starship and decide to investigate. It is evident that something has gone terribly wrong and strange monsters soon leap from the shadows.

FPS Prototype is a personal project I made on the side to showcase my scripting skills in Unreal Engine 4 as well as my ability to slowly build tension and guide players through an atmospheric environment. The star of the show is the level and while you can expect basic mechanics such as enemy AI and working gunplay, they are merely there as a means to an end and shouldn’t be treated as anything more than placeholder prototypes. The gun uses the stock model and the enemy uses an inanimate model of the Unreal Mannequin.

All assets are bought from Unreal Marketplace.


Design Goal and Game Pillars
Core Pillars:
  • Slow Buildup
  • Atmospheric
  • Easy to navigate

The point of the level is to guide the player around smoothly as the tension slowly builds until a natural climax is reached right before the game ends. The player is guided throughout the level using lighting and the angles of the walls. The tension is constantly raised using sounds and playing with the player’s expectations. Combining certain sounds and triggered events in certain rooms will make the player expect an ambush and leave them wondering when it doesn’t come.

You can only string the player along with this method for so long, however, and just when the player starts getting used to it, the tempo shifts and enemies start spawning into the game world.


Starting off inside the shuttle and exploring deeper into the starship until the command console is found.

The reactor is restarted and the player is attacked by hordes of monsters. This place is a death trap and the player must return to the shuttle and escape.

Blueprint Scripts

Dialogues and unique events were scripted directly in the Level Blueprint as they couldn’t simply be re-used. Common objects such as doors or lights with scripted behavior were separated into individual blueprints as they could be re-used and called from the level blueprint if needed.





Doors are used as gating mechanisms and to prevent the player from seeing into the next room from too far away. They are frequently encountered, so it’s important that they look, sound and animate properly.

Door Blueprint

Doors can be set to be locked on game start by setting the public bool isLocked to true, the lights on the door will then change from green to red.

Door Blueprint

Doors are triggered by walking into an invisible volume surrounding them. If the door is unlocked, it will slide open using a Timeline node for animations. If it’s locked, the red light will blink once and a noise will be heard. Leaving the volume bounds will play the open animation backwards, thus closing the door.

Door Blueprint

Doors can be unlocked after game start by calling ToggleDoor from another blueprint. The door’s light will turn green and blink twice while a sound is played to draw the player’s attention. If the door is already unlocked, it can also be locked by calling the same event node.

Triggers and Buttons



Triggers are activated when they are touched by the player. When activated, they can fire an overlap event in the level blueprint, thus triggering special events and dialogues. They can also function as a use trigger, spawning a text prompt and waiting for the player to press [USE] to trigger an event.

Player Blueprint

The overlap functionality is stored in the Player blueprint. Once the player overlaps with a ButtonTrigger, the trigger blueprint is fired. Pressing [USE] while overlapping with the volume will fire the TriggerButton event within the trigger blueprint before destroying the actor to prevent it from firing the same game event multiple times. Moving out of the trigger volume fires the TriggerEndOverlap event within the trigger blueprint and prevents the TriggerButton event from firing.

ButtonTrigger Blueprint

The ButtonTrigger blueprint stores three public variables.

TriggerOnce: If set to false will allow the overlap event to fire whenever the player steps into the trigger volume. Pressing [USE] within the volume however, currently breaks it as it destroys the actor from within the player blueprint.

ID: This string will be forwarded to the Interaction event within the level blueprint when the TriggerButton event is fired. This variable is used to connect the trigger volume to any events created within the level blueprint.

OverlapMessage: If the trigger volume is used to create a button, this string can be set to whatever message the level designer wishes to display as the player steps into the volume (Default set to “Press [E] to Use”). The text widget is automatically removed if the variable is left as blank.

Level Blueprint

Pressing the [USE] key within a trigger volume fires the Interact event dispatcher, which in turn fires the Interaction event within the level blueprint. The ID set within the trigger volume is carried over and will fire the command within the switch node with the same name (MachineConsole, LiftConsole or CommandConsole), thus triggering a script within the level blueprint. If no matching ID is set within the trigger volume, no further scripts will fire.

Flickering Lights & Screenshake


Lights are specific blueprints that contain multiple behaviors. By default they remain on throughout the game, but they can be set to constantly flicker or to listen to a specific ID within a trigger volume to shut down temporarily before turning back on again.

Light Blueprint

The Light Blueprint can be set to flicker at random intervals by marking public bool Flicker as true. The light will then initiate an infinite loop and flicker between random intervals.

The custom event FireBlackout can be called from external blueprints and is used to temporary turn off the lights whenever an explosion and screenshake occur. They can be set to listen to a specific ID, making sure that only the relevant lights are shut off whenever an explosion is triggered.

Level Blueprint

Whenever a trigger volume is overlapped by the player, it fires the TriggerOverlap event in the Level Blueprint via the event dispatcher. TriggerOverlap calls to FireBlackout in all the Light Blueprints gathered in the array FlickeringArray. Each Light Blueprint compares the ID from the initial trigger volume with their own to determine whether they need to shut off or not.

Areas of Importance


The game starts out with narrow corridors mainly meant for the player to soak up the atmosphere. The flickering light at the end of the corridor is placed so that it will grab the player’s full attention just before light on the right breaks. It’s more than just a cheap jumpscare though. By now players will start suspecting that something is wrong and by being exposed to such a simple scare so early will make them expect more later on. No further jumpscares will come, but the player will still expect them for a while, keeping them on their toes.

The sudden appearance of such a largo room is meant to catch the player off-guard and make them weary. It is designed to look like an arena and make the player expect something to happen. Nothing happens though and the player should start feeling uncomfortable. The window on the right serves two important purposes: It’s important for the player to be able to look outside and feel as if they’re part of a larger world and not just these cold corridors, but the light also paints the wall on the other end with shadows forming what almost looks like arrows and guiding the player further.


The cargo bay is another large room with lots of debris, meant to keep the player on their toes. It looks like another area where there should be an encounter or as if there would be something hiding behind the debris. Again, nothing happens, and the player is merely guided onward towards the lights.



The Command Room is the turning point of the game. The player reinitiates the main reactor, but is ambushed by a monster from behind. The player is given ample time to react as the creature makes plenty of noise while bashing the door down and then screaming as it attacks.



An explosion just rocket the starship. Back in the cargo bay, the room is now set ablaze, raising the stakes and signalling that it’s time to make an exit. Fortunately, having power up the reactor has activated the drawbridge and opened an alternative route out.


More explosions are heard and warning sirens are now blaring in the background as the enemy creatures become more and more frequent, putting further emphasis on the need to escape. This room is small and dark with plenty of debris where enemies leap from, putting the player in an uncomfortable situation where they feel preassured between escaping quickly or carefully navigating the area.



Down below lies the a familiar sight, the first open room the player encountered in the level. My goal was to make an impact on the player the first time they ventured through it so that they would instantly recall it along with the layout the second time around. As the player jumps down, 4 enemies spring from the shadows, offering a final climatic battle.


As the player escapes back through the corridor towards their ship, they are reminded that even though the enemies are defeated, the place is still falling apart and they should hurry and escape, offering some excitment until the very end of the level.