
Derelict was my first look into Unity 4.3’s 2D toolset and honestly, I wasn’t let down, much.
Working with sprites proved effortless and movement controls for the player were simple thanks to only using a 4-Axis movement.
What did prove interesting was our creature. A fairly simple FSM that used several senses (smell, sight and sound) to track down the player. Sight and sound have pretty much been explored everywhere but using a players scent to track them isn’t used much but on a code side isn’t too different.
The original concept for the scent had it dispersing from the player and setting up a strength and trail along a grid based movement system that the AI could pick up if it wandered into range, moving quicker as the scent screw stronger. This idea was heavily scaled down.
The player instead left a little trail that decayed over time. All strengths were 1 and they were treated like dynamic waypoints that worked really well for the AI tracking you.

The above was a later altered version of the monsters sense of smell. A stronger cone in the front but a smaller 360 degree sense overall. Originally we only used the front box to detect scent and it had a hearing box that covered 360. That was how the jam implementation was done, the above was a later thought that worked a lot better.
These boxes however only focused on the scent left by the player, meaning that if you were close to it and kept just enough distance (and kept quiet) you could actually avoid the monster. This came down to the fact that the sense of hearing was ignored if it was on your scent, an original design choice in the code but in hindsight (and after some sleep) hearing was a better use for letting the creature know in a 360 degree area that you were close.
Sight overwrote scent following and had the monster rush you down and attack. If you were seen, you were done for.
Overall it followed pretty much the following idea:
– Try find the scent of the player (within your front arc)
– If that fails, can you hear them behind or around you?
– If you see the player, drop everything and go for them.
The downside again was that if the monster didn’t see you and carried on following scent, walking or running would not alert him. MASSIVE oversight.
What scent did give us was a nice dynamic waypoint system which worked in conjunction with the static waypoints that the monster followed:

Metric shit tonne of waypoints were placed.
To overcome it just following a predictable path the monster will actually use the wall vents to move around as well. This was handled by the roam state (I’ll cover the FSM in a minute, sorry). If it hadn’t found you in X time it would take a vent to another area and search around there and repeat. This was a tiny bit RNG in whether you were detected or not but made for some “OH SHIT!” moments in testing when I just didn’t think it would find me.
One interesting thing that happened with all this was the doors. Since we were using static waypoints and not actual pathfinding, due to time constraints, we had to find a way for the monster to navigate doors. The conclusion was to allow it to use vents (on either side of the door) to pass through. During roam it would just go straight through. If it was chasing you and the door was closed we’d give the player some time to get away before it used the vent. This kept some balance and the original plan for the doors in check without screwing up the creature when it was just walking around.
The AI finally broke down into the following FSM all run by “MonsterController.cs”
– Roam State ( General purpose waypoint following state, jumped around the map through vents ).
– Search State ( Followed dynamic waypoints (scent) and allowed the creature to track the player, its main tracking state ).
– Investigate State ( When it heard a sound it would use this to follow the sound, essentially creating a new waypoint to the location where it heard it ).
– Chase State ( Once seen, it jumped into this, gained a speed boost and went for the player ).
– Attack State ( Attack and shout, send a kill message when it was done ).
– Victory State ( Stop the AI, it won ).
I’ll try get a UML up for this but the general idea was.
Roam goes into anything.
Search will return to roam if it lost the trail, transition into chase/attack if needed.
Investigate would transition into Search/Chase/Attack and Roam if it lost the trail. 99.9% chance it would always lead into Search as it turned around and picked up the trail.
Chase would go into Attack when in range. If you somehow escaped it could pick up the trail or return to roaming if you made some impossible escape (in as a safety precaution).
Attack would always succeed and lead into Victory.
So that is the main parts of the game. We had a few other little pieces like pick up (linecast vs. layer) and the torch…
The torch was just a texture with an alpha’d section to reveal the player and light up the floor (AKA Alpha 0 there). We knocked the Alpha on the total down a little so you could just make out the scenery. Unity’s 2D draw layer stuff was brilliant for this as we just made sure it was drawn as the top layer. There were some plans to try do some more lighting things with this (flickering lights etc) but I’ll save that for a later experiment.
Hope this proved interesting for someone and see you all next Ludum whether I’m solo again that time or part of a team like on Derelict.
Scott (https://twitter.com/iOSScott)
Art to follow from Dan (https://twitter.com/Daniel_Scholes)