Extending ThinkTrees instead of copying?

Started by bleedo, May 06, 2014, 01:22:12 PM

Previous topic - Next topic

bleedo

There might be something I'm missing, but I have the impression that in order to extend the humanoid thinktree, in particular for colonists, you have to copy the entire existing thinktree and reference the new one in an overridden pawn thingdef?
This will as far as I can understand make the last mod loaded "win" ownership of the thinktree.
Is there some other way to extend the trees so all mods could extend existing core behaviour?

pidggit

Instead of overwriting the Pawn ThingDef, you can just redefine the ThinkTreeDef and give it the same name. This doesn't get around the fact that other mods that redefine that ThinkTreeDef won't be compatible, but to accomplish that, it would be quite tricky. For example, I've redefined the HerbivoreHerd ThinkTree in my mod to replace the SelfDefense node with a HerdDefense node, so when one Muffalo is under attack, the herd will come to it's defense.

Because it's a Priority Tree, it'd be difficult to be able to specify the priority of my new ThinkNode compared to a ThinkNode from a mod that may not be coded yet.

So yes, as of right now, my mod and your Breeding mod would be incompatible. (Although your Muffalo ThinkTree would totally be worth more than mine as all mine does is have them defend themselves.)

bleedo

I've got a composite thinktree partially going.
I "derive" the original, and insert subnodes before given types.

For example:
<ThinkTreeDef Name="MyTree">
    <main>Humanoid</main>
    <subNodes>
        <li class="AI.MyCode, MyAssembly>
            <insertBefore>AI.CoreCode</insertBefore>
        </li>

It works, but everyone needs to use my class to be compatible.
Would be sweet if Tynan could bundle a class like that instead.

Of course I have to set the thinktree to MyTree on the humanoid race, but it's better than copying everything.

Another (better) option would be to end each thinktree with a "check next tree" class and making think tree references an array instead of a single one.

pidggit

Quote from: bleedo on May 08, 2014, 10:35:08 AM
<ThinkTreeDef Name="MyTree">
    <main>Humanoid</main>
    <subNodes>
        <li class="AI.MyCode, MyAssembly>
            <insertBefore>AI.CoreCode</insertBefore>
        </li>

I assume that it wouldn't work if you were to extend the ThinkTree you're redefining... I'd try it, but I'm at work right now.

e.g:

<ThinkTreeDef Name="Humanoid">
    <main>Humanoid</main>
    <subNodes>
        <li class="AI.MyCode, MyAssembly>
            <insertBefore>AI.CoreCode</insertBefore>
        </li>



That just seems like it would go into Endless recursion. If that would work though, then you could just inject yourself into the existing definition of the Humanoid ThinkTree. Then as long as everyone else mods the ThinkTree in that manner, everyone's ThinkNodes would be injected into one combination ThinkTree.

bleedo

I forgot to mention i have class=mycompositetree to the root. I wrote a custom thinktree class that unions the existing with the inserted. I'll post it another day, but it's still a hack I'd rather avoid.

pidggit

Ah, I see.

Either way, having that functionality would be incredibly useful, and that's a cool solution to the problem. I like it. We'd just need Tynan to adopt that kind of behaviour in the standard ThinkTree class so we can both have our mods play nicely together.

Tynan

Good idea. I may be able to implement it for A5.
Tynan Sylvester - @TynanSylvester - Tynan's Blog


Tynan

I've just done this, but in a different way.

I put some "insertion hooks" into the main game's ThinkTreeDefs. If you want to insert a think node at a specific point, just define it and give it a matching insertTag and it will be run at that point. Multiple modders can use the same insertTag and the game will order their contributions by the <priority> given.

Will be working in Alpha 5.
Tynan Sylvester - @TynanSylvester - Tynan's Blog

bleedo