A few weeks ago we were lucky enough to have a visit from YouTuber and professional Minecraft modder (for the HyPixel server) codename_B (a.k.a. VladToBeHere, a.k.a. Ben).
Ben (left) addresses CoderDojo Athenry. Also pictured: Auburn, Ben’s girlfriend, and our own Michael Madden
Ben is an extraordinary programmer who just breathes code. On his YouTube channel he regularly creates a complete MineCraft plugin in only sixty seconds!
After addressing the entire Dojo, Ben showed our modder group and a few other more advanced coders how to make a quick plugin which causes chickens to explode when a player kills them.
Ben’s mod was written in Java and used the Bukkit API to interface with MineCraft.
Porting the Plugin to ScriptCraft
ScriptCraft is built on top of Bukkit. Because of this, almost all the Bukkit API is available for use in ScriptCraft. I believe there are a few Java-only bits in Bukkit, but I haven’t encountered them.
I realized that, in theory at least, it should be possible to port Ben’s plugin to ScriptCraft. In practice, it proved to be more straightforward than I could have hoped. If you don’t already know Java, ScriptCraft is a great place to start if you want to create MineCraft mods.
ScriptCraft and Bukkit References
When writing something new, you’ll need to be able to look-up things that you are not familiar with. Two references I used for this script, apart from Ben’s original code, were:
- ScriptCraft API
- Bukkit API (from Spigot)
Browsing these resources is also a good way to see what can be done and to thereby generate new ideas.
Anatomy of the Plugin
The plugin is composed of four parts:
- Two variables to represent the Bukkit types which represent chickens and players respectively
- A loading function which we will run when the plugin loads
- An event handling function which will be called whenever one entity damages another
- A call to the loading function, at the bottom of the file, to make it run as soon as ScriptCraft reads it
Let’s talk about each of these parts in turn.
Variables to Represent Bukkit Types
After a require(‘events’) line (to make sure we can reference the events object), there are two lines as follows:
var bkPlayer = org.bukkit.entity.Player;
var bkChicken = org.bukkit.entity.Chicken;
These are ‘types’ which represent an entity of type Player and an entity of type Chicken respectively. We’ll use them in a bit to determine, when we’re told one entity has damaged another, that it was a Player entity causing damage to a Chicken entity.
The Loading Function
The next part of the script is the loading function. It’s short and really only does two things:
- Announces that the plugin has loaded by printing a message to the console
- Tells Bukkit that we’d like a function of our own to be run each time that a particular event occurs. In this case it’s the event that fires every time one entity damages another.
Here’s the code:
// The function which will run when we load this module
var _loadMod = function()
// Announce ourselves to the console
console.log("Exploding Chickens: [Loading ScriptCraft Mod]");
// Tie our code into the event that fires every time one entity damages another
The Event Handling Function
This is the most complex part of the module, but not terribly so. Here’s the code:
// The code that we want to run each time one entity damages another
var _entityDamageByEntity = function(event)
// Find out, from the event, who's getting damaged and who did the damage
var damagedEntity = event.getEntity();
var damagingEntity = event.getDamager();
// If it's a chicken getting damaged by a player, game on...
if (damagedEntity instanceof bkChicken && damagingEntity instanceof bkPlayer)
// Announce in the console that we've detected a player damaging a chicken
console.log("Exploding Chickens: [A player damaged a chicken]");
// Schedule a task to run in five seconds.
// Check to see if the damage brings the chicken's health
// down to, or below, zero. If so, it's dead...
if (damagedEntity.getHealth() - event.getDamage() <= 0)
// Get the chicken's location
var loc = damagedEntity.location;
// Create an explosion at the chicken's location.
// A big one...
}, 20 * 5);
What does it do?
- Gets the entity that caused the damage and the entity that was damaged and check to see if they’re a player and a chicken respectively
- If they are a player and a chicken, Schedule a task to run in aprox. five seconds. This task can result in an explosion, so it’s nice to have a little “getting away” time.
- When our task runs, see if the amount of damage inflicted was enough to bring the chicken’s health down to zero (or below) and if it was, make a massive explosion where the chicken was.
The Bukkit function scheduler.scheduleSyncDelayedTask() needs a reference to the plugin which is asking for the task to be scheduled. In this case it’s ScriptCraft and there is a special automatic variable, __plugin, which ScriptCraft can use to refer to itself when it needs to.
And that’s pretty much it!
Getting it All Going
The last line in the file is just a call to our _loadMod() function. This will get run immediately by ScriptCraft when it read it, setting the mod into action:
// Run this script as soon as the file's loaded
Here’s the mod in action:
The script file can be downloaded from here. I hope this inspires you to create your own server mods using ScriptCraft.
* The author is a vegetarian and general soft touch who even tends to feel bad about exploding virtual animals…