.brackets.json file

As described in the video below, you’ll want to install the JSHint extension in Brackets and then create a .brackets.json file (note the “.” character at the beginning of the file!)

.brackets.json should have these contents:

{
    "language": {
        "javascript": {
            "linting.prefer": ["JSHint"],
            "linting.usePreferredOnly": true
        }
    }
}

The Video

Where To Go From Here

Try sprucing up your mycottage function, or try building entirely new structures!

My Notes for the Video

The following sections are my unedited notes that I wrote before making the video.

Part 5: Can’t Hold Me Back!

Intro

More setup

To get going with ScriptCraft and the Drone, we went through some steps to set up our own Minecraft server using CanaryMod. Now, we’re going to do a bit of set up to make Brackets work well for writing code for ScriptCraft.

{
    "language": {
        "javascript": {
            "linting.prefer": ["JSHint"],
            "linting.usePreferredOnly": true
        }
    }
}

What does this do? Computers are very picky about the instructions you give them. With this setup, we’ll be able to have Brackets tell us about certain kinds of problems with our code before we jump into Minecraft.

Start up CanaryMod and Minecraft

Fire up your CanaryMod server and Minecraft, just as you did for part 4.

JavaScript Files

The Cottage

I’m going to work through building up the ScriptCraft cottage. This is a good example because it uses the Drone as we saw in part 4.

When we’re done, you can start modifying the code to build a house of any style you like!

Functions wrap up a bunch of commands

I spoke a bit about functions in part 4. In Minecraft, when we typed /js cottage(), we’re running a function called cottage. Now, we want to make our own function called mycottage. To do that, we type:

function mycottage() {
}

“function” is what is called a keyword in JavaScript. It has special meaning for JavaScript, because it tells the computer that we’re creating a function. The parentheses after mycottage tells JavaScript that this function doesn’t take any arguments. We then follow that with curly braces.

Those curly braces are used to block of a section of code (actually, people call those blocks of code). Between those curly braces is where we’ll put the set of instructions that we’re giving to the computer.

In part 4, we learned about some of the functions on available on the Drone. How can we use those? And how can we add mycottage to the Drone so that we can use it just like cottage?

Extending the Drone

The Drone is an object. Remember I mentioned that objects can store values by name? Those values can even be functions that do things. A function that is stored on an object is something special enough that it has its own name: a method.

The Drone has a method called extend. We use that to add new features to it, and that’s exactly how ScriptCraft’s own Drone features are added.

To add mycottage to the Drone, we put this at the bottom of our file:

Drone.extend(mycottage);

So, we call the extend method on Drone and we pass in our mycottage function. ScriptCraft uses the function’s name as the name we’ll call within ScriptCraft itself.

That semicolon at the end of the line is how we tell JavaScript that we’re done with this particular command.

Save the file, and JSHint tells us that it doesn’t know anything about Drone.

Requiring Things

Putting all of our code into a single file would cause a variety of problems, so we don’t do it. Instead, we break our code up into modules.

In ScriptCraft, we use the require function to use code that is in another module. So, if we want to use the Drone, we’ll require it:

require("drone");

When you save, you’ll see an error.

JSHint is helpfully telling us that it doesn’t know anything about require. require is something that ScriptCraft makes available to all ScriptCraft code. We call that a global. We just need to tell JSHint that require is a global.

/*global require*/

What’s up with that crazy /* stuff? This is a comment in JavaScript. Everything between the /* and */ is just ignored by JavaScript. JSHint looks at a comment that starts with global and uses that so that it knows about the things that are handed to you automatically.

We’re still getting the error about Drone though. How come? It’s because we haven’t said anything about Drone with a capital D.

Functions, it turns out, can not only do things, but they can return values as well.

require is a function that returns the module we’re asking for. We need to hang on to that.

When you’ve got a value you want to hang on to, you store it in a variable. In JavaScript, we use the var keyword to see we want a new variable.

var Drone = require("drone");

This says to take the value returned to us by the require function and give it the name Drone.

Our errors are gone, but this won’t do any thing, will it?

mycottage doesn’t have anything in between the curly braces, so nothing would happen if we call it.

Let’s use the echo function to make it do something.

function mycottage() {
     echo("my cottage goes here");
}

You press the tab key and Brackets will put 4 spaces in front of echo. You don’t have to do that, but it makes your blocks of code easier to read.

echo takes a string. A string represents some text. In this case, the text “my cottage goes here”. In JavaScript, a string can be in either single quotes or double quotes, but you’ve got to have the quotes to tell JavaScript that you’re talking about that text and not some variable or function.

When we save that, JSHint complains about echo. ScriptCraft gives that to us as a global, so lets add it.

/*global require, echo*/

Let’s try it

In Minecraft, type:

/js refresh()

The refresh function tells ScriptCraft to reload all of its plugins. This is nice because we don’t need to restart Minecraft or CanaryMod while we’re coding.

/js mycottage()

You’ll see ScriptCraft print:

my cottage goes here
"[object Object]"

That first line of output is the one we told ScriptCraft to echo. The second line is actually the return value of calling mycottage. The Drone does some magic to make mycottage return the Drone. That’s something specific to the Drone and not something JavaScript does automatically.

Start building!

Let’s start building by placing the floor. Replace the function contents with:

     this
          .down()
          .box(blocks.birch, 7, 1, 6);

When we save that, JSHint complains about blocks but not this. You may even notice that Brackets gives this the same color as function. Why?

In JavaScript, this is used to refer to the current object. Since we’re adding mycottage to the Drone, this will refer to the Drone itself.

As for blocks, we need to do what we did for Drone.

var blocks = require("blocks");

No errors. Let’s try it.

/js refresh()
/js up().mycottage()

I added the up() call because the convention is that we build from the block we’re pointing at.

Chaining

In part 4, I talked about how we can chain the Drone function calls together. That’s what we’re going to do here…

    .down()
    .box(blocks.birch, 7, 1, 6) // birch wood floor
    .up()
    .box(blocks.air, 7, 5, 6) // clear area first
    .box0( blocks.moss_stone, 7, 2, 6)  // 4 walls
    .right(3)
    .door() // door front and center
    .up(1)
    .left(2)
    .box( blocks.glass_pane ) // windows to left and right
    .right(4)
    .box( blocks.glass_pane )
    .left(5)
    .up()
    .prism0( blocks.stairs.oak, 7, 6) // add a roof
    .down()
    .right(4)
    .back()
    .wallsign(['My','Cottage']);

These are all Drone commands just as we’ve seen before.

What is that we’re passing in to the wallsign function?

This is what’s called an array. It’s like a list. wallsign lets you pass in a list of strings and it will put each element of the array on a separate line of the sign.

Let’s try this. Woah! Nearly complete cottage.

Checkpoints

When creating big things, we sometimes need the Drone to move around and then come back to certain spots. You can do that with checkpoints.

    .chkpt('cottage')
    .down()
    .box(blocks.birch, 7, 1, 6) // birch wood floor
    .up()
    .box(blocks.air, 7, 5, 6) // clear area first
    .box0( blocks.moss_stone, 7, 2, 6)  // 4 walls
    .right(3)
    .door() // door front and center
    .up(1)
    .left(2)
    .box( blocks.glass_pane ) // windows to left and right
    .right(4)
    .box( blocks.glass_pane )
    .left(5)
    .up()
    .prism0( blocks.stairs.oak, 7, 6) // add a roof
    .down()
    .right(4)
    .back()
    .wallsign(['My', 'Cottage'])
    .move('cottage')
    .right(3)
    .fwd(4)
    .up()
    .hangtorch()     // place a torch on wall
    .move('cottage')
    .right()
    .fwd(3)
    .bed()           // place a bed against left wall
    .fwd()
    .right(4)
    .box(blocks.furnace) // place a furnace against right wall
    .move('cottage');

Now it’s complete!

Play around and try to decorate your house!

See what you can do!