Child of Lothian
In ‘Child of Lothian’, you play as an orphan robbed of her childhood as her family is put on trial by zealous witch hunters. You are left on the streets to escape their persecution inside the bustling world of 18th century Edinburgh.
‘Child of Lothian’ is a single-player, narrative driven, stealth game. Set in 18th century Edinburgh, the player falls victim to witch hunts. After being orphaned the player must learn to survive in the harsh streets as a hunted outcast. It features a dynamic city with rich NPCs that go about their own lives. Through stealth and dialogue the player must create their own opportunities in order to complete objectives. As defined by the given creative brief the final product will serve as a prologue/intro to a hypothetical game.
After the divergent concept phase my responsibilities have been tied to the AI, from their design, to technical implementation (blueprints and AI systems such as Behaviour Trees), to the creation of tools to be used by level design, to setting up the animations (state machine) using the work by the artists!
‘Child of Lothian’ is now available on Steam!
Concepting, prototyping, implementing and playtesting AI & NPC design. Primary responsibility for the Witch Hunter’s design, the main enemy of the game and any NPC with gameplay implications.
‘Child of Lothian’ was developed over the course of a year by a team of 23-28 developers and is intended as a prologue.
The Witch Hunter NPC/AI Design
The Witch Hunter functions as the main enemy of the game. It’s design intentions are to create that prison escape-ish manhunt feeling, or in our case, a Witch Hunt. With this a unique and interesting we put a unique and interesting spin on our non-combat stealth as well. As the player wasn’t just sneaking past ‘guards’, they also had a pursuer so the evidence they left behind matters. It flips the ‘leave-your-mark’ trope as you leave your mark on the world but that’s not necessarily a good thing.The design solutions I put forward here allowed us the achieve the aesthetic of this all, not just in the cut-scenes, but also tell this narrative through gameplay!
The main way this is experienced by the player is through the ‘clues’ system. With this the Witch Hunter can track the player down with evidence left behind. This could for example be a sack of flour the player destroyed as an environmental interaction ‘smoke-bomb’. The player weigh short-term advantages with longer-term consequences. Putting a different emphasis on the planning aspect of stealth gameplay.
Enhanced Spacial Awareness System
Instead of every AI using complex logic and randomness to come to conclusion a lot more can be read from the environment.
AI need less communication between each other as they are all part of the same system which allows them to work together as dynamic in there without it needing bespoke logic.
Data stored here can also be accessed by NPCs without AI as they don’t need to use logic, but only to read and get info.
Particle Crowd Input
The data stored could also be used as an input to a particle system. This is relevant as the plan was to simulate crowds with this. By using this the particles could respond to world events without using perception or AI logic.
The systems also improved possibilities towards rational and believable ‘team’ work. Instead of each AI making the same decisions they can split up the area to investigate without them needing to communicate directly to each other as they all work within the same system. The AI themselves have no actual awareness of each other!
After our AI programmer implemented the node points and their generation logic. Unfortunately, after they left the team, it was discovered it scaled horribly to the larger game level. The generation process took so long no one ever actually completed one so I worked on a solution as to not harm the Level Designers’ rapid iteration process.
While I couldn’t match the technical complexity of the existing system, I did possess a lot of knowledge of already existing Unreal Engine systems. But modifying some C++ code in a minor way I was able to utilize the Environment Query System and Nav-Mesh Data to create a new generator that reduced the process to just a few seconds!
AI Perception of a Sandbox
As our concept contained a sandbox and an AI to interpret the player’s actions in it, we had to find a way for the NPCs to be able to understand an expandable variety of possibilities and events.
As a solution I designed a system that allow the AI to interpret the worlds based on tags. Anything that was detectable would then communicate its info using the universal tags. Each source has an array of three tags, each with their own purpose. Based on these the perceiving actor could then make a decision on how to respond.
0. Actor Type
This tag identifies the player or their unique actions. Most NPCs will deal with this the same as the NPC type, only the Witch Hunter will use it differently as they ‘recognize’ the player and their actions.
Tag used for NPCs that are also a stimuli source. For example a NPC that is knocked out.
The object type is reserved for actors in the world without their own behaviour but are still ‘perceivable’. For example a flour sack that can be destroyed.
The neutral tag is reserved for actors with a stimuli component but don’t contain specific info at this time. A flour sack is ‘neutral’ until is becomes ‘suspicious’ when hit by the player’s sling.
This tag can be reserved for things that are odd but not immediately dangerous. This can be unidentified sounds or sling-broken-objects. This is generally what an NPC would investigate.
This tag is slightly different than before as it not only means something is out of place but also that there’s a threat. This can be used for something civilians run from but the Witch Hunter runs towards. Think a knocked-out guard or witnessing the player pickpocket.
Things marked as ‘clue’ can be investigated by the Witch Hunter and work with the clue system. These will not affect the AIs alert state. (This index is left empty in the case of the source not being a clue).
With the use of macro’s the registering on tags is quite easily done. As all logic is dealt with in there and the input options are limited to Enums, there is little that can go wrong.
One of these Macro’s set the source’s type and description. This can change during runtime, for example, something that’s destroyed can change from neutral to suspicious.
The other Macro sets the third tag for the clue. As clues are only available for a limited amount of time it provides inputs for this in floats. The first determines for how long the clue can be found by an AI and the second for how long it is valid to be used if already found.
To use the tags we added a custom event to the AIPerception component. In addition to getting the actor we would now also get the tag array. With a function the tags are assigned Int values which then select an option from a struct. In this struct the designer can set how the AI should respond to each of the possibilities.
NPC Level Design Tool
The custom NPC Level Editor was made by me for the level designers to make working with the NPCs more accessible and speed up the workflow. While the properties could be edited in the details panel, the fact that it’s just numbers and has no in level representation makes it hard to work with. With the custom viewport (that controls like Unreal’s one) the level designers have all there properties in one screen. They can see what they are doing in the world through debug shapes and don’t have to type numbers as they can click in the world with a 3D cursor to set a point to that location.