This tutorial is for people who know nothing about scripting/programming.
I will explain the very basics starting from zero and in the end you will be able to create small scripts for worldpainter by yourself, you will know all the relevant tools and where to find help if something doesn’t work.

To start out you only need worldpainter installed and a text editor, windows comes preinstalled with Notepad (dont use word).

Creating a first script file

Worldpainter has the ability to run scripts by executing javascript files:

Such a script file is essentially a text file with a .js ending that contains code. When executed, worldpainter loads that file, reads it from the top to the bottom, line by line and then executes it. This holds true for most programming languages, its always top to bottom, left to right, statement by statement.
For javascript and worldpainter, it doesn’t matter where the file is saved, only the contents of the file (the “text”) matters.

Fun fact: file extensions dont really mean anything. Sometimes programs expect them to be a specific ending, but you can rename a .js file to .txt and open it with word. (Word is not a code editor, please dont use it for that). This holds true for programming files, but not necessarily for other stuff. docX word files are actually zip folders, etc.

We can open and edit these files or create them by ourselves. For starters, open your text editor (or notepad, NOT WORD!) and create a new file called helloWorld.js in a folder where you can find it again. It might make sense to create a mydocuments/worldpainter/scripts folder, to stay organized:

And thats it, you can load and execute this script file now in worldpainter. Hurray!
Of course it doesn’t do anything yet, so lets change that.
So, we know that code is read top to bottom, left to right.
Now how do we make it do something?

print("hello world");
print("this is my first program");

add that to your file and execute it in worldpainter.

So we see in the output that the first line was executed first, and the second after that. Notice the “;” at the end of the lines. In javascript, this is what ends a statement. A statement is a single instruction that tells the computer to do something.
The computer reads (“parses”) the script file from top to bottom, left to right, but in the end its the ; that defines where a statement starts and ends.
We could rewrite our code like this and achieve the same output:

print("hello world"); print("this is my first program");

For readability, programmers have come to write ONE statement per line.
Its purely a formatting thing, but its a standard that will make your life easier in the long run.
So back to this we go:

print("hello world");
print("this is my first program");

To make understanding code easier, programmers use comments in their script files.
Every line that starts with // is consideres a comment in javascript and will be ignored by the computer when reading the file:

// i am a comment
// this line is ignored: print("i am ignored")
print("hello world"); //comments can go anywhere
print("this is my first program");

Variables

So far we haven’t done anything useful.
Lets do some maths, that basic building block of all programming.
First we declare a variable and then do something with it:

//define the variable
var myVariable = 5;

//print it
print(myVariable);

// assign it a new value
myVariable = 10;
print(myVariable);

//do maths
myVariable = (150 + 270 + 999 - 42 + 4) * 30,462708182;
print(myVariable);

The pattern is always the same:
first you define the variable, you tell the computer that it exists:
var myName = 12345;
after that, you can assign new values to it.
Every variable that you used MUST first be defined before you can do anything with it, similar to a function.
Its always the same: first define, then assign, then use.

Functions and code blocks

Now what is that print( ) thing we did? Its called a function.
A function is a block of code that is defined somewhere (in this case worldpainter defines it without us seeing it in our own code). We can call functions like this to execute the code inside them and give them parameters.
1. print is the function
2. “hello world” is the parameter
3. print(“hello world”) is the function-call.
a function itself doesnt do anything on its own, unless it is called.
Lets see this in action.
First we define a function, we call it doSomething

function doSomething() {
   print("hello world");
   print("this is my first program");
};

The function definition usually goes on top of the file, so the computer reads it first before it is being used/being called.
Now that we have our function defined, we can call it:

function doSomething() {
   print("hello world");
   print("this is my first program");
};

doSomething();

the { and } brackets define the start and end of a code block.
print is a function too, just like doSomething. The difference is that it is defined by worldpainter, outside of our code and we can use it without having to define it ourselves.

The main purpose of functions is two things:
– make code easily reusable
– make code more readable by grouping code that does one thing into a properly names function.

Usually, when the computer has finished executing a script, it will “forget” everything that was defined inside the script file.
This is NOT the case in worldpainter, as long as worldpainter runs, it will remember function that you defined in scripts.

Lets create a script that calculate the yearly wage of 3 people:

// money danny makes per hour
var dannyWageHour = 7;
var elmoWageHour = 15;
var dieterWageHour = 3.5;

// function takes hourly wage as input and returns the yearly wage
function hourToYearlyWage(hourWage) {
   var workHoursPerWeek = 40;
   var weeksPerMonthAverage = 4.25;
   var monthsPerYear = 12;
   var yearWage = hourWage * workHoursPerWeek * weeksPerMonthAverage * monthsPerYear;
   return yearWage;
};

print("danny:");
print(hourToYearlyWage(dannyWageHour));

print("elmo");
print(hourToYearlyWage(elmoWageHour));

print("dieter");
print(hourToYearlyWage(dieterWageHour));

So our function allowed us to do repetitive tasks easily with very few lines of code. That is the essence of scripting.
On top of that, if we want to change the maths, we can do it inside the function and it will apply to all 3 employees. For example when we have reduced working hours to 35 a week, we only have to edit it once.

Fun fact:
You can define functions inside of functions inside of functions etc.
They will only exist in the block where they were defined, that is called “scoping”.

Objects

The last important building block you need to know about in javascript, are objects. Just like you can group together code (logic) into a function, you can do so with values / variables:

//define the object
var dannyEmployee = {
   name: "Danny",
   wageHour: 7,
   pet: "dog"
};

//get a value:
print(dannyEmployee.name);
print(dannyEmployee.wageHour);
print(dannyEmployee.pet);

//assign a value, danny got promoted 
dannyEmployee.wageHour = dannyEmployee.wageHour + 5

print(dannyEmployee.name);
print(dannyEmployee.wageHour);
print(dannyEmployee.pet);

//print the whole object at once
print(Json.stringify(dannyEmployee));

In javascript, objects are defined with key-value pairs:
name is the key
“danny” is the value of the key

key-value pairs are encapsulted with { } brackets and separated with ,
This is called Javascript-object-notation (JSON) and a standard which you can google.

Interacting with the worldpainter world

So now that we have the basics covered, we can start interacting with worldpainter. But how?
Worldpainter prepares a way for our script to give it commands and interact with the world:
https://www.worldpainter.net/trac/wiki/Scripting/API

Worldpainter has pre defined a couple of objects and functions for us to easily achieve large scale editing tasks.

// wp and world object is defined by worldpainter
print(wp)
print(world)
//we can see that those are java objects and we can use them in our script

//lets make everything sand (sand has id 5 in worldpainter)
//we execute the operation by chaining function calls to eachother, this is worldpainter-exclusive and not a standard
wp.applyTerrain(5).toWorld(world).go()

//paint stone at steep angles
// first create a filter 
var filter = wp.createFilter()
    .aboveDegrees(30) 
    .go();

//do the action and use the filter
wp.applyTerrain(0).toWorld(world).withFilter(filter).go();

Please note that the chaining of function calls is a worldpainter specific thing.
wp.applyTerrain(0) returns an object of type “MappingOperation”, which we then call mappingOperation.toWorld(world), which again returns a mappingOperation obejct.
In theory we could express the same like this:

var op1 = wp.applyTerrain(0); //mapping operation with grass
var op2 = op1.toWorld(world);
var op2 = op2.withFilter(filter);
op2.go();

This code is correct BUT worldpainter will throw an error at us. It wants us to do the chaining and execution with “go()” in one step, and will not allow it do be done in multiple steps.

Running javascript outside of worldpainter

So far we know that we can write code, give it worldpainter and it will execute it.
But whats actually going on?
All code in the beginning is just text, as we already discovered. This text is then given to a program thats able to execute code, the Runtime.
In our case, worldpainter has a built-in javascript runtime, a java-library called Nashorn.
Nashorn is a javascript runtime, that can read and execute an older version of javascript (ecma 5.1) AND allows the mixing of java and javascript. This is relevant, because worldpainter is writte in Java, a different language that has no connection to javascript (besides the name), and different programming languages can not interact with eachother by default.

Now, we have written normal javascript files so far, but they are not exclusive to worldpainter. We can run them in other javascript runtimes too.
It just so happens, that all webbrowsers have such a JS-runtime, so we can execute javascript code in our browser.
For that we open a browser (in my case firefox), press F12 and go to console:

in the bottom window, we have a text input, this is where we can type in javascript, press enter and have it executed:

in my case, i had to type “allow pasting” first to paste my clipboard there, because firefox thought i was getting scammed and told to paste stuff i dont understand.
Notice how i used “console.log” instead of “print”?
That is because the browser is not worldpainter, print() has a different meaning here (it prints the page). Instead the node.js – runtime in our browser defines the console object which allows us to interact with the console window:

// print("hello world") becomes this in the browser:
console.log("hello world");

You can also download and install node.js onto your computer and use it over the command line:

Just a neat little thing to know that code can be executed outside of worldpainter too. Of course you can not use things that are only defined in worldpaiinter such as wp, world or print.

Professional editing tools

So far we have written our scripts in Windows Text Editor “Notepad” (well you have, im on linux).
Maybe you have already made a typo on accident and caused the program to throw an error, or misbehave in other ways. And maybe finding the typo was very annoying.
Developers dont actually code in Notepad, instead we use other Text-Editors that come with support for the programming language we use, so called “IDEs” (integrated delevolpment environement).
In our case i recommend Visual Studio Code (not the same as visual studio 2022!).
Its a free text editor created by microsoft that allows installing extensions (like a mod) to make working with a specific language easier.
So:
1. download and install visual studio code (from google f.e.)
1.1 start visual studio code
2. install the js-doc plugin (it will help keeping an overview)
3. install the eslint plugin (it will help find spelling mistakes)
4. restart visual studio code

Go to File > Open folder, and navigate to your documents/worldpainter/scripts folder. open it.
You can see the coloring is different, comments are green, function calls are yellow and variables are blue:

Additionally, the Editor will now warn us if we make writing mistakes (“syntax errors”):

if you get red squiggly lines, hover over them with your mouse and read what it says. Usually it tells you what to do to solve the problem: “the fix”.

Find help

At some point, you will be confused, you get an error you don’t understand or you want to do something which you are not able to yet.
Follow these steps to figure out a solution:
1. if its an error, read what the error says. usually it tells you WHAT is the problem and in WHICH line of code it occurs.
2. copy the error/ write down your problem and give it to chatGPT. explain your environement: “im writing javascript for worldpainter in ecma5.1 version, tell me why this code doesnt work: … “
3. if chatGPT doenst know/dreams bullshit/ you cant figure it out, go to google and search for your problem: “‘,’ expected.ts(1005) javascript”, read articles from other people who might have had the same issues
4. if googleing didnt help either, post your question with code AND error to stackoverflow or a discord

You will have to learn the syntax of javascript and the basics yourselves.
We have covered: variables, objects, functions.
You should now go and learn yourself about:
for-loops, if statements, data types

Here again, usually chatGPT is very helpful with basics:
“Tell me about data types in javascript”
There are also A LOT of youtube tutorials and free-online-tutorials for learning the basics:
https://www.w3schools.com/js/
https://www.youtube.com/watch?v=2nZiB1JItbY

And if you think something is magic, for example how you give text to worldpainter and it does stuff, let ChatGPT explain it to you.
Just be aware the ChatGPT doesnt know THAT much about worldpainter and will lie to you. Use it mostly for basics about javascript.

NOTHING IS MAGIC, EVERYTHING IS DEFINED AND CALLED SOMEWHERE

Final words

You have learned the very basics of

  • how to create a script file
  • how to execute it
  • what tools to use for editing
  • where to find help
  • where to learn more

With this, i leave you to your own adventure, happy coding.


Leave a Reply

Your email address will not be published. Required fields are marked *