Scriptcraft – A Little Friendly Vandalism

For this week’s sample script, building on the ideas developed the week before, I decided to pander to the crowd a little and show a script called tagger.js which allows you to ‘spray’ a design, in a block type of your choice onto the environment. It can be downloaded from here.

Description: Graffiti near Moganshan Road in Shanghai. Photographer: Jakub Hałun. Artist: Unknown. Source: Wikimedia Commons

Defining Our Design

The script contains an array of strings used to defined our design. In the array each string represents a row. Each character in those strings represents a block. Spaces are treated as blanks, anything else is a part of our design. Take a look at this specification which represents a peace sign:

var tag = ["   ***   ",
           " ** * ** ",
           " *  *  * ",
           "*   *   *",
           "*  ***  *",
           "* * * * *",
           " *  *  * ",
           " ** * ** ",
           "   ***   "];

It may be a little hard to make out at first, because characters are much narrower than lines are tall and the whole thing is stretched. Comparing to this drawing should help:

Peace Sign

Peace sign design for tagger.js

I’ve used asterisks in my strings just because it fills the space, but any non-space character will work just as well.

Spraying Onto What’s Already There

The fun thing about tagger.js is that it places the design on whatever is already in the world. It’s not restricted to flat surfaces!

The script looks at the area the player is facing and moves forwards, within a sensible limit, until it encounters a solid block (not air). If it finds one, it changes the block to the requested type. These diagrams show the operation.

Tagger_before

Tagger_after

If no block is found within the search depth, as has happened several times in the diagram above, that part of the design is left out.

In Action

Below is a screenshot of tagger in action: a big stone sphere with a love heart, made of red wool, and a partial smiley, made of gold blocks, sprayed onto it (partial because I was too far away when I called the script and some blocks were beyond the default depth).

tagger

Not Only … But Also

The script also has a few other little interesting features. In common with many of the standard Scriptcraft functions, this one shows how to check for parameters being left out and how to provide default values when that happens. It also shows how to retrieve a part of an existing string, used here to get a single character at a time. Take a look at the script yourself to see how this happens.

Scriptcraft – Discovering the World

Introduction

Thus far, we have used Scriptcraft to build cool structures in our Minecraft worlds, but the interaction has been a little one-sided. We’ve placed objects into the world, but we’ve never stopped to ask: “What’s already there?”.

papapishu-Boys-running

That’s a powerful question to ask, because once we know what’s already in the world, our interaction with it becomes richer and opens up many new possibilities.

Objects in JavaScript

Objects in JavaScript have Properties and Methods. Properties are what they sound like; a value associated with object that we can get or set. Methods are actions, in the form of a function, that we can ask the object to perform.

If you thought of me as a Person object then you could imagine some of the Properties and Methods I might have. For Properties I might have things like NameAge, Height, Weight, etc. An example of a Method I might have could be SayHi() [notice the round brackets after the name marking this as a method]. That would make me say “Hi!”. A method might have arguments, so it could be SayHiTo(“Dave”) which would make me say “Hi Dave!”. A method could equally calculate a value. An example might be CalculateBMI() which would calculate my Body Mass Index (BMI) value based on my Height and Weight properties. On second thoughts… scratch that idea. SampleObject Exploring Existing Objects

How do we explore the objects in the ScriptCraft world? One way is to read the API documentation:

Another way is to look at the Scriptcraft code files themselves, especially drone.js.

Another handy, lazy, way to explore an object you already have a reference to in ScriptCraft is just to treat it like a string and pass it to self.sendMessage(). You’ll usually get a representation which shows some of the properties of the object and those properties’ values. It’s incomplete, but very quick and might show what you’re looking for.

Getting the Block Type

All of this was building to finding out, from Scriptcraft, what the block at a particular location is. Using a combination of the techniques listed above, I determined that I needed to call a method on the Bukkit World object called getBlockAt(). In Scriptcraft the server object has an array called worlds and the normal world is worlds[0]. For the curious; worlds[1] is the nether and worlds[2] is the end.

That’s everything we need to create a simple script to examine the block that we’re currently looking at. We can create a Drone, which is created at the block we are looking at by default, to get the location. Here is the main part of the code:

// Create a drone (will be placed at the block the player's looking at)
var d = new Drone();

// Gather information about the world, the drone's location
// and the block at the drone's location
var world = server.worlds[0];
var loc = d.getLocation();
var chunk = loc.chunk;
var block_info = world.getBlockAt(loc.x, loc.y, loc.z);

The remainder of the code is just printing this information to the console in a tidy way. We called it whats_that.js and it can be downloaded from here. The screenshot below shows it being run.

whats_that2

This will form the basis for some future projects.

Quick Final Note on Block Metadata

One final note and something that wasn’t discussed at our session last week: to fully define a block we need to know both its type and its metadata. Two wool blocks of different colours have the same type but different metadata values to distinguish them from one-and-other. Similarly steps use the metadata value to distinguish between the different possible orientations. You can use the whats_that() function to explore this.

Making a Rainbow in ScriptCraft – Part 2

rainbow

Welcome to Part 2 of “Making a Rainbow in ScriptCraft”. Take a look at Part 1 below if you haven’t already and them come back here. If you’re read Part 1, you can download the script by clicking here.

Approaches to Drawing the Rainbow

You might imagine that drawing a rainbow is just drawing a series of arcs, one inside the other. If you do that though, you’ll probably find that there are gaps between some of the arcs. Look at the diagram here:

arcs

The red circle fits perfectly inside the blue, but there are little gaps between the red and the green circles. Gaps won’t look brilliant in our rainbow so what can we do to avoid them?

What we can do is to scan across every single block that’s going to be in the rainbow and figure out what colour it should be based on how far it is from the centre. If we did that in the diagram above, the overall shape would be the same, but the little gaps would be red or green instead of empty. This is the approach our script takes.

If you’re interested, Walter Higgins uses a different technique in his built-in rainbow function. Run it and see: starting from the outside of the rainbow, he draws arcs a little thicker than he wants, and lets the ones inside them intersect a little bit. It’s more efficient (in terms of run speed) than my approach, but maybe not quite as flexible.

Array of Colours

At the top of the script, there is an array of colours. An array is a special type of variable that holds more than one value at a time.

// Colours for the rainbow
var colours = [blocks.wool.red, blocks.wool.orange, 
               blocks.wool.yellow, blocks.wool.lime, 
               blocks.wool.lightblue, blocks.wool.blue,
               blocks.wool.purple];

The first item in the array we can get with colours[0], the second with colours[1] and so on. Conveniently too, we can use colours.length in the code to know how many things are in the array without having to assume it’s always going to be seven. If you wanted to edit the script so it read:

// Colours for the rainbow
var colours = [blocks.iron, blocks.gold,
               blocks.diamond];

It would still work and give you a three bar rainbow made of iron, gold and diamonds. Cool? I think so. Hopefully this helps convince you of how convenient arrays can be.

Credit where it’s due: I borrowed the rainbow colours from Walter Higgins as he’d already gone to the trouble of figuring out which MineCraft colours were closest to the classical rainbow colours of red, orange, yellow, green, blue, indigo and violet. No point re-inventing the wheel! [Ok, I did come up with my own first and then discovered he’d done it better but whatever…]

Two Functions

The script contains two functions. The main function rainbowk and a second function called get_block. Why? The simple answer is, it’s a lot neater; easier to read and easier to understand. You never have to use more than one function, but if your code gets long and complicated you’ll eventually lose track of what is going on unless you break it up into simpler chunks.

The function rainbowk is the one we call from inside MineCraft and it’s the only one added to exports. It takes two arguments – the inner radius and the bar thickness. Inner radius decides how wide the inside of the rainbow is and bar thickness determines how wide each bar is. It scans over all blocks in the rainbow, one row at at time and from the ground up. At each block it calls get_block to figure out what block at that position should be.

The function get_block isn’t exported, so we couldn’t call it from inside MineCraft, but we can and do call it from inside rainbowk. It works out how far the block we are considering is from the centre of the rainbow, using the technique discussed in Part 1, and decides what the block type should be. The block type will either be one of those from the colors array if the location is inside the rainbow or blocks.air if outside the rainbow.

Mega-Rainbow

I showed the script to my nephew who attends CoderDojo Athenry in the Scratch Beginners group. He wanted to know what the “biggest” one he could make was. Well, there is no actual biggest but he decided to make a pretty huge one. He specified an inner radius of 50 blocks and a bar thickness of 12 blocks. For those wondering what the total width of that is, it’s this:

megarainbowdims

Two hundred and sixty eight blocks wide! It’s half as tall, so 134 blocks high. The total number of blocks inside the rainbow is 268 x 134 = 35912! It took about three quarters of an hour to build 🙂

megarainbow

Here it is utterly dominating a village! It was hard to get this much in the screenshot and keep a sense of scale 🙂

Thanks!

Thanks to everyone who’s read this post. Hopefully you’ll download the script and give it a try. I’ll be delighted to answer any questions on it at next Saturday’s session or indeed at any CoderDojo Athenry session in the new year.

Making a Rainbow in ScriptCraft – Part 1

rainbow

I decided for my first ScriptCraft project I would try to create a rainbow. There were two reasons for choosing this:

  • I thought it’d look nice
  • It would need a bit of maths, so it’s something you couldn’t easily build by-hand

I was a bit disheartened when I found that the creator of ScriptCraft, Walter Higgins, had included a rainbow as a standard function in ScriptCraft, but I persisted regardless and I’m glad I did.

There are, I think, three things that make this script interesting:

  • It’s got some useful maths in it
  • It’s got an array variable
  • It’s got a second function

So, I’ll have a quick chat about each of these, but because it’s fundamental to the rest. This post is all about the maths.

I can just about hear the groans now, but I promise, this is crazy useful and really not that hard.

Useful Maths – Calculating the Area of a Rectangle or Square

The area of a rectangle or square is just the width multiplied by the height. Take a look at the two shapes below. The rectangle is 2 high and 5 wide and contains 2 x 5 = 10 squares. It’s area is 10. The square is 5 high and 5 wide and it’s area is 5 x 5 = 25.

area

Count the little squares if in any doubt.

Useful Maths – Squares and Square Roots

In a square, width and height are the same so the square’s area is always the same number multiplied by itself. Above it was 5 x 5 = 25.

A number squared is simply the number multiplied by itself. The name makes sense when you see that it relates to the area of a square, as above.

Two squared is 2 x 2 = 4. Three squared is 3 x 3 = 9. A square is often written as the number with a superscript 2 after it. You can see that here:

squared

A square root is the reverse of a square. If 2 x 2 = 4, then the square root of 4 is 2. In the same way, the square root of 9 is 3. Every positive number has a square root, but most aren’t easy to guess like the two I’ve just shown. The square root of 2 is 1.414! A calculator or your computer program can always figure them out though. A square root is normally written as shown here:

squareroot

Useful Maths – Measuring Distance in 2D and 3D

Now that we know about squares and square roots, we can talk about calculating the distance between two points in 2D and 3D. This is something programmers need to do all the time. The technique that’s used is known as Pythagoras’ Theorem and it’s been round since ancient times.

The person who invented it (probably not Pythagoras, even though his name’s on it now) noticed that there was something interesting about triangles which have right-angles in them (a perfectly square corner). They noticed that if you squared the length of the two shorter sides and added them together that that was the same as the square of the length of the longest side. Notice that the longest side is always the one which is directly across from the right angle. This diagram shows everything I’ve just said visually, showing the squared side lengths as physical squares:

pt

If you’re in doubt, all the little squares are exactly the same size, you can count them to make sure they’re the same.

You might not see it, but we now have everything we need to calculate distances in 2D. Consider two points, shown in red below, which are x units apart horizontally and y units apart vertically:

distance2D

It’s a right-angle triangle! This means that we know that the distance is related to the length of x and y like this:

distanceeq

but we don’t want distance squared, we only want distance so we can reverse the squaring with a square root which gives:

distanceeq2

This is really easily extended to 3D too. If the points are at different Z positions and z is the difference between them in that direction the distance is:

distanceeq3

Which is almost exactly the same, but has the z bit added.

In JavaScript – Measuring Distance in 2D and 3D

So, what does this look like in JavaScript? A little different, but easy to understand.

JavaScript doesn’t have a short way to write “squared” so we just multiply the variable by itself to get the squared value.

When it comes to square roots, the built-in Math object has a function for calculating square roots called “sqrt”.

Lets see how this looks together:

var x = 4;
var y = 3;
var distance = Math.sqrt((x * x) + (y * y));

Hopefully you can relate this to what we’ve shown above. Even if you don’t get it, you can still copy and use this code yourself if you need it.

The extension to 3D is almost identical. You’re probably figured it out, but I’ll show it anyhow for completeness:

var x = 4;
var y = 3;
var z = 5;
var distance = Math.sqrt((x * x) + (y * y) + (z * z));

Closing

I’ll probably take one more post to finish this off, which could take a day or two to appear. The script will be attached to the last post, so stay tuned!

Photos from MineVention

Thanks to the organisers of MineVention for making a limited number of tickets available to the Minecraft Modders group in CoderDojo Athenry to demo their mods. All of our modders did a great job of explaining what we do in CoderDojo Athenry to visitors, and demonstrating their Forge Java mods and their JavaScript constructions.

Well done to Eoin, Eli, John, James, Ruaidhri, Luke, Emmet, Oisin, Darragh, Sean and Aidan, and special thanks to mentors Martha, Kieran and Julie.

A real highlight was the 3D printed house that Cathal Egan had prepared, which was a printout of the Stone House that Oisin from CoderDojo Athenry had created:
https://cdathenry.wordpress.com/2014/11/30/combining-scriptcraft-and-printcraft-write-code-to-build-minecraft-structures-and-3d-print-them/

At the end of the day, Dan the Diamond Minecart was kind enough to visit our booth and see some of our mods. Here are a couple of photos of him looking at mods from our group.
luke-tdm
ru-tdm

ModderDojo Topic 5: Moving from Scratch to JavaScript

GeneralFeaturesOfProgrammingLanguages

Reminder: JavaScript is a well-established programming language, mainly used in web development. ScriptCraft is a Minecraft mod that allows you to write JavaScript code for building structures in Minecraft and writing new Minecraft mods. (So it’s a mod for creating other mods.)

Steps 1 and 2: Try out ScriptCraft commands and write simple mods

Please look back to last week’s notes for now to do this: https://cdathenry.wordpress.com/2013/10/05/modderdojo-week-1-getting-started-with-scriptcraft-and-javascript/

Step 3: Comparing JavaScript to Scratch

Some people criticise Scratch as being “childish”, but I don’t agree. While it is designed so that even 8 year olds can use it, it is still has all of the key features of ‘adult’ programming languages, as listed in the image at the top of this post.

(Technically, any programming language with variables, decision and loops is Turing Complete.)

This means that, if you already know how to write a Scratch programs that use these features, you will be able to apply that knowledge to any other language, such as JavaScript. The syntax of JavaScript is different, but it uses the same computational thinking.

Variables-Operators

Loops

Decisions

Notes:

  • Even though they have basic ideas in common, every programming language has its own specific commands that relate to its purpose: Scratch is focused on 2D games and animations, while ScriptCraft is focused on operating inside Minecraft, and JavaScript generally is used for interactive websites.
  • the echo command that features in these slides is not a standard JavaScript command, it is just used in ScriptCraft to display things on your screen in Minecraft.  Everything else is standard JavaScript.