25,000,000 blocks

Using the Bukkit Scheduler In ScriptCraft

In this post we’ll use the Bukkit Scheduler to decrease the likelihood of our Minecraft client being dropped while performing computationally intensive tasks in our ScriptCraft code–tasks like building gigantic structures. As an added bonus we also get to watch our huge structures being built (rather than just poofing into existence as they currently do). Poof!

MCMap Live Shot For Perspective (the jagged tops are an artifact of the rendering software).

MCMap Live Shot For Perspective (the jagged tops are an artifact of the rendering software).

From what I can gather ScriptCraft currently performs all of its work in the main server thread. The main thread also takes care of a number of important tasks including the networking logic which manages the connection to your Minecraft client. Now, running on the main thread isn’t a problem in itself, it only becomes a problem once you start doing some heavy lifting like rendering a 500 x 100 x 500 rectangular prism (at least for my little server):

25,000,000 blocks (most clipped beyond the horizon)

25,000,000 blocks (most clipped beyond the horizon)

If your ScriptCraft code is gobbling up too much time you’ll end up seeing this screen:

Dirty Screen

Dirty Screen

I see it frequently.

One way to decrease your chances of seeing the old dirt screen is to punt off your ScriptCraft tasks off into another thread thereby giving the main server thread a little breathing room. Here’s an example of using the schedule to draw a large rectangular prism:

As you can see it is only a few extra lines of code and doesn’t add too much complexity. We get a reference to the scheduler and call the scheduleAsyncDelayedTask method supplying a reference to the ScriptCraft plugin and the task we wish to run.

Now a async delayed task isn’t the only type we can use in our ScriptCraft–in fact sometimes we shouldn’t use it. All in all Bukkit allows us to schedule four different types of tasks:

  1. Synchronous Delayed – Schedules a one-time task to run in the main thread with an optional delay.
  2. Synchronous Repeating – Schedules a repeating task to run in the main thread on a specified period with an optional delay.
  3. Asynchronous Delayed – Schedules a one-time task to run in a separate thread managed by the scheduler with an optional delay.
  4. Asynchronous Repeating – Schedules a repeating task to run in a separate thread managed by the scheduler with an optional delay.

 

In our example above I scheduled an async delayed task and you can too as long as your task is thread safe and doesn’t utilize the Bukkit API (so far all I have done with just ScriptCraft and JavaScript has been fine). If you need to use the Bukkit API inside your task, then you will have to use a synchronous task or just run your ScriptCraft code like you always have. You can also find out more about the Bukkit Scheduler in the Doxygen docs.

Finally, remember this is no silver bullet! If your doing too much work and your server can’t keep up nothing will save you from being dropped.

Advertisements
Wolf-bot

Scripting A Simple Minecraft Bot

Here I will implement a simple in-game wolfbot with ScriptCraft in under a hundred lines of code. In the beginning our bot will only support a few commands–mostly serving as a glorified “donkey”. In later posts we will add more functionality. You can find the code for our bot in the wolfbot Github repo.

First off, my intent in this post is not to create the next best pet/bot plugin, especially since there are already some good pet plugins out there. The purpose of this post is for us to learn how to create a bot in ScriptCraft.

We will also be using the brand new ScriptCraft plugin feature which was included in the newest release. The plugin feature is a neat addition since it gives us data persistence and also the ability to safely package various features so that non-op players can indirectly use ScriptCraft goodies.

ScriptCraft Plugins

There are three main parts to a ScriptCraft plugin:

  1. Definition
  2. Storage
  3. Initialization

Plugin Definition

The plugin’s definition section is where the meat of the plugin resides. Here we define various methods to implement the features we want to support in our plugin. We can also place helper methods here for accessing our plugin’s data storage.

Data Storage

ScriptCraft makes it absurdly easy to persist data with your plugins. To save data we need only add a key to our plugins store and assign it an object. Behind the scenes ScriptCraft will serialize the data into JSON when needed and save it for us to be accessed later.

Initialization

We can perform any initialization our plugin requires inside the ready method provided by ScriptCraft. Any code we place inside ready will run only after all other JavaScript functions have been loaded. In this section we can add hooks to Minecraft events and also determine what functionality we want to expose from the definition section using the command method.

A Simple Plugin

Below, check out each of the three sections in action in this plugin which can get and set a string:

If you would like to read more about ScriptCraft plugins, then I recommend reading Walter Higgins original post introducing them.

Wolfbot Specs & Demo

Before we get started coding our wolfbot, let’s look at the list of various actions I would like the bot to support:

  1. summon – Summons the bot.
  2. dismiss – Dismisses the bot.
  3. come – Causes the bot to target you and follow.
  4. stay – Causes the bot to sit and stay put.
  5. pack – Causes the bot to show you its inventory and allow you to take and place items with it.

You can see these commands in action below:

Wolfbot Implementation

To implement the actions we described above we will create a method for each action in the plugin definition section.  Most everything inside these methods are Bukkit API calls.  You can see the definition section below.  Reference the Bukkit API docs to find out more about the API calls I make.

All there is left to do now is create our storage and associate plugin commands with our plugin’s functionality so that players who are not ops can also have bots. Checkout the code for the complete plugin in the Github repo.

Suggestions

Is there a topic you would like to see covered here?  I want to hear your input. Send me an email with any suggestions for future posts.  If you liked this post, then you might also like Visualizing Towers Of Hanoi In Minecraft.