Revisiting Rule-based AI

With today’s Processing Power I think its time to Revisit Rule-based AI. I’m particularly interested in Expert Systems using if–then rules. An expert system is a computer system that emulates the decision-making ability of a human expert. Expert systems are designed to solve complex problems by reasoning through bodies of knowledge, represented mainly as if–then rules rather than through conventional procedural code.

In revisiting, IF THEN Rules, I reviewed an old post of mine back in my DarkBASIC days on my first Behavioral Rules A.I. Nodes System (BRAINS)concept of implementation. I found this hilarious as at that time I really didn’t know that such an AI existed and thought I was on to something new. Theres even a Behavior Tree in there, LOL. But I felt there were some nuggets of value hiding in this old post.

BRAINS incorporates Give||Take Registry, Binary Decision Trees, Hit Objects (Triggers), Tasks (LUA Script), Dark AI (Pathfinding), and Q & A Diaglog.

The Give||Take Registry

The Give||Take Registry is a list (queue, stack, or any other data structure) of Node Keys. A Node Key contains a: name, value, compare operator, and logical operator. Node Keys can represent any kind of property. The data in the Node Key is used to perform a simple IF condition and return a TRUE/FALSE result. I find it easier to visualize each IF Condition as a node in a decision tree, hince the label Node Key. All the Node results are tallied to produce a final TRUE/FALSE result.

All Interactive Entities have their own Registry and the Give||Take role is based on the entity that initiates the interaction (collision check). Entities who initiate the interaction are Giving, the receiving Entities are Taking. When Giving, each Node Key can represent something the Entity possesses. When Taking, each Node Key can represent something required by the Giving Entity for positive interaction.

From a coding perspective, we iterate through each Node Key in the Take Registry. Each Node Key is matched-by-name to a Node Key in the Give Registry. The Operators from Take Registry Node Key are used to perform the comparison. If the result is TRUE we continue to the next Node Key, otherwise we exit checking returning a FALSE result. If we’re able to iterate through all the nodes we return a TRUE. Thats it! The final result can used to execute a scripted action.

GTR is a simple and high performance solution for dealing with Interactions that require many conditional checks against a Player Character abilities, skills, accessories, items etc. GTR solves Question #1.

This takes me back to the my Prolog dev days. Good times.

You telling your age @EvilCleric. :). As simple as the Prolog syntax appeared, I could not wrap my head around it :mad:

I’d love to get a primer about basic A.I. logic, if you would be willing to recommend something. I’m developing some very basic A.I using simple logical checks like this along with other update events that check those values, or allow for other events to interrupt the process. But I feel I could benefit from reading more about this process.

My project is involving firefighters and basic A.I. for them to move around. Right now I’m simply building the actual logic, no assets like characters/animations, I’m just playing with the system. End goal is for them to execute assignments and respond to other simple conditions, like smoke visibility reducing theirs speed, which increases time left to complete phase but also allow for events to with delay or end the current phase they are on, and lead down a different path. Right now though, I think my current understanding is to create logic that just seems to behave intelligent, but I think it’s piecemeal and not necessarily planned. I should note though - I’m less interested right now in the more machine-learning-like A.I, something that like maps a room, and more in the simple decision-tree classic design.

I’ve read through (though not truly comprehended, (especially behavior trees) Unreal’s AI, but that was mainly for understanding the engine’s logistics behind it, like working with nav meshes.

I do think I will need to master behavior trees before the end of this but I need to first put some type of rudimentary system in blueprint so I can see how it all works together, because I’m much, much more familiar and able to comprehend complex systems in blueprint. Do you have any recommendations?

Hi @LiveSimulator

I would say at the lowest level BASIC AI is a simple conditional IF x THEN do y ELSE do z Statement. A Select/Switch construct is the simplest form of a List of Conditions. We use these constructs in programming the computer, giving it AI it needs to accomplish what ever task need. For Bots, we’re doing the same thing, but in much smaller/specific context, typically with a data-driven approach based on Sensory Input(Environmental Checks, Self-inventory Checks, Target-inventory Checks) and Motor Output (Navigation Actions, Animation Actions, Event Actions: Fire Weapons / Give Health, etc).

The List of Conditions can be fixed or dynamically built by some form of Decision Method. The various AI Methods are the Decision Methods.

IF fire distance < 50 THEN check water supply ELSE apply water supply to fire
IF water supply = 0 THEN queue Fire location and seek water source
IF water distance < 5 THEN extract 20 water
IF water supply = 20 THEN seek queued Fire location

This video does a decent job at giving a short overview of the evolution of AI from Rules-based AI to Neural Networks. There are several similar videos, but, they all talk about moving away from or problems with Rules-based AI. All predecessors AI methods improve on the concept of a Rules Lists. UE4 has subsystems and user-friendly functions that handle gravity-based navigation to move an Actor from point A to B in the 3D environment.

I have to admit I’m not big fan of UE4s current implementation of the Behavior Tree. It just feels clunky with how the task are implemented. Not sure why the AnimBP {State Machine, etc} wasn’t used. Could have benefited from some interchangeability and self containment. In fact, the Anim BP Statemachine can be repurposed into a AI FSM & HFSM. With practice, I’m certain I could get used UE4 BTs, but I cringe every time I see one lol.

Right now I have a main data structure consisting of 12 or so variables, most of which are enums (granted, it’s inefficient for some things like MovementType, where you have a numerical value. But as I’m establishing them I want to have a lot of clarity from the very beginning.

I’m sure that this main data structure could develop as many as 100 or 200 separate variables to track on each of the fire units, though I don’t anticipate the data structure to become too many levels deep I would say three at the most right now. (The main benefit will be the combination of multiple variables one or two levels deep but simultaneously occurring and thus overwhelming the user and appearing to be fluid and complex)

How how concerned should I be about performance? Right now I just have a timer set it begin play to loop every tenth of a second and I’m slowly building up functions that check the value of various variables and if those variables have changed, execute the different branching path.

My understanding is that it’s usually better to run those updates the moment you’re having the variable questioned itself changed but I didn’t know if I should be so concerned about that at the moment, since my biggest obstacle is simply coming up with these variables and tying them together logically and keeping track of the whole system. My Hope is later if I know that it’s stable but needs some improvements and performance I can refactor it and put those updates the moment the variables are changed by the surrounding environments, events, etc.

For my purposes I’m hoping just using wishful thinking by keeping to the simpler more traditional form. I do think there are certain elements where a more modern AI or machine learning based solution would be effective such as realistic heat and fire propagation, but for now I’ll focus on the simpler elements which should provide more immediate benefit anyway.

Thank you very much for your insight.

I’m not certain if you’re using Behavioral Tree, FSM, etc, but if you’re going for simpler Rules-based setup, You may need much less than 20 variables. You could store vars in BP Structand use a BP Array as the data storage structure, BP Structs can be used with BP Datatables for CSV/JSON import, export, transfer great for managing data in data-driven systems. and BP Arrays are really flexible and can serve as a List, Queue, or Stack Structure when processing iterating over the data.

My first game related subsystems we’re particle systems, thus I design all my subsystems like particle systems with some form of Object Pool Manager, Initializers, Object State Process Loop/Iterator (Update), and Termination Constructs. The Process Loop/Iterator is where you will process the data in the data structure.

In regards to performance, once you get the system working, you can stress test and optimize as needed. The question I have for you is the game multiplayer? That will play a role in how, when, what vars to update.

Machine Learning is awesome, but do you need it to accomplish what you need Bots to do?