I open a new topic for an already described "issue" 1 year ago here (viewtopic.php?f=6&t=642&hilit=Logic) but I will take a new approach on the description and the resolution of the "issue" that is why a did open a new topic. Please merge both if you consider it should.
Note that this is a very long post (so take a coffee cup ), but if you are already used to Gladiabots mechanics and Boolean algebra, you will be able to skip a whole bunch of paragraphs/sections. I've tried to make it as clear as possible using typo and quote section to make it "readable". Bold expression can ease to find "hot" points .
I will try to be as "global" (but precise) as possible starting from the base logic of the game. Note that I'm not a math professor but an engineer and (quite) used to "work" with Boolean algebra and I think I've found the root cause of the "issue".
The "issue" (I will call it after "misconception" because it is more accurate) induce a lack/weakness in the Target Filters of Condition nodes and Action nodes.
It is only related to the way the "not" condition is handled in Target Filters in association with logical operator (I mean the math behind). For instance when you select "Not attacking me" condition, but it is valid with any "Not" condition selected in the Target filters. The "main" INVERT in condition node is working fine though.
I think there is a medium/high level misconception on it, and this is what is creating issues and/or confusions. I've seen several others threads where the main reason of the issue or confusion come from this misconception, remember or try to make a node with "not attacking me" and "not attacking an ally" ticked at the same time. That's why I consider this as a "bug" even if it is not really a coding bug but because it's related to the core Boolean system of the game. The final goal of this topic is to remove the possibilities of having confusion or misunderstanding with the "Not" operator in the Target Filters. It will require a game update.
Basically it comes from the fact that the game is based on the Boolean algebra for the condition and action system but there is a weakness, the "not" logical operator for "Target filters" is not implemented at the right "level" of Boolean variables. The "level" notion will be explained after, but if you know a bit about Boolean algebra, you may already understood what I mean. You can see the Wikipedia page for more detail on the Boolean algebra, but I will explain the minimum required for everyone to have a thought.
So here is my understanding of how the game mechanics works :
- Condition node are used to create a node that based on a target type and Target filters will activate or desactivate if the conditions are fulfilled. You can invert the final result if you want. Yes it is basic and obvious but it is to make the whole screenshot.
- Action node are used to make action based on an "action type"(Configure action), an Action selector and Target filters to select the target you want to make an action to. You can't invert the final result (but you still can invert some "sub-result").
- We make Branches from Root node of AI or SubAI using conditions and finally always end up by an action. There is only one action at the end of a Branch, starting from root node and going down to one of the action in the AI. The "left to right" priority is part of this "branch selection" that's why you have only one action at the end. The last portion of the Branch from the last condition to the action is part of the Branch.
- In both of them, this is the same Target filters selection system. The filters selection system propose only the possible choice so this mean for instance that you will not be able to select any "Target current action" if the selected target is an object. This is because there is some "Exclusive" values (this is explained in the Minimum Requirement below)
Ok now it come the "tricky" explanation :
[Minimum Requirement - Boolean algebra]
Let say we have a and b to different Boolean value (variable in term of math). Boolean value mean that each can be only 0 or 1.
In term of Boolean algebra, the symbol + mean "OR" so :
a+b=0 if a=0 and b=0
a+b=1 if a=1 or b=1
Note that if a and b are both equal to 1, a+b=1 (not 2) because we are talking about Boolean variable and so this is only 0 or 1.("False" or "True")
Again, in term of Boolean algebra, the dot "." mean "AND" so :
a.b=0 if a=0 or b=0
a.b=1 if a=1 and b=1
Now the negation.
I can't make the real typo (french typo) of the negation since I would need to put a line on top of the a or b or a+b etc... but I will instead underline it.
So we can have for instance a which is the inverse of a , a+b opposite of a+b etc...
Note that a+b is not same as a+b !
a+b is the opposite of the whole "a+b" (so [inverse of (a or b)]) Boolean value while a+b mean [(inverse of a) or (inverse of b)]
Now here is the way the Boolean algebra work when you "play" with the negation "NOT" and the logic gate "AND" and "OR", this is called "De Morgan's law":
See the french wikipedia for "Algèbre de Boole (logique)" if needed to better understand this, this is the part 2.4.4 "Théorème de De Morgan" and it is way more clear on the french page than on the english one...in fact the whole Typo of those equations are easier to read in the french wiki.
The important thing to note here, is that the result of such kind of operation is 1 or 0 only when both a and b are 1 or 0 at the same time so :
a+b=1 only if a= 0 and b=0
a.b=0 only if a= 1 and b=1
This is not the case for a+b or a.b or a+b or a.b etc...
Last thing is the "exclusive" or "non exclusive" value and that's all we need from boolean calculation to understand the concept.
Exclusive value mean that those value cannot be valid at the same time.
This mean that if a and b are exclusive value, if a=1 then b=0 and if b=1 then a=0.
But that does not mean on the other hand that if a=0, b=1 or if b=0, a=1. So in word, knowing that "a" is valid tell you for sure that "b" is invalid, but if you know that "a" is invalid, you cannot tell anything about the state of "b", and reversely.
This is quite complex to explain why but if you I take an example, it will be clearer.
Instance of non-exclusive value (2 distinct groups, not exhaustive):
Moving to Me
Fleeing from me
At short range from ally
At medium range from enemy
At long range from ressources
etc... they are non exclusive because they are related to specific action or behaviour or state which are not linked to each other or at least because they are related to several targets, where the targets can be several enemies or ally... so all can be valid at the same time.
Instance of exclusive value (2 distinct groups, not exhaustive):
At short range
At medium range
At long range
Out of range
I'm Fleeing from
I'm Moving to
etc... are exclusive because if one of those value are 1 in a group, all others are for sure 0. It is quite clear with the example, here we can even better understand why knowing that one value is 1 then others are for sure 0 but if you know that one value is 0, you still cannot tell if one of the others are 1.
Note that you can take 2 exclusives value from two distinct group of exclusives value (one in each group) and have then 2 non-exclusives value relative to each other. The "exclusive" behaviour is relative.
So in Boolean algebra (with a and b exclusive values):
if a=1, b=0
if b=1, a=0
this may looks quite tricky but:
if there are both 0, then a+b=0+0=1+1=1
if one on them is 1, then a+b=1+0 or 0+1 = 0+1 or 1+0 = 1
if bot are 1 at the same time....both cannot be 1 at the same time as they are exclusive value.
[End of Minimum Requirement]
All the game mechanics is based on the Branching of conditions and actions to form a Boolean function to reduce the overall possibilities to one by "open/close the logical gate" for condition and "select an action and make it" for action.
In terms of boolean algebra, we can describe the game mechanics this way :
-When we create a branch from the Root of the AI, we can describe the form of the Boolean function as :
Br= C1.C2.C3.ETC.A where Br represent the whole Boolean function of that Branch (from the root of this AI or SubAI to the active Action).
C1,C2,C3 and etc... represent all the Condition nodes in that Branch. "A" represent the first from left to right Action node active at the end of this Branch.
- There is no need to explain the way the first from left to right selection works but this is only "AND" gate with all exclusive value in terms of Boolean algebra. There is no "not" option here.
-Condition node is basically this form of Boolean function : C=X.Y.Z where X represent the Target type, Y the Target filters and Z the Configure action. So C1=X1.Y1.Z1 , C2=X2.Y2.Z2, Ci=Xi.Yi.Zi etc...
- Action node is in form of : A=B.C.D.Y where B represent the Action type ("Configure action"), C Action selector, D Target type and Y Target filters (so Y cause it's the same Target filters than in Condition).
So we have a two Boolean functions, one for condition and one for action. Now let's describe their components.
In this instance,the variable X used in the Condition node is the Target type "function" and can be described like this form : X = a.b.c.d.e.f.g.h.i.j.k, where all the a, b, c,etc... represent one of the choice you can make (Myself/ally/Enemy/Ressources/etc... there is 11 choices), and it is a Boolean operation like "a" or "b" etc.. is the result of "is it true it is Myself" or is it true it is a Ressource" etc...
Y Target filters will be explained at the end cause it is the toughest.
Z is in form of Z= a.b.c.d.etc... where a,b and so (not the same from X, those "a" "b" "c" etc... are local values) represent the result of a Boolean operation like "is it true it exist" or "is it true it does not exist" or "is it true it is more than 2" etc...
B is in form of B= a.b.c.d.etc... where a,b and so (never the same ) represent the result of an operation like "is it true I need to Move Forward" or "is it true I need to attack" etc...
C is in form of C= a.b.c.d.etc... where a,b and so represent the result of "is it true it must be weakest" or "is it true it must be closest to enemy base" etc...
D= a.b.c.d.etc... where a, b and so represent the result of "is it true it must be an enemy" or "is it true it must be a ressource" etc...
Note that in each, this is (and should be) "AND" gate logic and are all exclusive value.
Comes Y. Target FiltersY is in form of Y = A.B.C.D.ETC... where uppercase A, B and so represent each of Target filter selection possibilities. Still "AND" gate.
Each Target filter possibilities, like if A = "Distance from me" for instance, can be described as a function in form of A = a+b+c+d+etc... where a, b and so represent the result of "is it at short range" or "is it at medium range" or "is attacking me" etc...
Now there is two important thing to notice.
-One is that in Target Filters, the uppercase A,B,C etc... are all non-exclusive value. "Carrying a ressource" as no link at all with "moving to me" or "At short range from Ally" and it is the same for all those function compared to each other. They all can be valid or invalid at the same time. That mean that even if this is an "AND" function at this level, you can select several filters at the same time and have a final result representing a fine selection of several "characteristics" the target must have at the same time to make a choice. This is why it is there in the game we can make the most precise decision to choose the right target. I will even precise that this is why it is even more impacting the Action nodes since all the Boolean function construction is embedded in the Action nodes (this is always the last node of the Branch) while with Condition nodes, you still can make a branching with several nodes to make the right function without hurting the common sense.
-The second is that for the lowercase a,b and so this is not an "AND" gate but a "OR" gate. That's why you can select "at short" and "at medium range" and you will end up selecting all target at short or medium range. Of course.
The same logic applies for Condition and Action node, except there is one more Boolean variable in the Action node. So all "AND" gate except for Target filters possibilities.
In this case the final result of a Branch function is like :
Br = C.C2.C3.C4.ETC.A
Br = [X.Y.Z].[X2.Y2.Z2].C3.C4.ETC.A
This is a non-essential paragraph after I re-read the post. But I keep it for information
There is some "levels" in the Boolean value we are handling. This is part of the way the Branching of Condition and Action mechanics work and should work. This mean that Xi, Yi, Zi are evaluated separately before to make the last Boolean operation and evaluate the final result. And so this mean as well that "inside" the Y=A.B.C.D.ETC... function A, B and so are evaluated separately before the final result.
So the function can be written as Br = X.[A.B.[a+b+c+d+etc...].D.ETC].Z.C2.C3.A (I intentionally put the [ ] to remark that this is the result of the C function inside the result of the Y function).
Separately does not mean that there is no link between value , because there are sometimes "exclusive" value which mean that if a condition is valid, another condition cannot be valid at the same time, that how we are making selection trough the Branching, Condition and Action system, excluding possibilities.
So now begin the nightmare, where all the possible choices in "Target Types" or "Configuration filter" or "Action selector" are exclusive (like "attack closest enemy" mean as well that this is not "Fleeing From Enemy" and all others possible choice), the Targets filters use non exclusive values (uppercase A,B,C etc...) and exclusive value (lowercase a,b,c,etc...) that can be combined to form a fine selection with several condition valid at the same time.
The condition function let the ability to Reverse the final result of the function which is working fine as the game evaluate Ci and then return Ci, which mean it return Xi.Yi.Zi
The misconception is on the "level" the "NOT" function is implemented in the Target Filters especially because we are handling exclusive and non exclusive value. It is one level to low or at least it lack in one level.
Here is the explanation :
As explained Target Filters uses non-exclusives values at first and the result we are expecting is the result of Y= A.B.C.D.ETC...
Remember that A, B, C each represent one of the Target Filters like "Distance from me" or "Carrying a resource" or "Shield" etc... where each is like A = a+b+c+d+etc... with the "OR" gate instead of "AND" (and this is fine!) and where a,b or so represent "At short range" or "At longe range" or "0-25% shield" etc...
The problem is that the "NOT" level for each filter are not evaluated at the uppercase A or B or so but instead it is evaluated at each a,b,c,etc.. and for each A or B or C etc...
The results of this handling is if you select in a Filter 2 or more "option" with "not" ticked like "Not attacking me" and "Not Moving to me" at the same time or "Not at short range" and "Not a medium range" at the same time, you will end up with an always valid condition for that filter because inside the filter this is "OR" gate and they are exclusive value. Surely if it is "Attacking me" this mean as well as it is "Not Moving to me", the result of a+b which are exclusive value is always 1 (Demonstrated In the Minimum requirement of Boolean algebra).
So finally if you want to make this action, you have to select "as valid" all others actions than those you want to be invalid at the same time. In fact you are manually asking for the A, or B result.
The "not" function for filter should be on the A,B,C level, which mean that you add the possibility of inverting the "whole" result of "Distance from me" or "Ally Current Action" or so in the filter selector.
This mean that at the left or right of each Filter , you have one button only for each A,B,C("Distance from me") to make them "not" the result they should return which will restore the game mechanics from the Top level (Root) to low level (final condition or action result).
Now, we have a "hole in the racket" in french cause we lack the A,B,C "not" condition which induce the confusion, especially because they are not exclusive Boolean variable. The fact they are non exclusive, make the "not" function on this level more useful than in any other level as each variable, not exclusive, mean that you can tick or untick "not" on any Filter here without impacting any other filter.
In mose Filters ,it can even be put only this button instead of one for each a,b,c("At short range") level which is quite useless most of the time as they are exclusive value in most case (Filters like Tag case will be worked after).All you need is selecting the "valid action" instead. Yes this mean that "Not out of range" will no longer be "tickable" as a single, but this is where the confusion has grown because we can make and exclusion for one "option" here but not 2 at the same time, which is quite not intuitive.
If the Reverse button was one level up, you will still be able to make a reverse on one Option to exclude it (and then "choose" in fact all other "option") like "Not [Out of range]" for "[At short range or at medium range or at long range]". But you will be able as well to really exclude two options at the same time without having to select all others, all you need is to select several options and tick "not" for the whole, which is intuitive and especially useful with the "Target Current Action" filter where you have many options (all exclusive). Finally you will be able to select "Not [Attacking Me Or Attacking An Ally]" with a perfectly working result.
If we come back to the Boolean, remember that Y=A.B.C.D.ETC with A=a+b+c+d... or this is an "OR" gate and when you make a reverse on the "whole" A, you end up with A=a+b+c+d...=a.b.c.d... and this is how we should be able to "work".
Currently, we have this result if we select all "not" option A=a+b+c+d... which is not what we want as this result is always 1 as they are exclusive value at this level.That why we are currently forced to select manually the inverse, so all other options than those we wanted to exclude to make the right Boolean function
And so there is a last thing to "fix" to have it complete, the Tag Filters or rather all the "non exclusive filters" like Tag or Enemy action or Ally Action on target etc... those where we have an "AND" gate inside the filter instead of a "OR" gate in the Target Filters.
Where I did mention the form of Sub function of the Target Filter in the form of
Y= A.[a+b+c+...].C.D.ETC... and that the lowercase a,b,c inside the Y (Target Filter) function are in most case exclusive, in the Tags filters and all those with "AND" gates "at the end" there is two major differences.
First, this "AND" logic gate instead of "OR" logic gate. Those "AND" are the consequence of the Boolean's misconception in the Target Filters. At first it sounds good as we can select a target that is Tagged A and Tagged B at the same time. But, and this is where we have a real problem currently, we can't select in an Action node a Target that is Tagged A OR Tagged B. Why not?
Secondly, "those" a or b or so are not exclusive value. A Target can be Tagged A and B at the same time, or you can as well be Not Tagged A and Not Tagged B at the same time.
And this is what makes all the "power" of the suggested additional invert button at the "right" level in association with non exclusive values.
We first need to put the "OR" gate inside all the Filters with no exception.
Then we need to keep the button "not" for each non-exclusive value (this is useful here cause they are non-exclusive so the De Morgan's laws fully applies).
If we had the Invert Button at the Filters level and the "not" button on each Tag option, combining them we will be able to select :
"[Tagged A or Tagged B]" which is obvious, TRUE when Tagged either A or B.
"Not[Tagged A or Tagged B]".
Or "Not [Tagged A or Tagged B]" mean "[Not Tagged A] and [Not Tagged B]" the function to select a target that is Not Tagged A and B at the same time. So it will not select this target only if Tagged A and B at the same time.
"Not[Not Tagged A or Not Tagged B]"
Or this is equal to "[Tagged A and Tagged B]" 1 more obvious, only TRUE when Tagged A and B at the same time.
And the last "Not Tagged A or Not Tagged B" (which sounds like the main misconception consequences but it is not because they are non-exclusive value and so the result is not always 1 but can be 0 if the target is Tagged A and Tagged B at the same time),
So 0 if Tagged both A and B mean "Not[Tagged A and Tagged B]". This mean that it will not select this target only if it's not Tagged A and B at the same time.
In this way we have all the possibilities available in the Boolean algebra (proving that this is the right way to handle it) but I must admit that it is not really intuitive as it rely a lot on the De Morgan's law.
Instead, I have at least 3 suggestions, the second being probably the best:1- Or "splitting" Tag (or all using non-exclusive variable) filter into two distinct filter into the Target Filters .
We will then be able to choose between selecting several Tag into one Tag filter to make an "OR" gate (as we supposedly restored all "OR" gate inside filters), or select several Tag into two distinct Tag filter to make an "AND" gate.
We have to find a solution for make it clear why we make that though and distinguish the difference between the 2 rows. At this level, each row has his own "reverse" button for the whole row result as suggested.
2 - Or add inside the Tag Filter one more row for Tagged A,B,C... one row for "OR" gate and one row for "AND" gate. It is just needed to distinguish the two rows.It may be the most convenient way to achieve a clear, confusionless interface as their is no need for any "not" operator on the last low level of the target filters, allowing to make the perfect Boolean function and without cluttering the interface too much. Each row must have his own "reverse button" as well.
3 - The worst is to split Tag filters into one Filters with all A or B and so with an "OR" gate, and into several individual filters for each A, B, C and so. This would work as well because at this level,the operator is "AND" so we can make an "OR" selecting several Tag into the first Filter or the "AND" at the same level as other filters. And because we suppose we have the "not" operator at this level, you can do all the possibilities. But for sure this will Clutter the interface too much
All 3 solutions can get rid of the "last low level" NOT operator for any Filter. We choose the AND or OR gate "manually", and can even combine them, with or without reversing the whole result for each to achieve the right function without using the De Morgan's law. All solutions will be possible in a "direct intuitive solution".
And this is the end of this long thread... I hope everyone has at least understood the mechanics and hopefully the reason of the confusion. For sure I hope this approach will elucidate the debate and confusion by ending up with an update of the game that put an end dot to the subject
Have all a nice day/night.
PS : I probably broke the world record for the longest first post on a forum.This is weird the way having the feel that you have the solution to an issue make you super motivated to share this with the world oh yes I'm born to be an engineer
or this is because Gladiabots is an amazing game that I play occasionally since almost the first Alpha release, and now I come back to the game and it keep me awake late at night so much I want to play it. I could not resist to possibly make it better. So I did subscribe to the Forum to make this topic.
Such a complex Boolean function