Jump to content

A Beginners Guide to Writing OSBot Scripts (where to get started!) by Apaec


Apaec

Recommended Posts

11 hours ago, Glaciation96 said:

Yes of course, seems so obvious now, I fixed that simply by just reducing sleep times lol. 

I've also noticed a couple things when testing my script and attempting some debugging. Whilst it is still listed in the API, completeDialogue no longer seems to work, or maybe it's unreliable? For example, when running the below snippet, the bot will only advance 'continue' dialogues, but do nothing when the options are presented. Any idea what's going on there? Could I be using it wrong?

  Hide contents


public final String[] CustomsOptions = { "Can I journey on this ship?", "Search away, I have nothing to hide.", "Ok." };

public void talkToOfficer() throws InterruptedException {
		Entity sailor = npcs.closest("Customs officer");
		if (sailor != null && !dialogues.inDialogue()) {
			if (sailor.interact("Talk to")) {
				new ConditionalSleep(9000, (int) (Math.random() * 436 + 247)) {
					@Override
					public boolean condition() throws InterruptedException {
						return getDialogues().inDialogue();
					}
				}.sleep();
			}
		} else {
			if (dialogues.completeDialogue("CustomsOptions")) {
				new ConditionalSleep(9000, (int) (Math.random() * 436 + 247)) {
					@Override
					public boolean condition() throws InterruptedException {
						return !getDialogues().inDialogue();
					}
				}.sleep();
			}
		} //etc..

 

 

 

What's more, the depositAllExcept function only works with ids now? But I've seen people use strings to accomplish this task! So why does my bot bank the coins and lobster pot along with the lobsters when depositing? Everything seems to be in place... Unless the examples/tutorials that I've seen have called upon outside classes that weren't shown to get it working.

  Hide contents


public final String[] Essentials = { "Coins", "Lobster pot" };

else if (this.depositBox.isOpen()) {
			this.depositBox.depositAllExcept("Essentials");
			new ConditionalSleep(9000, (int) (Math.random() * 248 + 127)) {
				@Override
				public boolean condition() throws InterruptedException {
					return inventory.isEmptyExcept("Essentials");
				}
			}.sleep();

 

 

 

I really appreciate the help. Hopefully other scrubs reading will benefit aswell.

Hey,

The mistake your making is that you are passing single strings to these method. Since there is nothing in your inventory with the exact name 'Essentials', the script will deposit everything!

The same can be said for the complete dialogue method input.

It is also worth noting that these methods take var args so you can define the exceptions in place if you prefer, e.g:

// ...
return inventory.isEmptyExcept("Lobster pot", "Coins");
// ...

-Apa

  • Like 1
Link to comment
Share on other sites

Couple of questions..

 

1: I was already learning bit of c# and so this made a lot of sense to me; is it worth it to try to learn java separately or is it ok if I just know the basics from c#?

(for reference, was using this to learn, got to lesson 12 https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169?l=vE6GqMQIC_506218949)

2: Can you use visual studio?

3: How does the api work? Do you import the parts of the api you need, and then just use it like a method?

4: Is there a scripting discord or something where I could quickly show someone my code and they could see whats wrong with it?

 

Will prob have more questions, this seems easy enough to get into ?

 

Edited by Dark798
Link to comment
Share on other sites

9 hours ago, Dark798 said:

Couple of questions..

 

1: I was already learning bit of c# and so this made a lot of sense to me; is it worth it to try to learn java separately or is it ok if I just know the basics from c#?

(for reference, was using this to learn, got to lesson 12 https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169?l=vE6GqMQIC_506218949)

2: Can you use visual studio?

3: How does the api work? Do you import the parts of the api you need, and then just use it like a method?

4: Is there a scripting discord or something where I could quickly show someone my code and they could see whats wrong with it?

 

Will prob have more questions, this seems easy enough to get into ?

 

Hey

  1. The object oriented concepts from C# apply with Java, so you can totally learn by trying
  2. You can use whatever you want, but I've herd terrible things about visual studio. Much better would be Eclipse or IntelliJ Idea, or a more general editor like Atom, VSCode  or Notepad++(I like VSCode)
  3. Once you've linked the OSBot jar, yep
  4. There's probably a scripting discord but I don't know of it. You can always ask questions in the chatbox, I know lots of scripters hang out there :)

GL

Apa

Link to comment
Share on other sites

Hello apa,

Got a problem again, this is a tricky one. It's not so much to do with my script breaking, but more like a feature that I'm having trouble adding. In my fishing script, I want the player to pick up any dropped fish whilst fishing, then to go back to fishing when there are no fish left to pick up. I'm using a while loop to check this, but after all the fish has been picked up, my script just can't break out the loop, so it gets stuck. Shouldn't the null checking returning false break me out of the while loop? Because there is no fish on the ground! I also thought about using isVisible but I Don't think that would work either... I've tried using a normal if statement but then that only picks up one fish, then pauses forever. I'm using a switch statement approach to this bot. I'm going to share a snippet so you can see what's going on.

If it doesn't require a complete design change, could you give me some help here if it's just some tweaking that's needed? Thanks! 

Also, I would have thought a way to solve this is to be able to check if something doesn't exist. Seeing as there isn't a method for that, there's a completely different approach to get this working?

Spoiler

int animFishing = 619;
int pickup = 0;

// ========== During the fishing animation, we do...
	private void pickupFish() throws InterruptedException {
		log("Attempting to check if fish exists.");
		GroundItem freeFish = getGroundItems().closest("Raw lobster", "Raw swordfish");
		while (freeFish != null && !this.inventory.isFull()) {
			log("Fish exists, proceeding to pick up...");
			int lastCount = getInventory().getEmptySlots();
			if (getMap().canReach(freeFish)) {
				pickup = 1;
				log("pickup(should be 1) = " + pickup);
				freeFish.interact("Take");
				new ConditionalSleep(1500, (int) (Math.random() * 500 + 250)) {
					@Override
					public boolean condition() throws InterruptedException {
						return getInventory().getEmptySlots() < lastCount;
					}
				}.sleep();
			}
		}
		pickup = 0;
		log("pickup(should be 0) = " + pickup);
	}

//The getState stuff...
else if (KaramFishingSpot.contains(this.myPlayer()) && this.myPlayer().getAnimation() == -1
			&& !this.inventory.isFull() && !myPlayer().isMoving() && pickup == 0) {
			log("We are doing nothing. Time to fish");
			return BotState.letsFishCase;
else if (animFishing == this.myPlayer().getAnimation()) {
			return BotState.pickupFishCase;

 

 

 

EDIT: While looping freeFish.exists() && freeFish.isVisible() doesn't work either, after null checking :/

Edited by Glaciation96
Link to comment
Share on other sites

15 minutes ago, Glaciation96 said:

Hello apa,

Got a problem again, this is a tricky one. It's not so much to do with my script breaking, but more like a feature that I'm having trouble adding. In my fishing script, I want the player to pick up any dropped fish whilst fishing, then to go back to fishing when there are no fish left to pick up. I'm using a while loop to check this, but after all the fish has been picked up, my script just can't break out the loop, so it gets stuck. Shouldn't the null checking returning false break me out of the while loop? Because there is no fish on the ground! I also thought about using isVisible but I Don't think that would work either... I've tried using a normal if statement but then that only picks up one fish, then pauses forever. I'm using a switch statement approach to this bot. I'm going to share a snippet so you can see what's going on.

If it doesn't require a complete design change, could you give me some help here if it's just some tweaking that's needed? Thanks! 

Also, I would have thought a way to solve this is to be able to check if something doesn't exist. Seeing as there isn't a method for that, there's a completely different approach to get this working?

  Reveal hidden contents


int animFishing = 619;
int pickup = 0;

// ========== During the fishing animation, we do...
	private void pickupFish() throws InterruptedException {
		log("Attempting to check if fish exists.");
		GroundItem freeFish = getGroundItems().closest("Raw lobster", "Raw swordfish");
		while (freeFish != null && !this.inventory.isFull()) {
			log("Fish exists, proceeding to pick up...");
			int lastCount = getInventory().getEmptySlots();
			if (getMap().canReach(freeFish)) {
				pickup = 1;
				log("pickup(should be 1) = " + pickup);
				freeFish.interact("Take");
				new ConditionalSleep(1500, (int) (Math.random() * 500 + 250)) {
					@Override
					public boolean condition() throws InterruptedException {
						return getInventory().getEmptySlots() < lastCount;
					}
				}.sleep();
			}
		}
		pickup = 0;
		log("pickup(should be 0) = " + pickup);
	}

//The getState stuff...
else if (KaramFishingSpot.contains(this.myPlayer()) && this.myPlayer().getAnimation() == -1
			&& !this.inventory.isFull() && !myPlayer().isMoving() && pickup == 0) {
			log("We are doing nothing. Time to fish");
			return BotState.letsFishCase;
else if (animFishing == this.myPlayer().getAnimation()) {
			return BotState.pickupFishCase;

 

 

 

Avoid while loops when writing scripts for OSBot, since this is a live game, getting stuck will happen often. The reason the null check doesn't break out of the loop is because you're null checking a variable after you assign it. The variable will never go back to null on its own, unless you change it! (This is fairly basic java, be sure to revisit a tutorial on variables and variable assignment if you feel you need to :) )

I'd strongly suggest a restructure so you rely on the continuously looping nature of the onLoop method rather than having your own sub-loops and sacrificing game state awareness. However if you really wanted to update your current code to do what you expect, think about re-defining your freeFish variable from within your loop.

GL!

Apa

Link to comment
Share on other sites

Ah crap, I was under the impression that the while loop will just keep null checking with each loop lol, then break me out when there is no fish so it returns false. Also, freeFish is just set to focus on picking up raw lobsters and swordfish. Wouldn't re-defining that just result in me wanting to pick up other items?

You're right about the restructure, I'm just struggling to see how it would work when it comes to something like picking up fish as soon as some appear on the ground. Looping through the whole script just to check if there are some fish to pick up, then going back to fishing and banking as normal seems like a more difficult approach which is why I probably went off on a weird one with sub-loops. I'll play around with it. Thanks again. 

Link to comment
Share on other sites

50 minutes ago, Glaciation96 said:

Ah crap, I was under the impression that the while loop will just keep null checking with each loop lol, then break me out when there is no fish so it returns false. Also, freeFish is just set to focus on picking up raw lobsters and swordfish. Wouldn't re-defining that just result in me wanting to pick up other items?

You're right about the restructure, I'm just struggling to see how it would work when it comes to something like picking up fish as soon as some appear on the ground. Looping through the whole script just to check if there are some fish to pick up, then going back to fishing and banking as normal seems like a more difficult approach which is why I probably went off on a weird one with sub-loops. I'll play around with it. Thanks again. 

Apologies, maybe I phrased my first reply a little ambiguously.. You're right in that the while loop will re-check if freeFish is null with each iteration, but my point was that freeFish will never go to null, because you initialise it but never update its value. This is the same reason that the following code will be stuck in a permanent loop:

int aNumber = 5;
while (aNumber != 0) {
  system.out.println("aNumber is still not 0!");
}

In the second part of your reply, you seem to hint that looping through the whole script just to check if there are some fish to pick up is a bad thing, when in reality, that is exactly the situation we want to be in. Regularly checking the game state and acting on it is the best way to make a responsive and reliable script, and the best way to achieve this is to have onLoop being called very frequently, with all game interaction being non-blocking.

It's hard to explain but it comes with practice: keep at it and your understanding will grow :)

You're doing great so far

-Apa

  • Like 1
Link to comment
Share on other sites

Ahhh.. That actually cleared up a lot of my confusion. Truth be told, seems like going for a switch/case approach for scripts isn't a great idea then, as it seems as though the onLoop never gets called that way. It's pretty much just my getState doing everything. I'll try not to rely too much on that! 

And thanks! Any signs of improvement are my motivators lol

  • Like 1
Link to comment
Share on other sites

I'm confused on using the api. I understand that I can use it after importing it, but I don't know specifically how to use all of it. I don't know what the conductor and the method summary and all that mean.

Also, the red underlined error messages aren't very helpful, is there a guide that clearly says what each error means?

 

	public int onLoop() throws InterruptedException {
		if(getInventory().contains("Bones")); {
			getInventory().interact("Bury", "Bones");
		}
		
		else if (RS2Object cowbones = getObjects().closest("Bones"));
		if (cowbones != null) {
			  cowbones.interact("Pick up");
		}
		return random(2000, 3000);

Pretty excited cause I got it to bury the bones, but then I'm getting errors when making the rS2object var

Edited by Dark798
Link to comment
Share on other sites

8 hours ago, Dark798 said:

I'm confused on using the api. I understand that I can use it after importing it, but I don't know specifically how to use all of it. I don't know what the conductor and the method summary and all that mean.

Also, the red underlined error messages aren't very helpful, is there a guide that clearly says what each error means?

 


	public int onLoop() throws InterruptedException {
		if(getInventory().contains("Bones")); {
			getInventory().interact("Bury", "Bones");
		}
		
		else if (RS2Object cowbones = getObjects().closest("Bones"));
		if (cowbones != null) {
			  cowbones.interact("Pick up");
		}
		return random(2000, 3000);

Pretty excited cause I got it to bury the bones, but then I'm getting errors when making the rS2object var

It would be easier to properly understand the API with a good understanding of Java. That being said, you don't need to understand it to use it :) 

Your code is quite odd - it certainly isn't doing what you think that it is doing. It might be worth visiting some very basic java tutorials to get a feel for variables and conditionals before working further on this :)

-Apa

Link to comment
Share on other sites

7 minutes ago, Malcolm_OS said:

@Dark798 I would just delete the “if” in your “else if” statement. You’re just trying to declare what the bones are, that doesn’t need an if statement. So basically if you delete the if in your else if statement it should bury the bones and then if you have no bones in your inventory (else) then it will declare your bones on the ground and go pick them up. But this code will bury that bones right away and won’t gather a full inventory and then bury them  

 

 

The bone burying works. And that part looks okay. If inventory contains bones, bury them , else blah blah.

edit. My mistake. The other “if” else if, if. Part.

the bones just aren’t rs2objects they are ground items. Also consider &&getMap.canReach so you aren’t spamming bones that are on the other side of the fence.

Edited by sonda
Link to comment
Share on other sites

For the bones pickup phase, just to give my 2 cents, this is how I would do it, personally. It's not been tested yet, but hope it helps.

else {
			GroundItem cowBones = getGroundItems().closest("Bones");
			if (cowBones != null && !this.inventory.isFull()) {
				int lastCount = getInventory().getEmptySlots();
				if (getMap().canReach(cowBones) && cowBones.interact("Take")) {
					new ConditionalSleep(1500, (int) (Math.random() * 500 + 250)) {
						@Override
						public boolean condition() throws InterruptedException {
							return getInventory().getEmptySlots() < lastCount;
						}
					}.sleep();
				}
			}
		}

 

Link to comment
Share on other sites

Alright boys, I messed around with the script and managed to make it pick up bones and then bury them!

Next I tried to have the bot check if you are in the cow pens on start, and walk there if you aren't, and then sleep for 20 seconds to give you time to walk there. Was looking at explv's guide but still having problems with it.

	public void onStart(){
		Position playerspot = myPosition();
		Area pen = new Area(3253, 3255, 3264, 3279);
		if (!pen.contains(playerspot()))
			getWalking().webWalk(pen);
		
		sleep(20000);
			
		
		log("Let's get started!");
		
	}

 

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...