Jump to content

What style of script is best for new script writers?


Chris

Recommended Posts

If you wan't to keep your sanity for as long as possible I recommend going with the Enum/State skeleton/style
Example:

public class Enum extends Script {

    boolean dropping = false;

    private enum State{
        DROP, CHOP
    }

    @Override
    public int onLoop() throws InterruptedException {
        switch(getState()){
            case DROP:
                drop();
                break;
            case CHOP:
                chop();
                break;
        }
        return random(100, 250);
    }


    private void drop(){
        //do dropping stuff
    }

    private void chop(){
        //do chopping stuff
    }

    State getState(){
        if(inventory.isFull() || dropping){
            return State.DROP;
        }else{
            return State.CHOP;
        }
    }
}

Sure it has more base framework than the Logic loop style 

public class LogicLoop extends Script {
    boolean dropping = false;

    @Override
    public int onLoop() throws InterruptedException {
        if(inventory.isFull() || dropping){
            //do dropping stuff
        }else{
            //do chopping stuff
        }
        return random(100,250);
    }

}

But depending on the length/complexity of your script the logic loop method can get quite messy and the Enum/State method retains neatness and easy readability.

  • Like 1
Link to comment
Share on other sites

If you wan't to keep your sanity for as long as possible I recommend going with the Enum/State skeleton/style

Example:

public class Enum extends Script {

    boolean dropping = false;

    private enum State{
        DROP, CHOP
    }

    @Override
    public int onLoop() throws InterruptedException {
        switch(getState()){
            case DROP:
                drop();
                break;
            case CHOP:
                chop();
                break;
        }
        return random(100, 250);
    }


    private void drop(){
        //do dropping stuff
    }

    private void chop(){
        //do chopping stuff
    }

    State getState(){
        if(inventory.isFull() || dropping){
            return State.DROP;
        }else{
            return State.CHOP;
        }
    }
}

Sure it has more base framework than the Logic loop style 

public class LogicLoop extends Script {
    boolean dropping = false;

    @Override
    public int onLoop() throws InterruptedException {
        if(inventory.isFull() || dropping){
            //do dropping stuff
        }else{
            //do chopping stuff
        }
        return random(100,250);
    }

}

But depending on the length/complexity of your script the logic loop method can get quite messy and the Enum/State method retains neatness and easy readability.

Yeah i started with the logic loop style but might switch to the state method

Link to comment
Share on other sites

import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

import java.awt.*;

@ScriptManifest(author = "Sinatra", info = "The best bot ever", name = "SPOCKET", version = 1.0, logo = "")
public class Spocket extends Script {
    public void onStart() {

    }
    private enum State{
        STEAL,DROP
    }
    State getState() {
        if (inventory.contains("Cup of tea")) {
            return State.DROP;
        }
        return State.STEAL;
    }
    private void Thieve(){
        Entity T_STALL = objects.closest("Tea stall");
        if (T_STALL != null && (!myPlayer().isAnimating())){
            T_STALL.interact("Steal-from");
        }

    }
    private void drop(){
        log("Dropping shit tea");
        inventory.drop("Cup of tea");
    }

    @Override
    public int onLoop() throws InterruptedException {
        switch(getState()){
            case STEAL:
               Thieve();
                sleep(random(300,600));
                break;
            case DROP:
                drop();
                sleep(random(300,600));
                break;
        }
        return random(100, 250);

   }

    @Override
    public void onExit() {

    }

    @Override
    public void onPaint(Graphics2D g) {

    }

}

 

Steal 1 Drop 1 Is more efficient.

This might never steal tea because it looks like you put all the stuff in !Area contains so when you're in that area nothing'll happen.

Deciding to fix it just for the tea stall :P

Link to comment
Share on other sites

First, I'd like to say that you shouldn't decide that a coding style is good for beginners soley due to the fact that it uses primitive coding techniques (which programmers tend to learn at an early stage).

 

Code which requires to to focus on only one thing, rather than changing 3 different things to implement what you want, is good code for a beginner. 

 

To give you options, there's another way of handling the states, which I find to be a lot cleaner:
 

class MyScript extends Script {
    public int onLoop() {
        for(State state : State.values())
            if(state.canProcess(this))
                state.process(this);
    }

    enum State {
        DROP {
            boolean canProcess(MyScript script) {
                return script.inventory.contains(...);
            }

            void process(MyScript script) {
                script.inventory.drop(...);
            }
        },
      
        STEAL {
            boolean canProcess(MyScript script) {
                //...
            }

            void process(MyScript script) {
                //...
            }
        };

        abstract void process(MyScript script);
        abstract void canProcess(MyScript script);
    }
}

I understand a few people aren't syntax savvy, and would love to point and yell at my code. Please read below first..

In the functional style code (creating getState() method and what not), there's quite some room to mess up.

1. Forget to specify the state condition in getState()
2. Forget to account for the state in onLoop
3. Forget to call the behavioral methods in onLoop
4. Forgetting break statements

With this new, object oriented way, you no longer need to worry about the onLoop method (once you have created it, that is); it will not change, so you won't forget to account for states.

To create a new state, you simply create a new enum value (with a body to declare methods). Each enum value is forced to declare a conditional method and a behavioral method, so the user will not forget to account for those.

Rather than being required to focus on onLoop() and getState(), all you need to do (literally) is define your state. Adding states is easy as pie.

Edited by fixthissite
Link to comment
Share on other sites

First, I'd like to say that you shouldn't decide that a coding style is good for beginners soley due to the fact that it uses primitive coding techniques (which programmers tend to learn at an early stage).

 

Code which requires to to focus on only one thing, rather than changing 3 different things to implement what you want, is good code for a beginner. 

 

To give you options, there's another way of handling the states, which I find to be a lot cleaner:

 

class MyScript extends Script {
    public int onLoop() {
        for(State state : State.values())
            if(state.canProcess(this))
                state.process(this);
    }

    enum State {
        DROP {
            boolean canProcess(MyScript script) {
                return script.inventory.contains(...);
            }

            void process(MyScript script) {
                script.inventory.drop(...);
            }
        },
      
        STEAL {
            boolean canProcess(MyScript script) {
                //...
            }

            void process(MyScript script) {
                //...
            }
        };

        abstract void process(MyScript script);
        abstract void canProcess(MyScript script);
    }
}

I understand a few people aren't syntax savvy, and would love to point and yell at my code. Please read below first..

In the functional style code (creating getState() method and what not), there's quite some room to mess up.

1. Forget to specify the state condition in getState()

2. Forget to account for the state in onLoop

3. Forget to call the behavioral methods in onLoop

4. Forgetting break statements

With this new, object oriented way, you no longer need to worry about the onLoop method (once you have created it, that is); it will not change, so you won't forget to account for states.

To create a new state, you simply create a new enum value (with a body to declare methods). Each enum value is forced to declare a conditional method and a behavioral method, so the user will not forget to account for those.

Rather than being required to focus on onLoop() and getState(), all you need to do (literally) is define your state. Adding states is easy as pie.

 

but with the way you're doing it, the getState() process can get hard to follow in bigger scripts. I prefer to do it like this:

	// // // // // // // THE DECISIONS // // // // // // //
	public enum State {
		TAKE_TEA, WAIT, STOP;
	}

	// // // // // // // THE DECISION MAKER // // // // // // //
	public State getState() {
		if (atTeaStall) {
			return State.TAKE_TEA;
		}
		if (!atTeaStall) {
			return State.STOP;
		}
		return State.WAIT;
	}

	// // // // // // // THE EXECUTIONER // // // // // // //
	public int onLoop() throws InterruptedException {
		switch (getState()) {
		case TAKE_TEA:
			paintState = "Take tea";
			takeTea();
			break;
		case STOP:
			paint_state = "Stopping Script";
			stop();
			break;
		case WAIT:
			paint_state = "Waiting";
			idle();
			break;
		}
		return 73;
	}

	// // // // // // // THE BRAIN // // // // // // //
	public void takeTea() {
		// take the tea!
	}
	
	public boolean atTeaStall() {
		return teaArea.contains(myPlayer());
	}

I don't find this way tedious at all. I can see everything and the only thing that looks different from script to script is the getState()

 

Link to comment
Share on other sites

but with the way you're doing it, the getState() process can get hard to follow in bigger scripts. I prefer to do it like this:

	// // // // // // // THE DECISIONS // // // // // // //
	public enum State {
		TAKE_TEA, WAIT, STOP;
	}

	// // // // // // // THE DECISION MAKER // // // // // // //
	public State getState() {
		if (atTeaStall) {
			return State.TAKE_TEA;
		}
		if (!atTeaStall) {
			return State.STOP;
		}
		return State.WAIT;
	}

	// // // // // // // THE EXECUTIONER // // // // // // //
	public int onLoop() throws InterruptedException {
		switch (getState()) {
		case TAKE_TEA:
			paintState = "Take tea";
			takeTea();
			break;
		case STOP:
			paint_state = "Stopping Script";
			stop();
			break;
		case WAIT:
			paint_state = "Waiting";
			idle();
			break;
		}
		return 73;
	}

	// // // // // // // THE BRAIN // // // // // // //
	public void takeTea() {
		// take the tea!
	}
	
	public boolean atTeaStall() {
		return teaArea.contains(myPlayer());
	}

I don't find this way tedious at all. I can see everything and the only thing that looks different from script to script is the getState()

 

I understand why you prefer it that way, especially seeing how you're already a scripter (probably familiar with that style). But for a beginner scripter, or even a beginner programmer, it could be quite easy to forget to add a condition to getState() or possibly forget to call the "brain" methods (I call em behavioral methods) in the onLoop.

 

The style I proposed doesn't require the scripter to focus on 4 sections independently (the decisions, the decision makers, the executor and the brain). After setting up the onLoop method, they are forced to implement everything that's needed (decision, decision maker, the brain) as soon as they create a new decision.

 

It's nearly impossible to forget to add a condition with this style, since everytime you create a new decision, a compilation error occurs if you forget to create the "decision maker" or the "brain" for a decision. In the functional style, if you were to forget something, you wouldn't realize you accidentally left something out until after you've ran the script. Compilation errors are always preferred to runtime errors, since they inform you of a problem right away.

 

As the script grows in size, there's more potential to mess up if the code doesn't enfornce such rules (every state must have a condition and behavior)

Edited by fixthissite
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...