Editor Scripting is an experimental feature that can be used to build levels by programmatically placing blocks. The editor is currently available in the beta version of Fancade Web by entering the EditorScript command in the command line.

Getting Started

Let's create a new level and enter the EditorScript command. You will be greeted by a simple code editor with some examples in place. The code might seem unfamiliar at first, because it is written in JavaScript. But don't be scared, because we will learn the basics in this tutorial!

Functions

Set Block

So let's look at our first example.

// Set block at position (x, y, z) in level or open block
setBlock(x, y, z, prefabIndex); 
We can ignore the first line, since it begins with //. This makes the editor ignore any code in the current line, but it can give us some hints on what the following line does.
The second line starts with the function setBlock. You can imagine this as placing a script block with the aforementioned name. A list of these functions can be found in the examples. The following text represents the inputs given to this function, separated by , and enclosed by brackets. So to put this in visual scripting terms, we are placing a block called setBlock and give it the inputs x, y, z and prefabIndex.

But those inputs were actually just placeholders, so let's replace them with some actual values!

// Set block at position (0, 0, 0) in level or open block
setBlock(0, 0, 0, 3); 
Copy this code and paste it in the editor, then hit Run and Save and Close. As you might have guessed, this puts a block on the coordinates (0, 0, 0). The fourth value is the unique identifier for the Grass block to be placed. There is a list of unique ids for each built-in block, but what if we want to place a custom block instead?

Find Block

Create a custom block, for instance My Block. Then replace your previous code with this one:

// Find the block called "My Block"
findBlock("My Block");
You can once again see a function, but this one is called findBlock. In contrast to the previous function, this one doesn't take numbers as input. Instead it takes a block of text, called a string, which is encapsulated by a pair of quotes. We can now run this code, but it will do nothing at first, because we haven't used the output of the function anywhere. We can change this by storing the output in a variable!

Variables

// Find block by name and store it in a variable
let myBlock = findBlock("My Block");
setBlock(0, 0, 0, myBlock);
This line is different, because it doesn't start with the name of a function. Instead, we can see the let keyword, which creates a new local variable for us. The name of the variable is determined by the next word, myBlock. To store a value in the new variable, we follow the variable name with a = and the value to store, similar to a Set Variable block. In this case, this value is the output of the function we have used before.
The next line looks familiar and it once again places a block at the coordinates 0, 0, 0. But this time we don't directly input the id of our block, but instead we use the value stored in the variable which we have created before. This allows us to not only store the id of our block, but also use it in multiple other places.
After we have created the variable, we can change its value by adding following code in order to add a Brick next to our previous block:
// Change the value of the variable
myBlock = findBlock("Brick");
setBlock(1, 0, 0, myBlock);
But what if we want to store multiple blocks in our variable?

Arrays

// Create an empty list
let myBlocks = [];
// Store block ids in the list
myBlocks[0] = findBlock("Bricks");
myBlocks[1] = findBlock("Dirt");
Like previously, we are creating a new variable. But this time, we instead store an empty list [] in it. We then add values to the list by assigning them to the indexes in curly braces. This works similar to a List Element block and is also used to access the values afterwards.
// Set blocks from the list
setBlock(0, 0, 1, myBlocks[0]);
setBlock(1, 0, 1, myBlocks[0]);

Loops

Now if we want to place multiple blocks at once of course we will need a loop! JS uses 3 types of loop; "while" loop, "do while" loop and "for" loop. In this scenario we will use the "for" loop.

const myBlocks = [findBlock("Bricks"), findBlock("Dirt")];

let x = 0;
for (let element of myBlocks) {
    setBlock(x++, 0, 0, element);
}

Objects

Objects {} works almost similarly to arrays but unlike it is not considered a collection of value but instead a single value composed of other values called "properties" and functions called "methods". Lets take for example a ball, you will ask, how bouncy is this ball? what is its radius? just like this ball an object has its own properties to determine its characteristics. Using it lets try to make a simple structure.

Properties

let justATree = {
    x: 0,
    y: 0,
    z: 0,
    components: {
        // component: material, size, position
        trunk: ["Wood Y", [1, 6, 1] [0, 0, 0]],
        leaves: [Foliage, [3, 3, 3], [-1, 4, -1]]
    }
};

//If you want to you can also add or override properties later e.g.
justATree.position = [0, 0, 0];
properties are values that represent chracteristics of an object it can be any value type or a function. As you can see in our example we made the object justATreewhich contains properties named x, y, z and component. Using this properties lets try to make a method that will build the tree!

Methods

methods are special properties of an object that can be used as instruction for its behaviors. Now lets try to add a new method named build inside justATree.

let justATree = {
    x: 0,
    y: 0,
    z: 0,
    components: {
        // component: material, size, position
        trunk: ["Wood Y", [1, 6, 1] [0, 0, 0]],
        leaves: ["Foliage", [3, 3, 3], [-1, 4, -1]]
    },
    build: () => {
        // the "this" keyword refers to the object it is inside to,
        // in this case the "justATree" but since its not yet defined as that we use "this"
        setBlock(this.x, this.y, this.z, 0);
    }
}