Can someone please help me understand how the BehaviorTrees work?

chillbaka1

Chieftain
Joined
Nov 13, 2016
Messages
46
So for the last couple of weeks, I've been working on a mod to improve the AI. Ive had some success in a few areas, and the AI is taking more cities than it was before, and also (occasionaly) taking cities later in the game as well. Some changes ive made are balance changes, and others are more temporary "cheats" for the AI, at least until I can figure out how and where the behaviors are calculated.

Here are the changes ive successfuly made so far that have seemed to help.
-Got rid of the "cannot move and shoot" requirement for siege units. (in my play tests, catapults, bombards ect. are now shooting at units and cities more often, where before I had never seen a siege unit fire at anything)

-Got rid of the siege unit penalty against units. (I like to think of siege units more as "heavy artillery" that historically played significant roles in open field battles) The AI seems to build tons of catapults regardless, even if you set their values in operations to 0, so now they are at least using them.

-Got rid of the "ranged penalty against fortifications". This one is more of a cheat, but I do not know how to change or where to find individual unit AI behavior trees. The AI fires at cities with ranged units much more often than siege units (again, i think this is in a unit class behavior tree, which puts more self preservation on siege units for some reason) so for now it might as well be effective. This has greatly increased the amount of city captures.

-Played around with the operation team requirements, the minimum odds of success, and initial/ongoing strength advantages. This one is much harder to see any significant results. I would appreciate it if anyone could maybe explain the relationship between MinOddsSuccess and strength advantage. What constitutes "success" when sieging a city? Because in my observations while tweaking these values, melee and ranged units will attack the city walls and do almost no damage, while siege units just sit there.

-Decreased the combat strength buff from all walls. Seems like someone at firaxis forgot to do balance testing with walls and city combat strength compared to the strength of units in that area. Decreasing the strength has helped a little.

So here is where i need help. I have spent the last couple of weeks trying to figure out how the AI works and makes decisions in regards to BehaviorTrees, and how its subtrees, ShapeDefinitions, NodeDefinitions, NodeDataDefinitions, DataTypes, BehaviorTrees, BehaviorTreeNodes, and TreeData all work. NodeDefinitions gives descriptions to different actions and gives them NodeId's, but then those NodeId's are seemingly never used again, so why put them there? If they are used again, how can you tell the difference between the NodeId's in NodeDefinitions and BehaviorTreeNodes when trying to make sense of what is going on in TreeData? And finally, which one of these is actually used when the AI is going through a descision process?

Sorry if these questions sound dumb, but i really cant figure out how to make any significant changes, and I am just now getting into modding.

My goal is to create separate trees for each era. The problem i have seen is that the same "Siege City Assault" tree is used from the classical era all the way through the information era. Taking over cities is pretty smooth in the ancient era, then there is a nice transition to the operation for attacking walls when the city still only has about 25 combat strength. Then, the AI uses that same tree over and over again when the tactics required are drastically different. I think this is the reason why further into the game, we see AI's filling their borders with dozens of knights, and holding onto their classical era UU's and making them into armies, causing them to either never go to war or never take cities.
 
I started to look into this, but it's ridiculously obtuse. The relationships among the trees, nodes, and data are complex, and ill-suited for tables. If I were to continue the analysis, I'd probably consider writing a program that transforms the XML into an object graph that could be inspected using a debugger or graph visualization (e.g. D3.js).

That's a non-trivial amount of work, and it won't be worth the effort if the mod tools contain their own browser. Faced with this, I decided to work on easier experiments. If there's wider interest, however, I'll take another look at it.
 
Would you be willing to explain to me how to create one of these for the "siege city assault" tree, or at least point me in the right direction? I really just want to redesign this particular tree to get rid of, and tweak certain parts.

I want to get rid of, or at least make optional, the "siege city" requirement. Right now, ranged and siege units just sit there and get killed instead of firing at the city because the "attack city" node comes after the "siege city" one, which makes the units almost never fire because the concurent node reads false until the city is under siege.

I also want to make the tree continue once it starts originally. The problem right now it that if a catapult or a siege tower is destroyed during the operation, the operation team requirements are not met, which causes all units to just sit there and wait for another catapult to join the operation. (For the same reason explained above) This can take anywhere from 8-25 turns (assuming the reinforcement catapult doesn't die on the way) and in the meantime, the operation force just sits there and dies, creating the need for even MORE reinforcements. It's an endless cycle that really breaks the AI. I want them to keep recruiting reinforcements, but also ignore the requirements once the op starts.
 
That is far more than I can help you with--I haven't studied the trees enough to debug them. You might find some help by asking a contributor to the AI+ mod.

If I were to try to map out a single tree, I'd probably start by creating the tree structure from BehaviorTreeNodes. After that I'd list the data available to each node type from NodeDataDefinitions, and fill in defaults & tags from TreeData. I'm not sure where I'd go after that... it really depends on what the resulting object graph looks like.
 
Back
Top Bottom