Hello World! We’re the dynamic programming duo of Dharma Games, M1rakk and wornTunic! In the next couple of months, we’re planning to publish a few development blogs to show how we solved some problems, or even educate. Things that we’ll cover are general design ideas and approach to certain problems in game development. Our aim isn’t to overwhelm you with code, but to explain our reasoning in implementing certain solutions. This blog should also serve us, so that we can define our game better. We’ll use examples from Hatchet, but we’ll try to keep blogs general so the ideas they carry could be applied elsewhere.
AI systems for games rise in complexity proportionally to how diverse you want your game to be. If you need enemies that rush to the player in order to hit them, like in tower defence games, you won’t need some well-designed, modular machinery to back it up. However, enemies in Hatchet were designed to be intelligent, making various decisions, all readable to the player. Those decisions dictate how the player perceives the game: if done wrong, player may reasonably expect certain enemy’s behaviour, and be misguided due to poor AI predictability. So, we marked what we wanted our AI to be:
Smart, but not too smart!
Predictable, but not too predictable!
And that’s a problem…
Making AI behave certain way so that player finds it realistic and human-like is a thing of experimentation. Through testing, interacting, we find that certain behaviours work or not, and tweak the behaviour or the decision so that it becomes more natural to the player. Player who pays attention, that is.
Our misfortune lies in that we started making the AI before we saw how much slight improvements will be necessary. This is our first game of larger scale, so we based our AI on the decision tree, since it’s the industry standard for decision making. Improvements and special cases were difficult to pull off and required coding. That’s why we decided to make a second system, with knowledge gathered in our failed experiment. It’s designed to make it easy to change what influences decisions for actions, so that only coding we need to do is actions (unavoidable) and the system itself. The new AI is based on the Utility AI principles, and it will be described in detail in future blogs.
Hacking system is designed in a way so that it can be highly extendable and customizable. It is based on a node system with 3 types of nodes: computers, objects and actions. Computers have a list of objects it can access. Similarly, objects have a list of actions that can be done over that object. The system should also have a simple and robust detection system based on timers that will give urgency to the hacking mechanic. The availability of certain nodes to the player needs to be dynamically calculated. Player stats and some events or actions in the game are taken into account when setting the node availability.
For our stealth mechanic we decided that it should be as binary as possible for greater readability. Player can crouch behind cover to hide, sneak to avoid being heard, perform distractions etc. The enemy can either see the player or not at any given time. Every cover should be able to completely hide the player in regards to height (consequence of camera perspective).
Even though player visibility to the enemy should be binary our detection system is not. Visual detection is based on a fact that the human brain takes a while to process images coming from the eye. We greatly exaggerated that effect. The detection system should have the ability to detect closer, bigger, and out of place objects faster than far, small and regular objects. In order for player to manipulate the given detection system, it must be clearly visible and readable. For sound detection there should be no lag between sound and hearing. Sound can be detected only if it is loud and close enough. This allows for greater ability to use distractions and get out of tight situations.
If you have any suggestions or criticism feel free to contact us.