Skip to content

Basic JS and ModPE Tutorials

Maxim Chintalov edited this page Dec 28, 2017 · 15 revisions

###Page in development #Javascript (ModScript) Tutorials ####Started by PEMapModder Please help improve the readability of this article by editing it. Normally, I would advise people to read W3Schools (https://www.w3schools.com/), but it is in fact for HTML. So I decided to include syntax of JavaScript.

Table of contents
The most basic syntax
Operators
Variables

###Intro First, let's go into the basic script syntax: A script is made up of functions. A function is something the reader (i.e. BlockLauncher) would operate its contents. The format of a script:

function newLevel(){
//contents of the function
print("new level");
if(1-2>=0||3<4)print("One minus two is larger than zero or three is smaller than four.");
if(3!=2==4+5){
  print("Three does not equal two, and four plus five equals nine.");
}
}
function attackHook(attacker, victim){
/*contents of the function*/
}

The code in each line after the symbol // will be ignored until there is a next line. The ones surrounded by /* and */ are also ignored. These are called comments.

The function name can be anything, but to let BlockLauncher run it, you must use a particular name. These functions are called hook functions, whose contents are modder-defined. What are functions that are not hooks? I will explain later.

function newLevel() is a hook that is called when a new level starts. A list of hook functions are present at another page of this wiki.

Inside a function, there are assignments and blocks. (Comments not counted)

An assignment is to do an action, for example, print("abc") prints a toast message abc. They must be followed by semicolons (;). (Note: semicolons after the last assignment are not required in some script readers, but it is a good practice to do so.)

A block is a group of assignments or/and sub-blocks. The contents in it are called under a certain condition or means. In the example, the first block in function newLevel() is called if 1-2>0 or (the || means OR) 3<4. (which is kind of rubbish because everyone who can read knows the first is false and the second is true)

There are other kinds of blocks, explained later.

There are some built-in functions in BlockLauncher. print() is an example. We call them for two main purposes:

  • to get a returned value
  • to do an action

There are many built-in functions. For example, we want to move the player to two blocks higher. According to the wiki in another page of the wiki, we should do setPosition(player,x,y,z); But what should be put for player, x, y and z, to let BlockLauncher know what we want it to do?

  • For player, there is a function getPlayerEnt() that returns the id of the player. So we put getPlayerEnt() in it. (Remember to add the brackets to indicate that it is a function, not a variable.)
  • For x, use the x-axis of the player originally. Use Player.getX() for the player's x-axis.
  • Look at appendix at the bottom for axes documentation.
  • For y, y-axis plus two blocks should be used. Therefore, it should be Player.getY()+2. It works similar to Algebra. These operators will be explained later.
  • For z, it is similar to x. Use Player.getZ().

Therefore, we end up using setPosition(getPlayerEnt(),Player.getX(),Player.getY()+2,Player.getZ());.


Operators

Operators are symbols used to represent mathematical things.

  • Player.getY()+1 is the player's y-axis plus 1
  • Player.getZ()-1 is the player's z-axis minus 1
  • Player.getX()*2 is the player's x-axis times 2
  • Player.getYaw()/90 is the player's yaw divided by 90, AND THEN MINUS THE REMAINDER, so the returned value is always integer, but not rounded off, but rounded down to the nearest integer.
  • e.g. 90/80 is equal to 150/80.
  • Player.getX()%16 equals to this in mathematics:Let x be the player's x-axis: returner = x (mod 16), or for Microsoft Excel =MOD((Player.getX()),16), or in English the remainder of Player.getX() divided by 16
  • 1==1 is the answer (true/false) whether 1 is equal to 1. Note: 1=1 is syntax error.
  • 1!=2 is the answer (true/false) whether 1 is inequal to 2. Note: this is not VBS. Don't use 1<>2.
  • 1<2 and 1>2 are the answer of whether these mathematical statements are true.
  • 1<2||1>2 always return true unless both expressions, in front of and behind it, are false. In other words, it means or.
  • 1<2&&1>2 always return false unless both expressions, in front of and behind it, are true. In other words, it means and.
  • 1<=2 and 1>=2 are equivalent to 1<2||1==2 and 1>2||1==2 respectively.

Variables

Instead of

if(getCarriedItem()==1||getCarriedItem()==5||getCarriedItem()==12/*etc*/){
//etc.

You can define a variable to represent getCarriedItem(). There are two types of variables: local and global. Let's look at local variables first. How to define a new variable:

var item=Player.getCarriedItem();

The var tells BlockLauncher to define a new variable. The item is the variable name. It is custom. However, by traditional, and because there cannot be spaces in it, to express "the player's holding item", we instead call the variable thePlayersHoldingItem. The allowed characters for a variable name are limited to a-z, A-Z,0-9, "" and "$". However, the character "" cannot be placed at the beginning (or the end) of the variable name. Also, note that some names, like "if", "this", "super", "var", "for", "try", "catch", etc., which are some keywords (bolded in Notepad++ [https://notepad-plus-plus.org/], which I recommend you to use to make the script), cannot be used as a variable name. You can skip the =, until the semicolon (;), but then the line is useless. You need to initialize it, at least do var item=null. (So that if you want to check if the variable is changed after some code you can do if(item==null)//something) The right of the = is the value to be stored into the variable. If you want to change it again, just do:

item=Player.getCarriedData();

without the token var. Sometimes you want to do this:item=item+2;, but it is in fact longer than necessary. For item=item(operator)anotherVar;, you can replace it with item(operator)=anotherVar;, e.g. item+=2;. However, if you want to do item+=1 or item-=1, you can instead do item++ and item--. This skill comes very useful in for loops.


What about global variables, then? Local variables are deleted when the function has stopped running (re-initialized when the function is re-called). To store some variables for next time the function is called, or for another function, you need to use global variables. Some people call global variables as "fields". (I dunno which, field is for java, and global is for PHP, java and PHP both with similar syntax). To make a variable global/field, you define it with the same way, but outside a function.

var time=0;
function modTick(){
time++;
}

In this mini-script, if you have already checked what modTick() is, you would know that time is added by one every 1/20 second (every tick).


Parameters

Now the player is tapping a block. You want to know which block he tapped. How can BlockLauncher tell you that? The answer is parameters, also called params. Params are a kind of local variable. It doesn't matter what you call it, as long as it is a valid variable name. However, they have to be in correct sequence so that the reader knows which one is the first parameter. For example, you can write useItem(itemId, blockId) in the hook, but their value won't be what you wanted.

So here is a simple script that has a field changed whenever a chicken is spawned:

var newestChicken=null;//initialized the field
function entityAddedHook(e){//when an entity is added - the entity is represented by local variable/parameter e
  if(Entity.getEntityTypeId(e)==10){//if the type id of the entity is 10 (i.e. chicken)
    newestChicken=e;//sets the field newestChicken to this chicken
  }
}

###Custom Functions

Uses

Now, you want to do the same block of actions when the player types a command, attacks a mob, taps a block, destroys a block... The method to do it without repeating the same code is to define a function.

function myFunction(a,b,c){
  //action1
  //action2
  //...
}

Then you can use it like print() and clientMessage(), and the parameters, both the types and amount are custom.

Return

If you want to get a value in multiple places, you can use functions. You may ask how you get the results from the function. Fields/global variables? Not so troublesome (and not very easily possible). The return token in a function can return a result.

After returning a result, ModPE will stop your function, and, like, replace the code that called the function with the returned value. Just like the GET functions built-in.

What if you want to return multiple values? Then you can use arrays to do that. Group your values in an array, and return them all-in-once at the end of the function.

You may also use the return token to stop a function running in an if-block.

Whatever you return, ModPE ignores what you return in hook functions.


Appendix

Strings

Strings can be joined from pieces by the operator +: var joined=pieceA+pieceB+pieceC;

Arrays

An array is a group of data grouped together into a single variable. The data are called by their sequence in the array. Different types of data can be in a single array, different with java.

An array of string can be joined according to their sequence number in the array by: var joinedString=arrayOfStrings.join(breaker); The string breaker is added between every two strings. breaker can be any length of string, including "" and "\n".

Spaces and line breaks

Unless both the character in front of the space and the one behind are characters for variable names, or that it is inside "" or '', spaces are likely to be automatically deleted by the script reader. In the other hand, to ease reading, you can add as many spaces as you want everywhere in the script, except inside quotation marks and between two characters for variable names. The reason why I didn't in this page is to avoid people thinking that you need to add spaces in front of (s and =s. As for line breaks, you can add as many as you want anywhere you can add a space. However, note that //comment ends when the line breaks. Therefore, a reminder to automatic modscript creators about adding byte marks inside the script is that, do "/" + any bytes + "/" instead of "//" + any bytes. If you want to add a line break in a string, like printing a toast message:

This is the first line.
This is the second line.

you should put print("This is the first line.\nThis is the second line."); instead of putting a line break directly.

Axis

A quick means to know which axis to plus or minus: Look above your head (I mean in the game, not real world!) and look at the wind direction. (i.e. direction of clouds) The clouds are flowing to the west, always. You can say a player following the clouds direction is moving against the X-axis. (i.e. opposite direction to the X-axis trend)

Diagram

The Y-axis is simpler. When you move down you move against the Y-axis.

Yaw and Pitch

Yaw is the rotation (looking left or right), and pitch is the status of looking up or down. You starts a new level looking at pitch 0 degree and look at the sun in creative mode at -90 degrees pitch. You look below yourself at 90 degrees pitch. So if you want to get the block the player is in after walking in the direction he is facing or for 5 meters (blocks), you can use trigonometry:

//Inspired by 500 ISE in his Fly on mobs.js
var blocks=5;
var x=Player.getX();
var z=Player.getZ();
var yaw=Player.getYaw();
var deltaX=Math.sin(yaw)*blocks;
var deltaZ=Math.cos(yaw)*blocks;
var block=getTile(Math.round(x+deltaX),Math.round(Player.getY()),Math.round(z+deltaZ)));
//Of course, you have to consider about pitch if you are thinking about a light beam. Method: multiply by Math.cos(Player.getPitch());