Jump to content
Sign in to follow this  
wastedbro

Decision Tree Framework

Recommended Posts

Decision Tree Framework by wastedbro

 

Hello everyone,

While working on some very large scripts, I realized that the current accepted frameworks scale poorly with many tasks, and that I have to choose between cleanliness and efficiency. Due to this, I've been working on a new framework that I am writing about here.

Here is the Source, for Reference: https://github.com/WBScripts/Tree-Framework

Summary

So the decision tree framework is based on, well, The Decision Tree.

My framework uses this concept and implements a Binary Tree of Decisions and Actions. Both decisions and actions are Nodes. Nodes can have 2 children. Actions will have null children, and Decisions will have 2 children of either Decisions, or Actions. I know it sounds a little confusing, so let's talk about why we even need this.

 

Why not use the popular Node Framework?

The Node Framework is a great way to split up a large amount of code. However, there is a problem. Even though each node is a different class, they really aren't flexible. If we assume each node is completely independent and isolated, we must ensure it's an invalid node when another node is valid, which is a huge waste of resources. If we do not do this, we must ensure our nodes are checked in a specific order (or prioritized).

While prioritized nodes prevent wasteful duplicate checks, it still does not prevent all wasteful checks. And it certainly cannot be in-depth. For example, if you want a "Pick up birds nest" node and a "chop node", you must ensure both of their validation methods include "is in chopping area". That's wasteful, so putting them in the same node is the only option.

These problems are not a big deal in small scripts, but as the complexity grows, so do these problems.

 

Here's a visual comparison of the Frameworks in a Combat Script:

Node Framework

Ldh586TUQciqMrKhm11CNQ.png

 

As you can see, both of the first nodes include an Area Check. This is either solved by combining the Nodes or ensuring they always run in that order (and then you would be unable to re-use the nodes without including them all).

Also, let's say you start this script in the bank. It checks if it needs to eat. Why? We're in the bank. We could put the Banking Node first, but then we run the risk of the Eating Node not being fast enough once we start adding complexity. 

Oh, and let's say we want to add a Gear Upgrade feature. Well, how would we do that? Upgrading gear is really only done in the bank, so we could have two nodes that check a banking condition..... Well, that makes our valid() methods bloated and repetitive. So, I guess we just have to put them in the same node...

All of this can be solved with my framework.

 

 

Decision Tree Framework

x5Ss1L_lQIWiGRcqJya9Rw.png

 

As you can see, this framework is much different. It allows you to nest in logic. In this framework, our script will never even check the HP unless we meet a bunch of other conditions. Yet, we still have a direct path to the eating method, making it the number one priority where we can be attacked.

Now, if we want to add gear upgrading, we would simply add the nodes under the Banking part of the script. Now we can add functionality with touching our old code. This decreases regression bugs.

 

So how do I use this?

Well, let's show you how to create some Nodes.

Decision Node Example:

public class HasToBankNode extends DecisionNode
{
    @Override
    public boolean isValid()
    {
        return Banking.isBankScreenOpen() || Inventory.isFull();
    }
}

Important: Remember to include "extends DecisionNode"

Every Node has a "getValidNode()" Method. This method will check the "onValid" method and return the true node if it's valid. If not, it will return the false node.

 

Process Node Example:

public class BankNode extends ProcessNode
{
    @Override
    public String getStatus()
    {
        return "Banking";
    }

    @Override
    public void execute()
    {
        // Do bank stuff
    }
}

Decision Nodes must have these two methods to run.

 

How do we run these nodes?

Here's an example:

DecisionNode hasToBankNode = new HasToBankNode();

ProcessNode bankNode = new BankNode();

hasToBankNode.addOnTrueNode(bankNode);
hasToBankNode.addOnFalseNode([insert some other node]);

DecisionTree executionTree = new DecisionTree(hasToBankNode); // Create a tree from the root node

while(true)
{
    INode node = executionTree.getValidNode();
    if(node != null)
        node.execute();
}

That's it! You'll want to shorten this code once you have a lot of nodes, though.

All of the background stuff is handled for you! The "getValidNode()" method is recursive. It will go through the entire tree and pick the correct process node for you.

 

This framework has more features. I will try to write a tutorial for them soon.

 

Github Link: https://github.com/WBScripts/Tree-Framework

Edited by Fluffee
Wrong constructor on the DecisionTree creation.
  • Thanks 5

Share this post


Link to post
Share on other sites
37 minutes ago, HeyImJamie said:

May look to transferring to this. Is it limited to two process nodes per decision node or not? For example: a combat decision node could have a handleAntiban, shouldEat, attackNpc etc.

Would you just add another decision node like
inCombatArea - yes
isLowHP - no
shouldDoAntiban - no Attack or yes doAntiban
 

Share this post


Link to post
Share on other sites
4 hours ago, HeyImJamie said:

May look to transferring to this. Is it limited to two process nodes per decision node or not? For example: a combat decision node could have a handleAntiban, shouldEat, attackNpc etc.

A binary tree of decisions and actions is by definition only able choose between two different alternatives on each node.

Multiple decisions could be added in a hierarchical order. For example if you need to chose between 3 actions: "Chop down tree", "Perform anti-ban" and "Idle":

KcCfB1y.png

 

  • Like 2

Share this post


Link to post
Share on other sites
On 19.12.2017 at 1:37 AM, wastedbro said:

 

How do we run these nodes?

Here's an example:

DecisionNode hasToBankNode = new HasToBankNode();

ProcessNode bankNode = new BankNode();

hasToBankNode.addOnTrueNode(bankNode);
hasToBankNode.addOnFalseNode([insert some other node]);

DecisionTree executionTree = new DecisionTree(hasToBankNode); // Create a tree from the root node

while(true)
{
    INode node = executionTree.getValidNode();
    if(node != null)
        node.execute();
}

That's it! You'll want to shorten this code once you have a lot of nodes, though.

All of the background stuff is handled for you! The "getValidNode()" method is recursive. It will go through the entire tree and pick the correct process node for you.

 

 

Well thanks for your effort, but ... is this part of some main class or something?

it's a piece of code that should belong to somewhere, and I couldn't find it either on your github.

Share this post


Link to post
Share on other sites
Posted (edited)
1 hour ago, rstaiger said:

Well thanks for your effort, but ... is this part of some main class or something?

it's a piece of code that should belong to somewhere, and I couldn't find it either on your github.

It's an example that would go in your main class. It's hypothetical, and builds off the two classes also in the thread. They are non-functional examples, just to show you how the code works, so it's not actually IN anything. 

 

By the way, I have an update to this framework. It's now simpler. I will edit the main post and write a tutorial on it when I can.

 

Here is the link: https://github.com/WBScripts/DecisionTree-Framework

 

Basically, Process Node are now just classes that implement "Runnable". And DecisionNodes are a little simpler.

Edited by wastedbro
  • Like 1

Share this post


Link to post
Share on other sites
On 4.03.2018 at 4:58 PM, wastedbro said:

It's an example that would go in your main class. It's hypothetical, and builds off the two classes also in the thread. They are non-functional examples, just to show you how the code works, so it's not actually IN anything. 

 

By the way, I have an update to this framework. It's now simpler. I will edit the main post and write a tutorial on it when I can.

 

Here is the link: https://github.com/WBScripts/DecisionTree-Framework

 

Basically, Process Node are now just classes that implement "Runnable". And DecisionNodes are a little simpler.

can't really wrap my head around this, It would be nice to have some working examples I'll wait for some updates from you, I'll toy with the task framework till then.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Our picks

    • This release will:

      Add LG support for Runelite


      Fix NPCChat issues


      Fix a bug where the camera angle setter would just hold down a key for 5 seconds (the timeout)


      Slightly adjust the rotation via keys to be more accurate


      Add the ability for asynchronous camera movement via keys


      Make Camera rotation via mouse more fluid, with more antiban, and work much better in resizable mode


      Add a "Camera#setCamera" method, allowing the rotation and angle to be set in parallel


      Increase the likelihood of using the mouse for camera movements


      Add support for adjusting the camera to positionable entities (Positionable#adjustCameraTo)



      Upcoming updates:

      Improved CLI support


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
        • Thanks
        • Like
      • 36 replies
    • This update will:

      Allow for clicking through the chat box when possible (Thanks @Todd)


      Fix Combat#selectIndex (Thanks @Encoded)


      Ensure worlds stay sorted and added a check to avoid misclicks in the in-game world hopper (Thanks @erickho123)


      Fix out-dated Options API interface indices (Thanks @Todd)



      Upcoming updates:

      Break handler bug fix


      Improved CLI support


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
        • Like
      • 12 replies
    • This release will:

      Fix login bot after today's game update (Thanks @JoeDezzy1)


      Fix latest in-game world hopping issues (Thanks @erickho123)


      Compact Settings UI and set location relative to TRiBot (Thanks @JoeDezzy1)


      Fix an older implementation of GrandExchange#getWindowState (Thanks @JoeDezzy1)


      Improve the preformance of NPCChat by only searching in certain interface parents (Thanks @JoeDezzy1)



      Upcoming updates:

      Break handler bug fix


      Improved CLI support


      LG support for RuneLite


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
        • Thanks
        • Like
      • 16 replies
    • This release will:

      Fix bytecode manipulation in order to prevent the modification of parameters within the Filter and Condition classes themselves (thanks @wastedbro)


      Fix NPE caused by non-null value in GE API (thanks @erickho123)


      Add and fix equals methods for api2007.types (thanks @JoeDezzy1)


      Modify Mouse#leaveGame to make the mouse leave the game from top, left, right, or bottom (thanks @erickho123)


      Add Entrana area to Ships API (thanks @erickho123)


      Fix raid prayers index/settings in Prayer API (thanks @erickho123)



      Upcoming updates:

      Break handler bug fix


      Improved CLI support


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
        • Like
      • 29 replies
    • This update will:

      Implement better canvas locking/synchronization mechanism


      Fix small Login API bug


      Remove the requirement for xbooting Java classes


      Use ExecutorService to perform canvas work in parallel


      Add "Account Management" game tab to GameTab API (thanks @Encoded)


      Fix NPCChat#getMessage (thanks @Encoded )


      Fix NPCChat#selectOption (thanks @Encoded )


      Fix Banking API after today's update (thanks @Encoded )


      Fix in-game world hopper after today's update (thanks @Encoded )



      Upcoming updates:

      Break handler bug fix


      Improved CLI support


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
        • Thanks
        • Like
      • 38 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×