One Million Worlds Wiki

ScriptBlockTool

Scripting blocks are the most advanced blocks in the game, you can play the game without ever having to deal with scripting blocks. Here be dragons.

Introduction[ | ]

Script block

The idea is that they can accept a small text program and replace a huge load of wiring with just a little bit of text. You can set the script by interacting with it

So they can convert something like this (which is an automated turret that tracks and fires at the player):

TurretComplicated

With something more simple:

TurretSimple

Inputs and outputs[ | ]

The inputs and outputs are all referred to by the letters N,S,E,W,U,D for north, south, east, west, up and down. The N,S,E,W are shown on the chip itself, the up and down you’ll just have to figure out for yourself. You can set a direction equal to a value and that value will be output to that directions. e.g.

N = 5

or

W = 'Hi there'

You can output to multiple directions in a single program

N = 5
W = 'Hi there'

You refer to the inputs in the same way, so say you have a number inputted in the West port and wanted North to be twice the West value you could use the following script

N = 2 * W //note that * means multiply

Implicit Outputs[ | ]

If you only have one output equal to a simple equation (or want all your outputs to be the same) you can omit specifying what output you want the value to go to, so you can simplify the previous program to this:

2 * W

Asking questions[ | ]

You can use the “if” keyword (and a whole bunch of brackets!) to do different things based on a question. So lets say you have an input W that is the distance away a player is (reported by a scanner block) and if the player is closer than 5 meters away you want to show on a screen (connected to N) “Go away” and raise a door (a Rail block connected to S) but if they do go away reopen the door you could use this program:

if(W<5){        // W is the distance away the player is
  N = 'Go away!'
  S = 4         //S is connected to a rail set to position mode, 4 is fully closed
}else{
  S = 1         //position 1 is fully open   
}

Variables[ | ]

Sometimes you want to calculate something once and then use it several times, you can store it in a variable

someComplicatedCalculation= 2 * N + S
W = someComplicatedCalculation
E = 2 * someComplicatedCalculation

Arrays[ | ]

Sometimes a piece of data has several parts, like a position might have an x, y and z. These can be both read and creating within scripts. The main place you’ll see these is inputs coming from scanner blocks which report positions as an array of 3 numbers. For arrays that enter on inputs you can refer to them in 2 ways:  

Reading arrays by X,Y,Z:[ | ]

distanceAway = N.x      //N.x is the first value in the array, N.y is the second, N.z is the third
S = distanceAway

This way of referring to arrays only works with arrays entering on inputs, not ones you create yourself.

Reading arrays by a number index:[ | ]

distanceAway = N[0]      //N[0] is the first value in the array, N[1] is the second, N[2] is the third
S = distanceAway

Be aware when using numeric indexes the first entry has index 0; the first value is N[0], not N[1].

You can create arrays using square brackets. for example this program would return an array of the numbers 1,2,3

N = [1,2,3]

You can of course use variables

distanceAway = N.x 
N = [distanceAway, 2*distanceAway, 3*distanceAway]

Inbuilt information[ | ]

Some data is provided in variables for use in your script (note, variables are case sensitive). At present these are:

Variable Header text
firstRun If this is the first time this script has run (i.e. you just edited it) this is true, otherwise its false
timeSlice How much time this run of the script represents (aka how long there is between runs of the script)
scriptTime The total time this script has run (its the sum of all the timeSlices since the script was changed)
ticks The number of times the script has run (since being edited)
worldTime The total time the world has existed
position The position of script block, will return a Vector
direction[Direction] e.g. directionNorth The direction the script blocks "north" is pointing, will return a Vector. The available directions are North, South, East, West, Upwards, Downwards and combinations of those

Remembering things from the last time the script was run[ | ]

Usually the script runs a fresh each time, forgetting all its variables, but it is possible to remember things from run to run, this is done using the persistent (or p) scope. Also because I really struggle to spell persistent you can also use the persistant scope and that will work fine. Anything in the persistent scope will still be available the next time the script runs. So lets say we want to modify the “go away” script from the “asking questions” section so that if starts saying go away if you come within 5 meters but then it keeps saying it until you are 10 meters away:


if(firstRun){
    p.goAway = false //when the script first starts up default to not saying anything
}

if(W<5){
    p.goAway = true 
}
if(W>10){
    p.goAway = false
}
//note that if W is between 5 and 10 it is left at whatever value it had previously

if(p.goAway){
    N = 'Go away!'
}

Inbuilt functions[ | ]

A small number of inbuilt functions are available

Log[ | ]

Used for debugging, you can pass log a variable and it will be shown on the script block setup screen. This is log as in "put it in the log book", not the mathematical meaning

log(N)

Clamp[ | ]

This will take a value and ensure it remains between two other values

N=clamp(W,5,10) //This will output the value of W, or 5 if W is below 5, or 10 if W is above 10

Stabilise[ | ]

This will provide functionality to stabilise a system, e.g. if you have a turret that’s looking at the player, with a scanner block controlling an axel to make it look directly at the player, you set it up and it seems to work fine but it keeps swinging back and forth. Introducing a stabilise around the output will calm everything down.

(For the mathematically inclined, it is a PID controller)

stabilise(errorValue)

or

stabilise(errorValue, proportionalTerm, integralTerm, derivitiveTerm)

The proportional, integral and derivitive terms can be ommitted and sensible defaults are used instead. The meaning of the terms are as follows:

Value Meaning
errorValue how far the recorded value is from what you want it to be. E.g. if the player is 30 degrees to the left and you want to be looking at them the errorvalue is 30.
proportionalTerm this is a tuning parameter, you need to play with it to see what works. You want to set it to a value such that your system swings quickly to the desired position (even if it overshoots)
intergralTerm this is a tuning parameter, you need to play with it to see what works (you’ll probably want it to be zero. You can use it if you need to apply some force even if you are at the correct position (e.g. when you hold a weight up with your arm you still need to apply force even when you’re in the right position
derivitiveTerm this is a tuning parameter, you need to play with it to see what works. This controls overshoot, if the system keeps osculating about a set point increase the derivitiveTerm.

Loops[ | ]

You don’t need loops, please skip this section. Ok fine, loops are useful when you want to do something more than once.

A simple loop could be like this:

for(i = 0; i<5; i++){
   /*this area will be executed 5 times, 
   once with i as 0, then 1 etc until finally when i is 4*/
}

Lets say, in the “go away” example the closer they get the more you want to say go away, lets say one exclamation mark for every meter they get towards you. A loop can do that.

distanceAway = W
permittedDistance = 10
if(distanceAway < permittedDistance){
    message = "Go Away"
    exclamationMarksToShow = permittedDistance - distanceAway //closer they get the more exclamation marks

    for( i = 0; i < exclamationMarksToShow; i++){
        message = message + "!"
    }
    N = message
}

Reading errors[ | ]

If any problems occur with your script the errors are shown when you next open the script panel. It will tell you the line number and letter number where it knew for sure that your script was wrong, its possible it went wrong before this but that’s its best guess at where it went wrong

Secretly its JavaScript[ | ]

The script used within OneMillionWorlds is actually a variant of JavaScript. I’ve made some additions but broadly if your script is valid javascript it will work. I haven’t covered anywhere near the full features of the language so if you’ve got to this point and want more there are many resources for javascript available online.