top of page
LibraryHero(demo).png

Development Highlights

Built using Unity3D, C#, Blender, Cakewalk, Audacity and GIMP

  • Randomly generated levels

  • ScriptableObject workflow

  • Basic state machine AI

  • Stats, upgrades and Status Effects

  • Language localisation (English, Russian, French, Simplified Chinese)

  • Dynamic audio system (calculating audio attenuation)

  • Controller support

  • Serialised and secure save data (using binary formatter)

Shedding light on Heartless Dark

Published to Steam

I achieved my goal of releasing Heartless Dark on Steam. I also implemented Steam Achievements using Steam's C# wrapper, Steamworks.NET.

You can check out the Steam page here...

Mimic Furniture

Early in development I made many props destructible - smashing things tends to help with game feel. Unity's Rigidbody.AddExplosionForce() was really helpful and convenient for this. The furniture being able to "die" naturally lead to me wanting to add an enemy that disguises itself as furniture.
The mimic essentially chooses a random piece of furniture on spawn, copies the variables for mesh and colliders and adds relevant physics and AI components. It then removes the original prop and lies in wait for the player to come into line of sight.

ScriptableObjects

I made extensive use of ScriptableObjects in my workflow. I used them for Guns, upgrade pickups,  Character stats, Monster Stats, a drag and drop AI state machine, OnHit effects and more.

I found this designer friendly workflow to be very quick and helpful when it came to balancing the game as well as visualising my work.

I was able to easily add multiple characters, a varied arsenal and even elite versions of enemies while still exposing variables for players to adjust the the difficulty of enemies or roll a randomised character.

Audio

I have a passion for audio (I studied Sound Technology at COPA in 2017). I'm proud to say that I recorded and edited all the sounds in the game. I made extensive use of my own recording equipment  as well as Cakewalk and Audacity.

I also used C# to create an 'Audio Manager' (using the Singleton pattern) which integrated with Unity's Audio components.

It includes an object pooling system to optimise my usage of one-shot sounds and it dynamically calculates audio attenuation, volume and EQ based on the position of the sound relative to the player.

(watch video below with sound on)

Randomly Generated Levels

My level generation system is a mix between hand-crafted level design, random layout and procedural item, enemy, hazard and event placement. I also included a seed system for replaying runs and exposed many variables for players to adjust the challenge and variety of the level generation.

I created a grid of points, randomly picked a starting point and then stepped through the surrounding grid points to pick the positions for the next room (repeat for randomised RoomCount). All surrounding rooms that are not chosen are then made into wall tiles. The first room is the entrance and player spawn point and last is the exit and player objective.

Systemic interaction

I've tried to make the game's systems a web of interacting pieces that are interesting when they come together.

  • Acid

  • Water

  • Electricity

  • Webs

  • Lasers

  • Explosions

  • Exploding fire extinguishers (stun)

  • Life steal

  • Summoning ammo

  • And much more...

I used Unity's coroutines to make recurring ticks for effects that occur over time. I decided to go with coroutines instead of C# async tasks because I wanted the ticks to be closely linked to timescale and framerate (to avoid unwanted effects when pausing or creating hitstop feedback).

3D Modeling

I modeled and texture painted all the props (and their broken counterparts) in Blender.

bottom of page