Player movement features suited for a horror game (i.e., no backwards sprint, etc), including stamina, sprinting, crouching, and jumping
Lantern mechanics suited for a horror survival, including oil & matches as "ammo", different light modes affecting visibility & oil drain, and a deprecated light dimming based on oil left
Oil & Matches pickups for the player to refill their "ammo"
Player HUD pertaining to stamina level, oil level, matches left, tutorial objectives, and a deprecated "Moon Mechanic Cycle" visual
Deprecated "Moon Mechanic Cycle) which determined the player's environment & enemy difficulty
Cinematic triggers
Quick prototypes of features that had art/3D models yet to be implemented
General bug fixing, game optimisation, and rigorous playtesting
Adding debug toggles and print statements to assist with playtesting
On-call assistance (Discord screen sharing) with version control (Github, Github Desktop, Gitbash), including correctly pushing/pulling changes, creating branches, and resolving merge conflicts
Providing help with basic Unreal Engine 5.4.4 features & general manoeuvring around the engine
Implementation of 3D assets, models, materials
Applying virtual textures to created materials for models
Correcting the positioning of certain world objects to prevent clipping, wrong orientation, etc
Deciding whether a model, texture, or animation was necessary for scope/important to indicate mechanics
Theorising tunnel from tutorial cave to altar using 2 separate landscapes, hardwiring player goal
"Quick" cutscene flashes that hinted towards player objective
Zoom-out shot showing eye-shaped map
Deciding the optimal programmer workflow to ensure smooth collaboration
Attempted use of Flow Shotgun/Shotgrid Production Software to organise team workflow
Organising files, assets, and blueprints where they make sense
Deciding our version control workflow
Exporting weekly builds + solving build issues
Work in components and attach (e.g., stamina component attached to player character)
Create parent blueprints to create children from (e.g., pickup parent, then creating oil, matches, rune pickup from that)
Use Custom Events to sort organise events into a more readable format (nicknamed "Event Bus")
Categorise Variables
No "Magic Numbers" (0 is ok to keep)
Name blueprints BP_EtcEtc, WBP_Etcetc,
Name variables with spaces between (e.g., "Stamina Cost" instead of "StaminaCost")
Colour blueprints red for needing urgent attention, deprecation, or copyright issue
"Get Actor Of Class" and "Event Dispatch" to communicate between blueprints (only Blueprint Interface for certain mechanics)
Despite building off UE5's First-Person Template, we had to make sure the movement felt suited to a first-person, horror survival game. While still providing fairness to the player, this would mean barring "advanced movement tech", including:
Backwards/Strafe/Crouch Sprint
Sprinting in Air ( to prevent stamina loss for zero benefit)
Crouch Jumping
So the only "permitted movement" would be to sprint diagonally/forwards.
The NoCrouchInAir Custom Event prevents the player from crouching when they are falling (preventing crouch jumping) and sets their state accordingly.
The Sprint & Restrictions prevents sprinting while in certain states, also triggering a hacky way to allow sprinting after it goes through all branches
Initially, we used Unreal's inbuilt crouching function which essentially halved the player's height. However, the crouch felt quite sudden (which could potentially induce motion sickness) and didn't match the game's feel. We instead took an existing horror game movement template containing an "animated" crouch and adapted it to ours (Credits to Treety for the template).
Checks through states to allow crouching
Sends a sphere trace when uncrouching to prevent crouching into terrain
Set walk speed
Play sound
Change camera pitch overtime
Halve player capsule for collision
Event Dispatcher to trigger a tutorial task complete
This horror game movement template generally replaced our camera movement, sprint, and jumping feel, making it more "weighty". But the stamina, function, and triggers largely remains ours.
A clamped float variable drained upon input, recharged otherwise. Then it was restricting input when such variable was out. However to ensure less annoyance with jump taking up a large portion of stamina and terrain navigation, the player could endlessly jump (at the cost of using up their stamina bank for chases).
Event trigger from input after going through movement restrictions
Perform stamina regen or loss calculations
Clamp
Force walking when out
Don't regen if full or in air
Other outputs for printing
Update UI
Set speed
Set state
Reset doOnce since we want to be able to set the speeds again (and since the code runs on tick)
Since the lantern had a struggle animation in mind due to matches, toggling it was a bit more complex.
On input,
If we have oil/matches left,
Toggle visibility of initial lights to simulate the small sparks of a match striking
Repeat until successful based on a set chance
Lose a match
Turn on light
Send an update to the HUD to match actual matches left
A clamped float variable drained upon boolean. Recharged via pickups. Turns off lantern lights upon empty.
On tick,
If light source is on, run
Minus oil via calculation
Update HUD
Turn off light via boolean setting visibility
Using the scroll wheel,
Play sound
Set oil drain amount (since the modes burn at different rates)
Set state
Set colour
Set attenuation, source width, angle, length
Reset DoOnces (so player doesn't repeatedly set the same mode again)
Deprecated due to incompatibility with current light mode code.
If light is on,
Set light intensity and attenuation radius based on current mode and oil left
HUD class blueprint which organised how the HUD was shown, collapsed, and initialised upon game start. Also displays some of my programming standards, where all processes run on Custom Events to make the code readable/cleaner. Also demonstrates Event Dispatches.
Event Bus - Runs code inside the blueprint
Comms - Area containing communication to other BPs
Initialise HUD - Makes sure HUD is properly added
Visible HUD on Input (Deprecated) - Sets the visibility on certain HUDs for a progressive tutorial instead of showing every element which may overwhelm players. Deprecated due to issues with cutscene HUD code constantly setting visibility
Hide HUD in Cutscene - Depending on player state, show or collapse HUD (unfortunately contradicted with showing a progressive HUD for tutorial reasons)
8-part cycle which would've decided world events such as fog, enemy speed, and lighting. Deprecated due to focus needing to be in other areas like smoothing out the core gameplay loop.
Runs on a timer that ticks every 1 second
Every minute, change moon phase
On cycles that are "emptier", make the enemy slower, the fog less heavy, and the light more bright. Vice versa on fuller cycles
Display suitable cycle, name & timer depending on current state
Cycle back to initial phase after the last (8th) cycle
Flash of images to hint towards player objective as per player feedback & player direction.
Hacky way to implement a "circular timer" using a radial slider which had its values updated via event. Other way would be to create a material. Same mechanics were reused for skipping cutscenes.