Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Warning

Under constuction!

Excerpt

This guide is designed to help developers who are converting their old WZScripts to the new Javascript API...

 

Introduction

In the old Warzone scripting (WZscript) system, two files were required:

  • .slo – the main wz script
  • .vlo – variable definitions

In Javascript, these are merged in to a single file:

  • .js – variable definitions and your main script

Tip: You can also split your script in to several smaller scripts, and pull them in to a main script using include(). This can make working with large scripts much easier.

It is common for a script to deal with new or existing game components such as research topics, structures, unit bodies, propulsions, weapons etc. All these components are defined in appropriate text files like body.txt / body.ini, etc. In the old wzscript system, you had to define anything you wanted to use in the .vlo before you could use it in the .slo. In the new Javascript system, most Constants are pre-defined, and anything else (like a structure or component ID, etc) can simply be specified as a quoted string.

Note: If you are using the same value a lot, it's better to define a variable or constant and then use that throughout your script – see "Variables and Constants" section later.

Comments

There are two types of comments in Javascript:

Code Block
themeRDark
languagejavascript
linenumberstrue
// single line comment
var foo = "fish"; // can be put at end of lines
 
/* multi
line
comment */
 
var bar = /* can be put inside code */ "mammal";

Variables and Constants

Defining variables (read-write values) and constants (read-only values) is easy in Javascript:

Code Block
themeRDark
languagejavascript
titleSyntax for defining variables and constants
linenumberstrue
var <name> = <value>; // a variable
 
const <name> = <value>; // a constant

The <value> can be any data type you want – Javascript data types are discussed later.

Variable names are written in camelCase and constant names are written in UPPER_CASE, just for convention so it's easier to know if something can be changed or if it's read-only without having to find the declaration.

Your variable and constant names should be unique. For example, don't define a variable called "foo" and then define a constant called "foo" - there can only be one thing called "foo" (...within a given Scope).

Here's an example of defining a variable (with a string value) and a constant (with an array of strings as its value):

Code Block
themeRDark
languagejavascript
linenumberstrue
var myPythonBody = "Body11ABT";
 
const MY_RESEARCH = [
	"R-Vehicle-Body11",
	"R-Vehicle-Prop-Tracks",
	"R-Vehicle-Prop-Hover"
];

You'll notice that you no longer need to define the data type like you did in .vlo and .slo files.

Warning

With the current Warzone Javascript environment, it's not possible to define constants within functions, they can only be defined in the main part of your script (which is why you usually see them at the top of scripts). For now, you can only use variables in functions.

Some additional great information from Mozilla Developer Network: Values, Variables and Literals

Event/trigger concept

Like WZscript, the Javascript API is event-driven. However, there are some important differences between the way in which WZScript events work and the way Javascript events work.

WZScript events required you to define what would trigger the event, whereas most Javascript events have pre-defined triggers. So, let's start by looking at the way in which events are triggered (more detailed examples are shown later)...

WZScript TriggerJavascript equivalentNotes
wait, <time>Use queue()Wait for <time> milliseconds, then run the event function once
every, <time>Use setTimer()Run the event function every <time> milliseconds
<callback>Use event*() functions

Run the event function when <callback> occurs.

<bool exp>, <time>Use setTimer() and check the <bool exp> inside your event function.Every <time> milliseconds, check if <bool exp> is true and if so run the event function.
initUse eventGameInit()Run the event when the script starts
inactiveNot applicable in JavascriptDo not run the event function until a trigger is assigned to it

To make things clearer, let's take a look at some example code...

Wait and Every equivalents

The queue() function is like the WZScript 'wait <time>' trigger:

Code Block
themeRDark
languagejavascript
titleWait triggers
linenumberstrue
// define our event handler, let's call it "foo"...
function foo() {
  // some code
}
 
// now let's queue that function to be run after 200ms...
queue("foo", 200);

The setTimer() is like the WZscript 'every, <time>' trigger:

Code Block
themeRDark
languagejavascript
titleEvery triggers
linenumberstrue
// define our event handler, let's call it "bar"...
function bar() {
  // some code
}
 
// now let's set a timer to run bar() every 300ms...
setTimer("bar", 300);

So, in both cases, you create a function and then you use either queue() or setTimer() to call that function after a certain amount of time. You can specify some extra data to pass in to your function, for more information on that click the links to see full documentation for queue() and setTimer().

Callback equivalents

Javascript's callback system is much simpler than WZScript – all you need to do is create a function with a specific name.

Almost all Javascript callbacks have parameters – click on the links in the table below to get full details and examples...

WZScript callbackJavascript equivalentNotes
CALL_GAMEINITeventGameInit()The game has started.
CALL_DROIDDESIGNEDeventDesignCreated()The player created a new droid design.

CALL_DROIDBUILT

eventDroidBuilt()A new droid was built by a factory or created by a script.
CALL_NEWDROID
CALL_POWERGEN_BUILTeventStructureBuilt()

A structure was built.

CALL_RESEX_BUILT
CALL_RESEARCH_BUILT
CALL_FACTORY_BUILT
CALL_MISSION_START(minus) Not applicableJavascript API doesn't currently have a concept of missions starting or ending.
CALL_MISSION_END
CALL_VIDEO_QUITeventVideoDone()

A video has finished playing.

CALL_LAUNCH_TRANSPORTEReventLaunchTransporter()The transporter "Launch" button was pressed.
CALL_START_NEXT_LEVELeventStartLevel()A new level has started. (slightly different to WZscript meaning)
CALL_TRANSPORTER_REINFORCE

eventReinforcementsArrived()

A transport carrying reinforcements has arrived on the map.
CALL_MISSION_TIMEeventMissionTimeout()The mission timer has reached 0.
CALL_ELECTRONIC_TAKEOVEReventObjectTransfer()An object is captured by Nexus link or transferred between allies.
CALL_UNITTAKEOVER
CALL_RESEARCHCOMPLETEDeventResearched()A new technology has been researched.
CALL_STRUCT_ATTACKED

eventAttacked()

eventAttackedUnthrottled()

Something was attacked.
CALL_DROID_ATTACKED
CALL_ATTACKED
CALL_TRANSPORTER_OFFMAPeventTransporterExit()A transport leaves the map.
CALL_TRANSPORTER_LANDEDeventTransporterLanded()A transport lands.
CALL_BUILDLIST(warning) Not yet implementedThe build list was opened.
CALL_BUILDGRID(warning) Not yet implementedA droid was ordered to build something.
CALL_RESEARCHLIST(warning) Not yet implementedThe research list was opened.
CALL_MANURUN(warning) Not yet implementedNew templates are available to manufacture.
CALL_MANULIST(warning) Not yet implementedThe manufacture list was opened.
CALL_BUTTON_PRESSED(warning) Not yet implementedA button in the UI was pressed.
CALL_DESIGN_QUIT(warning) Not yet implementedThe droid designer was closed.
CALL_OBJ_DESTROYEDeventDestroyed()Something was destroyed.
CALL_DROID_DESTROYED
CALL_STRUCT_DESTROYED
CALL_FEATURE_DESTROYED
CALL_OBJ_SEENeventObjectSeen()Sensors detected a new object.
CALL_DROID_SEEN
CALL_STRUCT_SEEN
CALL_NO_REINFORCEMENTS_LEFTeventTransporterDone()The player has transported all their remaining units from one map to another.
CALL_DESIGN_WEAPON(warning) Not yet implementedA weapon turret was selected in the droid designer.
CALL_DESIGN_SYSTEM(warning) Not yet implementedA systems turret was selected in the droid designer.
CALL_DESIGN_COMMAND(warning) Not yet implementedA command turret was selected in the droid designer.
CALL_DESIGN_BODY(warning) Not yet implementedA body was selected in the droid designer.
CALL_DESIGN_PROPULSION(warning) Not yet implementedA propulsion was selected in the droid designer.
CALL_ALL_ONSCREEN_DROIDS_SELECTEDeventSelectionChange()The user selected one or more droids/structures.
CALL_PLAYERLEFTeventPlayerLeft()A player left the fame.
CALL_ALLIANCEOFFER(warning) Not yet implementedAn alliance has been offered.

Expression equivalents

Javascript doesn't have expression triggers – instead, just put the expression in your function...

Code Block
themeRDark
languagejavascript
titleExpression triggers
linenumberstrue
var readyToAttack = false;
 
function attackIfPossible() {
	if (readyToAttack) launchMyAttack();
}
 
setTimer("attackIfPossible", 5000);
 
function launchMyAttack() {
	// some code to make your stuff attack
 
	// and avoid attacking again until we have build some more droids
	readyToAttack = false;
}
 
function eventDroidBuilt() {
	readyToAttack = (enumDroid(me, DROID_WEAPON).length > 10);
	if (!readyToAttack) {
		// build another weapon droid!
	}
}

Ok, that's a really terrible way to decide when to attack, but it's just for illustration purposes.

The equivalent to the expression trigger is the attackIfPossible() function. We call it every 5 seconds (5000ms) using setTimer(). Each time it runs, it checks to see if we're ready to attack and, if we are, an attack will be launched.

But do you ever really need to do this? We could ditch attackIfPossible() function and it's timer, and just change the code inside eventDroidBuilt() so that it will launchMyAttack() if we've got more than 10 weapon droids. This would do just the same, with much less code:

Code Block
themeRDark
languagejavascript
titleExpression triggers
linenumberstrue
function launchMyAttack() {
	// some code to make your stuff attack
}
 
function eventDroidBuilt() {
	if (enumDroid(me, DROID_WEAPON).length > 10) {
		launchMyAttack();
	} else {
		// build another weapon droid!
	}
}

There, much cleaner!

Init equivalent

Super simple – just use eventGameInit() (smile)

Inactive equivalent

In Javascript API there isn't really a concept of an inactive event. If you don't want to use an event, don't create a function for it heh.

If you want to use an event, but only under certain conditions, well, that's a more noble cause! Here's how to do it:

Code Block
themeRDark
languagejavascript
titleDynamically enable/disable an event
linenumberstrue
// create the event function, but with a different name
function doStuff(victim, attacker) {
	// code
}
 
// let's activate it
eventAttacked = doStuff; // we're now listening to eventAttacked!
 
// and let's de-activate it:
delete eventAttacked;

Even more events...

The Javascript API has a load of other events not already discussed above. For a complete list and related documentation, see: Events & Timers.

Also, see Environment Sequences for some info on the order in which certain things happen.

Data types

Ok, before going any further I think we should take a look at the Javascript data types. The ones you'll use most are:

Click any of those links to see vast amounts of documentation about them on the awesome Mozilla Developer Network (one of the great advantages of switching to Javascript is that there's reams of great information available on the internet!).

There are others like Date and RegExp, but I doubt you'll have need for those.

Note that there's some things missing from the Javascript environment used by Warzone (at the time of writing this), such as iterators. For a list of what's currently available in the JS environment, check out Script Environment.

Warzone data types

The JS API has a bunch of well defined object types as follows (click links for more info):

Child pages (Children Display)
alltrue
depthall
pageObjects
excerpttrue

Custom objects

Making your own objects in Javascript is really trivial:

Code Block
themeRDark
languagejavascript
titleMaking custom objects
linenumberstrue
var foo = {
   bar: "fish",
   baz: function() { return this.bar; }
}
 
console(foo.baz()); // "fish"

There's a bunch of advanced stuff you can do, such as adding getter/setter properties, hidden properties, read-only properties, etc., but that's beyond the scope of this article!

Expressions, Operators, Assignment

Everything you need to know is here: Expressions & Operators

Also, you need to understand what Falsey & Truthy are. (wink)

If and Switch statements

If statements don't require much explanation...

Code Block
themeRDark
languagejavascript
titleif .. else if .. else
linenumberstrue
if (a == b) {
  // do stuff
} else if (a == c) {
  // do stuff
} else {
  // do stuff
}

And switch statements are also pretty easy to use:

Code Block
themeRDark
languagejavascript
titleswitch ... case ... default
linenumberstrue
eventAttacked(victim, attacker) {
	switch (victim.type) {
		case DROID: console("Droid attacked!"); break;
		case STRUCTURE: console("Structure attacked"); break;
		case FEATURE: console("Feature attacked"); break;
		default: console("No idea what was attacked!!");
	}
}

Before using switch statements, do some background reading.

Looping: While, Do, For, etc...

There's loads of ways to loop in Javascript!

There's actually a few more, but those listed above are the most widely used.

Like I said earlier, I highly recommend you learn about the Iteration Methods of Array objects!!

Casts 

See: Data type conversion

Custom & Script functions

Or, as they're known in Javascript: Functions (big grin)

Note: You can't use the 'const' keyword inside functions (not in the current JS API anyway). Also, the 'let' keyword is not currently supported.

Javascript (as in the language) provides a vast array of it's own functions, usually as methods of objects though. You can see a list of some of the ones I use most here: Native JS Features.

And the JS API (as in the stuff Warzone adds to the environment) provides an insane number of awesome Functions that let you do just about anything!

Local variables

See: Scopes & Closures and Code sandboxing.

Macros

There's no concept of "macros" in Javascript – just use constants, variables or functions as applicable.

Script function externals

In the JS API, script function externals are called "globals". Here's a comparison between WZScript and Javascript globals...

WZscript externalJavascript globalNotes
mapWidthmapWidthThe width of the map, in tiles.
mapHeightmapHeightThe height of the map, in tiles.
gameInitialised(minus) Not applciable

If you want to recreate this, use the following code:

Code Block
themeRDark
languagejavascript
linenumberstrue
function eventGameInit() {
	this.gameInitialised = true;
}
selectedPlayerselectedPlayerThe current id of the human player on the local machine.
gameTimegameTimeThe elapsed time since the game started, in milliseconds.
multiPlayerGameTypeisMultiplayerIs this an online multiplayer game?
multiPlayerMaxPlayersmaxPlayersThe number of player positions on the current map.
multiPlayerBaseTypebaseTypeThe base type setting for the current game.
multiPlayerAlliancesTypealliancesTypeThe alliance mode for the current game.
scrollX(warning) Not yet implementedThe x1 co-ordinate of the scroll region set by setScrollParams().
scrollY(warning) Not yet implementedThe y1 co-ordinate of the scroll region set by setScrollParams().
scrollWidth(warning) Not yet implementedThe width of the scroll region set by setScrollParams().
scrollHeight(warning) Not yet implementedThe height of the scroll region set by setScrollParams().
cursorType(warning) Not yet implementedThe current mouse pointer mode.
intMode(warning) Not yet implementedThe current game mode (eg. design, intelligence, etc)
targetedObjectType(warning) Not yet implementedThe type of object currently under the mouse pointer.
boolextraVictoryFlag(minus) Not applicable

You can trigger gameOverMessage() from your script.

Use your own variables if you want to keep track of game state.

boolextraFailFlag
GameLeveldifficulty

See Difficulty Levels for more information.

Note, in JS API this property is read-only.

In Javascript, there are also several new globals:

Big list of everything

For a big list of everything in the JS API, see Quick Reference (smile)

Error Handling

See: Error Handling

Questions?

As you port from WZscript, you'll likely have questions - drop a comment below and i'll do my best to answer them!

Div
classbox
Availability
Status
colourGreen
title3.1+

Requires:

  • Warzone 3.1 or above is required to use the Javascript API
Div
classbox
Contents

Jump to:

Table of Contents
maxLevel5