Brains vs Goals - Tslat/SmartBrainLib GitHub Wiki
One of the first questions asked when someone is looking at or considering the brain system, but aren't yet familiar with it, is:
"So what's so good about the brain system?"
Which if we're being honest; is a pretty fair question to ask. Most people who have worked with entities or AI in the past know fairly well how the goal system works (at least at a basic level of understanding), but the brain system is often some kind of vague distant mystery no-one ever really seems to talk about.
I postulate that the reason for this lack of discussion and knowledge is purely because of vanilla's implementation of the brain system leaving it a messy and near-unusable system, but that discussion can be left to the about page.
So what is so good about the brain system?
To give a full answer requires you understand the intricacies of both the goals and brain systems, which I cover in How do Goal Selectors Work and How do Brains Work pages respectively.
I can however give a pretty good explanation without going too much into the specifics of the systems. NOTE: As a pre-word, I'll note that the below explanation is based on using the SBL system. It follows the same design philosophy as the vanilla brain system, but it actually makes use of all the benefits that the vanilla system fails to. A lot of the below benefits are just not realised without using something like SBL.
To make things easier, I'll break it down into comparative sections.
Capability
The simplest and most prominent benefit of the brain system is that it's just downright more powerful than the goals system. By that I mean you can do a lot more with it, making more complex interactive AI and feedback-response loops and functionality, and incorporate more data sets and information streams than will ever be reasonably possible with the goals system.
This is primarily due to several key factors:
- Behaviours are designed with one function in mind. No more complex multi-facet goals that handle multiple things at once causing conflicts and limiting usability. You can can add in and tweak additional behaviours with little concern for strange and inexplicable conflicts.
- While goals primarily action-lock other goals with the Flags system (MOVE, LOOK, TARGET, etc), behaviours utilise a dynamic memory-state lock system. Behaviours operate based on whether their conditions are met, rather than whether an arbitrary flag has been marked.
- Memories are an all-encompassing data storage facility that allow for an entity to arbitrarily keep track of any data it needs to, without needing to rely on more and more in-entity variables and data points.
- Interactivity of behaviours means that behaviours work together, and collectively work together with sensor input. This is as opposed to goals, where goals are isolated and do their own thing, with little regard for any other goals.
- Behaviours have multiple layers of prioritisation, allowing for deeper customisation and ordering of behaviours, as opposed to the single integer that goals use.
- Behaviours and Sensors all work together in a brain, sharing their data and operating as parts of a whole. This allows for significantly less wasted work from fully-independent functionality like goals.
Configurability
Configurability is one of the most important requirements of a good AI system, and yet weirdly the goals system has almost none of it. At most with goals you'll get few primitive constructor parameters that's supposed to act as configuration for an entire goal, but anyone who's used this knows it just doesn't cut it.
Usually you just end up re-implementing the goal entirely in your own class with new logic, which in itself is usually inflexible and just specifically coded to the task at hand.
It might just be me, but this sounds like a really backwards way of doing AI.
Contrast this with the brain system, where behaviours and sensors are innately configurable to their core, with numerous dynamically configurable options and callbacks, and you immediately begin to see where a lot of the power comes from. These builtin configuration options mean that you can vary a mob's AI greatly with only a few minor changes, with no additional need to change entire classes or goals, potentially risking breaking other mobs in the process.
Usability
This point is a bit of a 'two sides of the same coin' situation. At their core, goals are rather simplistic and easy to use. You just pick a goal that does what you want, list it in order you want it to be considered, and you're done. Your entire AI is done in 10 lines of code and everyone's happy.
But then it just.. ends there. There's no more usability options, expanding on a mob's AI often involves changing entire blocks of code to make goals compatible, configuring them is confusing and tedious, and trying to understand how they work at face value is often frustration-inducing.
Because of the compartmentalised design philosophy of behaviours, after a short learning curve they become very easy and intuitive to use. Simply insert the behaviour segment you wish to perform in the position you want to prioritise it, and configure with any additional changes you want to make, and you're done. If you want to make adjustments, all you need to do is drag it to a different position in the list or change one of its configurations, and you're done. This design almost turns AI into a plug-and-play, where you just insert behaviours wherever you want them and let it fly.
Efficiency
One of the most important areas of modding in Minecraft is efficiency. We all understand the pain of players struggling to get the game to run well, especially with large numbers of mods and creatures.
Goals are actually quite efficient, for what they are. They're not an inherently inefficient system, and their minimalist approach lends itself well to lightweight operation. That being said, we can actually take it even further, whilst still offering the benefits of the brain system.
With the memory module system that the brain uses, we now have the powerful ability to cache memories of all sorts. This can be as simple as single boolean, or as complex as entire lists of entities. This means that in key areas such as nearby entity seeking, we can have a single check every dozen ticks (or slower!), done once for all behaviours to use. We no longer have every individual goal sweeping for entities every other tick, using them, then dumping them immediately. We can make use of an already efficiently managed memory system which has done the work for us!
The tradeoff to this however is that at its core, the brain system is less efficient than the goal system. It has more work going on in the background, and that costs CPU time. Vanilla doesn't do a very good job optimising this, opting to frequently iterate over collections not designed for iteration, refusing to sub-set collections to save iteration loops, and wastefully wrapping objects in other objects to solve problems that didn't need to solve.
Luckily, SBL resolves that and brings operation time significantly lower, allowing the brain system to actually compete with the goal system for efficiency, and in places with complex AI (bosses?), even beat out goals entirely in the efficiency arena.
Crazy!
Extensibility
Lastly, and arguably most importantly; the extensibility of the AI system.
Goals essentially have no extensibility whatsoever. If you want to make tweaks to a goal you effectively have to make an entirely new goal. If you want to inject additional functionality into an existing goal, you have to make an entirely new one. If you want to modify the conditions of a goal, you need to make an entirely new one.
See the trend?
SBL's brain system makes all of this incredibly easy. Brains in general operate in such a way that making tweaks is usually as simple as appending a single method call to your behaviour's instantiation, right in your entity's class. Injecting additional functionality is the same, as is modifying the conditions of entry for behaviours.
The inherent nature of a compartmentalised AI system means that it's incredibly easy and simple to extend the functionality of the system, without substantial additional work. Cut back significantly on entirely new classes and rewriting of entire chunks of code, and replace it with simple method calls.
Grouping behaviours is as simple as inserting them as a child of one of the parent group behaviours, which also have all the same extensibility functions on their own.
Everything becomes vastly more powerful, with less work!
Afterword
Unfortunately it's really hard to demonstrate these comparisons without going into deep detail, usually in code. I don't expect everyone will see the benefit of the brain system, or even come to terms with how it works in place of the traditional goals system, and that's ok. If you decide that the library or the brain system isn't for you, that's totally ok. The goals system does still work, it does its job, and it'll likely be there for a while to come.
For those of us who have seen the new way, I hope you enjoy the power and benefits it offers.