Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

OmniAPI - A super simple API that handles most things for you

Featured Replies

Another reason I wrote this API is easier cross-bot compatibility. Means I rewrite less code, and therefore I have the same code base in case a bug breaks out.

Within this context, a null is not good. A null means that code that should work perfectly fine will not work. A null means additional checking on the users end, which can cause more problems if they forget. In my case, I pass a omniapi.data.DefaultNPC instance, which simply extends omniapi.data.NPC and is constructed to, simply, not exist. This means there is no NPE when trying to interact (my above post), but it still actually represents nothing. A new scripter is going to try the exact code I highlighted in my above post, realise it doesn't work, and panic because they wrote incorrect code (that is actually correct). I personally don't believe that the API should ever return null, especially in contexts like this.

 

Lastly, I wrote this API as this is personally what I believe the OSBot API should be like.

 

cross-bot? HERESY. BURN HIMMM

Alright, here is a reasonable example of why you want to have control:
 

Monster X is found in two regions, Region A and Region B.

 

NPC monsterX = getNPCs().closest("Monster X");

if(monsterX != null)
monsterX.interact("Attack");

else if (regionB.contains(myPlayer())
walk(new Path(regionA))

 

Not using null checks:
getNPCs().closest("Monster X").interact("Attack"); //Does nothing, doesn't go to a different region

Not using null checks with region switching:
NPC monsterX = getNPCs().closest("Monster X");

if(!monsterX.getPosition.equals(new Position(-1, -1, 0)) //See where I'm going with this?
monsterX.interact("Attack")
else if (regionB.contains(myPlayer())

walk(new Path(regionA));

 

You could do some hard spaghetti crap and make booleans for new NPC instances, but that's a hundred times worse than returning null. It's totally fine for scripters to do this because you guys know exactly what to expect from the behavior of your script. From our standpoint, this would be a nightmare.

 

Alright, here is a reasonable example of why you want to have control:

Monster X is found in two regions, Region A and Region B.

NPC monsterX = getNPCs().closest("Monster X");

if(monsterX != null)

monsterX.interact("Attack");

else if (regionB.contains(myPlayer())

walk(new Path(regionA))

Not using null checks:

getNPCs().closest("Monster X").interact("Attack"); //Does nothing, doesn't go to a different region

Not using null checks with region switching:

NPC monsterX = getNPCs().closest("Monster X");

if(!monsterX.getPosition.equals(new Position(-1, -1, 0)) //See where I'm going with this?

monsterX.interact("Attack")

else if (regionB.contains(myPlayer())

walk(new Path(regionA));

You could do some hard spaghetti crap and make booleans for new NPC instances, but that's a hundred times worse than returning null. It's totally fine for scripters to do this because you guys know exactly what to expect from the behavior of your script. From our standpoint, this would be a nightmare.

It should be optional. Check out my suggestion thread.

With a null object, you can still optionally check the reference. The point is it's common to "do nothing" if there is no object to work with, so you should not force the check. The branching should only occur if you want an else (like your example).

NPC npc = ...;

if(npc == NPC.NONE) {

//move

} else {

npc.interact(...);

}

The player might not want to go to a new location. There are times where you're waiting for something to spawn, which you don't want to do anything at that exact moment (such as waiting for a tree to spawn). It's common to "do nothing" if null occurs. You should not force this. There are seriously no downfalls. Null pointers were a mistake. Some languages only support it for compatibility with other languages.

Edited by fixthissite

It should be optional. Check out my suggestion thread.

With a null object, you can still optionally check the reference. The point is it's common to "do nothing" if there is no object to work with, so you should not force the check. The branching should only occur if you want an else (like your example).

NPC npc = ...;

if(npc == NPC.NONE) {

//move

} else {

npc.interact(...);

}

The player might not want to go to a new location. There are times where you're waiting for something to spawn, which you don't want to do anything at that exact moment (such as waiting for a tree to spawn). It's common to "do nothing" if null occurs.

 

Respect your opinion, but I don't agree with it.

You are then comparing two NPCs, which is more of an expensive check than null (not by very much). The only situation where I can see this being "alright" is sitting in a single area waiting for something with a fast respawn rate.

 

If you are sitting at KBD (long respawn), you could be doing other tasks (maybe some anti-ban crap). Above all this would break way too many scripts because you are talking about all entities that this would affect (widgets, ground items, inventory, objects, npcs, etc).

 

 

Respect your opinion, but I don't agree with it.

You are then comparing two NPCs, which is more of an expensive check than null (not by very much). The only situation where I can see this being "alright" is sitting in a single area waiting for something with a fast respawn rate.

If you are sitting at KBD (long respawn), you could be doing other tasks (maybe some anti-ban crap). Above all this would break way too many scripts because you are talking about all entities that this would affect (widgets, ground items, inventory, objects, npcs, etc).

That's micro-optimization and should be avoided. It is true that you COULD be doing other tasks, but you do not need to force it. Most scripters don't. There are situations where you would want to do nothing on null, and that's what the design is aiming for. Look through scripts, and I'm sure you'll see that most of the null checks are there primarily to avoid the NPE. I've seen scripters perform null checks when it isn't needed for the sake of "better safe than sorry".

Sleeping will slow the bot down. If a rock/npc appears while the bot is sleeping, someone else could snatch it. It's still possible to do so aswell. It's helping the situations that don't need to branch if a reference is null

Edited by fixthissite

  • Author

Alright, here is a reasonable example of why you want to have control:

 

Monster X is found in two regions, Region A and Region B.

 

NPC monsterX = getNPCs().closest("Monster X");

if(monsterX != null)

monsterX.interact("Attack");

else if (regionB.contains(myPlayer())

walk(new Path(regionA))

 

Not using null checks:

getNPCs().closest("Monster X").interact("Attack"); //Does nothing, doesn't go to a different region

Not using null checks with region switching:

NPC monsterX = getNPCs().closest("Monster X");

if(!monsterX.getPosition.equals(new Position(-1, -1, 0)) //See where I'm going with this?

monsterX.interact("Attack")

else if (regionB.contains(myPlayer())

walk(new Path(regionA));

 

You could do some hard spaghetti crap and make booleans for new NPC instances, but that's a hundred times worse than returning null. It's totally fine for scripters to do this because you guys know exactly what to expect from the behavior of your script. From our standpoint, this would be a nightmare.

if (regionB.contains(myPlayer()) walk(regionA);
else if (getNpcs().closest("Monster X").interact("Attack")) log("attacked");

would work fine as an alternative.

if (regionB.contains(myPlayer()) walk(regionA);else if (getNpcs().closest("Monster X").interact("Attack")) log("attacked");
would work fine as an alternative.
He was referring to doing something if closest returned null. Your code focuses more on ensuring the player is at the correct area.

I got bashed on another forum for this subject, at a time long before I came across the "billion dollar mistake" thing. I expressed it as an opinion, and it was shunned. It's like the time when people were told the world is round. It's like when Sacrotes got sentenced to death for denying belief in gods. But now, there are tons of topics on it, and tons of reason behind it. It can be debated for ages if you'd like, it's not going to change the fact that null pointers were a mistake (as coined by the creator of em). So it's best to leave it at "null grew on some people, so they prefer it" and allow them to code their style

Edited by fixthissite

Just wanna let you guys know that I've added webwalking to OmniAPI (courtesy of @Valkyr), enjoy biggrin.png

Does it handle objects? Widgets? Dungeons? Teleports? Shortcuts?

  • Author

Does it handle objects? Widgets? Dungeons? Teleports? Shortcuts?

 

It handles objects + the enter wilderness widget atm. There was a teleport handler however Valkyr never gave it to me, so I'll write my own at some point.

  • Author
 

Hey guys, just letting you all know that I pushed another update that further improves the interaction system as well as implementing my PaintLib project (gonna make it look nicer soon), enjoy :)

 
 
 
  • 2 weeks later...
  • Author

Alright, here is a reasonable example of why you want to have control:

 

Monster X is found in two regions, Region A and Region B.

 

NPC monsterX = getNPCs().closest("Monster X");

if(monsterX != null)

monsterX.interact("Attack");

else if (regionB.contains(myPlayer())

walk(new Path(regionA))

 

Not using null checks:

getNPCs().closest("Monster X").interact("Attack"); //Does nothing, doesn't go to a different region

Not using null checks with region switching:

NPC monsterX = getNPCs().closest("Monster X");

if(!monsterX.getPosition.equals(new Position(-1, -1, 0)) //See where I'm going with this?

monsterX.interact("Attack")

else if (regionB.contains(myPlayer())

walk(new Path(regionA));

 

You could do some hard spaghetti crap and make booleans for new NPC instances, but that's a hundred times worse than returning null. It's totally fine for scripters to do this because you guys know exactly what to expect from the behavior of your script. From our standpoint, this would be a nightmare.

 

I know it's useless to reply at this point, it's been a long time. I'm not sure why I didn't say this in the first place, but in any data type present in OmniAPI, #exists() will define whether or not the object is both there and available to be interacted with (for example, in widgets it will check if the child isn't null and if the widget is visible). No need for nasty instanceof checks, no need for null checks either ;)

if (getNPCFinder().findClosest("Dwarf").exists()) {
    getNPCFinder().getLastFound().attack();
}
else {
    log("not there :(");
}

Or, in your case:

NPC monsterX = getNPCFinder().findClosest("Monster X");
if (monsterX.exists()) monsterX.attack();
else if (regionB.contains(myPlayer())) walk(new Path(regionA));

Might be something to look in to ;)

  • 2 weeks later...

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.