Other great resources: Official JS API docs, Scripting Forum
WZscript (.vlo and .slo) to Javascript (.js)
- Aubergine
Under constuction!
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:
// 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:
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):
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.
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 Trigger | Javascript equivalent | Notes |
---|---|---|
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. |
init | Use eventGameInit() | Run the event when the script starts |
inactive | Not applicable in Javascript | Do 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:
// 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:
// 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 callback | Javascript equivalent | Notes |
---|---|---|
CALL_GAMEINIT | eventGameInit() | The game has started. |
CALL_DROIDDESIGNED | eventDesignCreated() | 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_BUILT | eventStructureBuilt() | A structure was built. |
CALL_RESEX_BUILT | ||
CALL_RESEARCH_BUILT | ||
CALL_FACTORY_BUILT | ||
CALL_MISSION_START | Not applicable | Javascript API doesn't currently have a concept of missions starting or ending. |
CALL_MISSION_END | ||
CALL_VIDEO_QUIT | eventVideoDone() | A video has finished playing. |
CALL_LAUNCH_TRANSPORTER | eventLaunchTransporter() | The transporter "Launch" button was pressed. |
CALL_START_NEXT_LEVEL | eventStartLevel() | A new level has started. (slightly different to WZscript meaning) |
CALL_TRANSPORTER_REINFORCE | A transport carrying reinforcements has arrived on the map. | |
CALL_MISSION_TIME | eventMissionTimeout() | The mission timer has reached 0. |
CALL_ELECTRONIC_TAKEOVER | eventObjectTransfer() | An object is captured by Nexus link or transferred between allies. |
CALL_UNITTAKEOVER | ||
CALL_RESEARCHCOMPLETED | eventResearched() | A new technology has been researched. |
CALL_STRUCT_ATTACKED | Something was attacked. | |
CALL_DROID_ATTACKED | ||
CALL_ATTACKED | ||
CALL_TRANSPORTER_OFFMAP | eventTransporterExit() | A transport leaves the map. |
CALL_TRANSPORTER_LANDED | eventTransporterLanded() | A transport lands. |
CALL_BUILDLIST | Not yet implemented | The build list was opened. |
CALL_BUILDGRID | Not yet implemented | A droid was ordered to build something. |
CALL_RESEARCHLIST | Not yet implemented | The research list was opened. |
CALL_MANURUN | Not yet implemented | New templates are available to manufacture. |
CALL_MANULIST | Not yet implemented | The manufacture list was opened. |
CALL_BUTTON_PRESSED | Not yet implemented | A button in the UI was pressed. |
CALL_DESIGN_QUIT | Not yet implemented | The droid designer was closed. |
CALL_OBJ_DESTROYED | eventDestroyed() | Something was destroyed. |
CALL_DROID_DESTROYED | ||
CALL_STRUCT_DESTROYED | ||
CALL_FEATURE_DESTROYED | ||
CALL_OBJ_SEEN | eventObjectSeen() | Sensors detected a new object. |
CALL_DROID_SEEN | ||
CALL_STRUCT_SEEN | ||
CALL_NO_REINFORCEMENTS_LEFT | eventTransporterDone() | The player has transported all their remaining units from one map to another. |
CALL_DESIGN_WEAPON | Not yet implemented | A weapon turret was selected in the droid designer. |
CALL_DESIGN_SYSTEM | Not yet implemented | A systems turret was selected in the droid designer. |
CALL_DESIGN_COMMAND | Not yet implemented | A command turret was selected in the droid designer. |
CALL_DESIGN_BODY | Not yet implemented | A body was selected in the droid designer. |
CALL_DESIGN_PROPULSION | Not yet implemented | A propulsion was selected in the droid designer. |
CALL_ALL_ONSCREEN_DROIDS_SELECTED | eventSelectionChange() | The user selected one or more droids/structures. |
CALL_PLAYERLEFT | eventPlayerLeft() | A player left the fame. |
CALL_ALLIANCEOFFER | Not yet implemented | An alliance has been offered. |
Expression equivalents
Javascript doesn't have expression triggers – instead, just put the expression in your function...
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:
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()
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:
// 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:
- Boolean
- String
- Number
- Object
- Array – I highly recommend you learn about the Iteration Methods of array objects – they will save you a lot of time and make your code cleaner and more reliable.
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):
- .type — Defines the type of a game object – the .type of Objects.
- POSITION
- PLAYER_DATA — Indicates the object contains player data.
- DROID
- RESEARCH_DATA
- STRUCTURE
- FEATURE
- AREA
- GROUP
- getObject() — Three ways to retrieve a specific object...
- label() — Retrieve the object associated with a label...
- hackGetObj() — Retrieve a game object based on it's type, player and ID...
- objFromId() — Retrieve a game object based on it's ID...
- droidFromId() — Get an object based on it's object ID and player ID...
- objFromId() — Retrieve a game object based on it's ID...
- removeObject() — Remove a game object from the map...
- removeStruct() — Immediately remove a structure object from the map...
- Data objects — These objects relate to players and game config ("stats")...
- Weapon Object — An object describing a weapon turret...
- Group Object — A group of Game objects...
- Template Object — An object describing a droid template...
- Research object — Describes various attributes related to a specific researchable technology.
- Player object — Specifies useful static information about a specific player in the game.
- Game objects — The common properties for all objects that appear on the map such as droids, features and structures.
- Structure object — Describes a structure (something a truck can build) on the map.
- .status — Defines the build status of a structure – the .status of a Structure object.
- BEING_BUILT
- BUILT
- BEING_DEMOLISHED — This constant is no longer available, but this article provides some guidance on dealing with structure demolition...
- .stattype — The .stattype of a Structure object and, in Warzone 3.2 and above, also certain Feature objects...
- HQ
- WALL
- POWER_GEN
- SAT_UPLINK
- GATE
- CYBORG_FACTORY
- ARTIFACT — Indicates an artifact Feature object...
- COMMAND_CONTROL
- FACTORY
- LASSAT
- REPAIR_FACILITY
- BUILDING — A Feature object representing a building...
- DEFENSE
- VTOL_FACTORY
- RESEARCH_LAB
- OIL_RESOURCE — Indicates an oil resource Feature object...
- REARM_PAD
- OIL_DRUM — Indicates an oil drum (barrel) Feature object...
- RESOURCE_EXTRACTOR
- .status — Defines the build status of a structure – the .status of a Structure object.
- Droid object — Droids are mobile game objects (items on the map), and have a huge number of properties and related API features...
- .droidType — Defines the type of a droid – the .droidType of a Droid object.
- DROID_ANY — Used to bypass droid type filtering in functions that list or count droids.
- DROID_TRANSPORTER — A cyborg transporter (or possibly a super transporter in Warzone 3.1 Beta 4 and earlier), capable of airlifting droids to some other location on the map.
- DROID_REPAIR — A droid that has a repair turret, capable of repairing other droids.
- DROID_PERSON — A droid that uses "legs" propulsion, for example a civilian or a scavenger machinegunner.
- DROID_SUPERTRANSPORTER — A heavy transport unit, capable of airlifting any type of droid (including VTOLs) to some other location on the map...
- DROID_CONSTRUCT — A construction truck or a cyborg engineer.
- DROID_SENSOR
- DROID_ECM — A droid that has an Electronic Counter Measures (radar jammer) turret.
- DROID_COMMAND — A commander unit, to which other units can be assigned.
- DROID_CYBORG — A cyborg warrior capable of attacking the enemy.
- DROID_WEAPON — A droid capable of attacking other droids.
- .order — Defines the order which a droid is currently performing (the .order property of a Droid object) or must perform (orderDroid*() functions).
- DORDER_HELPBUILD — Instruct a construction droid to help with an existing structure building site.
- DORDER_RECOVER — Order a droid to recover a collectible item such as an oil barrel or artefact (crate).
- DORDER_DISEMBARK
- DORDER_GUARD — Instruct a droid to guard a structure.
- DORDER_TEMP_HOLD — Use DORDER_HOLD instead of DORDER_TEMP_HOLD.
- DORDER_RTR — Instruct a land droid to go to a repair facility for repairs.
- DORDER_EMBARK
- DORDER_UNUSED — As it's name suggests, this constant is not used.
- DORDER_CIRCLE — Instruct a VTOL to circle around a specific location.
- DORDER_HOLD — Instruct the droid to hold its current position until instructed otherwise.
- DORDER_SCOUT — Instruct a droid to "scout" to a new location.
- DORDER_OBSERVE — Instruct a sensor droid to observe (target) a Droid object, Structure object, or even a Feature object.
- DORDER_RTR_SPECIFIED — Instruct a land droid to go to a specific repair facility for repairs.
- DORDER_DESTRUCT — Instruct a droid to self-destruct!
- DORDER_RETREAT — Instruct a droid to retreat to a pre-defined retreat point. Does not retreat to HQ! Read docs before using!
- DORDER_NONE — Indicates that a droid is currently idle.
- DORDER_BUILD — Instruct a construction droid to build a Structure object at a specific location.
- DORDER_ATTACK — Instruct a droid to attack something.
- DORDER_LINEBUILD — Indicates that a construction droid is building a line of structures (eg. a long wall).
- DORDER_REARM — Instruct a VTOL to return to a rearming pad for repairs and rearming.
- DORDER_RECYCLE — Recycle a droid...
- DORDER_FIRESUPPORT — Assign a attacker droid to a sensor droid so that it can attack whatever the sensor droid targets.
- DORDER_RTB — Instruct a droid to return to your base.
- DORDER_MOVE — Instruct a droid to move to a new location.
- DORDER_COMMANDERSUPPORT — Assign an attacker droid to a commander droid so that it will attack whatever the commander droid targets.
- DORDER_STOP — Instruct a droid to stop what it's doing.
- DORDER_DEMOLISH — Instruct a construction droid to demolish one of your structures.
- DORDER_PATROL — Instruct a droid to patrol between it's current location and a specified location, attacking any enemies it detects along the way.
- DORDER_DROIDREPAIR — Instruct a repair droid to repair a damaged Droid object.
- DORDER_REPAIR — Instruct a construction droid to repair a damaged Structure object.
- .action — Defines the current action a Droid object is taking to fulfil its current .order.
- .droidType — Defines the type of a droid – the .droidType of a Droid object.
- Feature object — Feature objects describe inanimate game objects such as oil barrels and resources, artefacts, log cabins and skyscrapers, trees, etc.
- Structure object — Describes a structure (something a truck can build) on the map.
- Location objects
- Position object — Defines a position on the map via its x,y co-ordinates.
- Area object — Specifies the top-left and bottom-right co-ordinates of an area of the map.
Custom objects
Making your own objects in Javascript is really trivial:
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.
If and Switch statements
If statements don't require much explanation...
if (a == b) { // do stuff } else if (a == c) { // do stuff } else { // do stuff }
And switch statements are also pretty easy to use:
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
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 external | Javascript global | Notes |
---|---|---|
mapWidth | mapWidth | The width of the map, in tiles. |
mapHeight | mapHeight | The height of the map, in tiles. |
gameInitialised | Not applciable | If you want to recreate this, use the following code: function eventGameInit() { this.gameInitialised = true; } |
selectedPlayer | selectedPlayer | The current id of the human player on the local machine. |
gameTime | gameTime | The elapsed time since the game started, in milliseconds. |
multiPlayerGameType | isMultiplayer | Is this an online multiplayer game? |
multiPlayerMaxPlayers | maxPlayers | The number of player positions on the current map. |
multiPlayerBaseType | baseType | The base type setting for the current game. |
multiPlayerAlliancesType | alliancesType | The alliance mode for the current game. |
scrollX | Not yet implemented | The x1 co-ordinate of the scroll region set by setScrollParams(). |
scrollY | Not yet implemented | The y1 co-ordinate of the scroll region set by setScrollParams(). |
scrollWidth | Not yet implemented | The width of the scroll region set by setScrollParams(). |
scrollHeight | Not yet implemented | The height of the scroll region set by setScrollParams(). |
cursorType | Not yet implemented | The current mouse pointer mode. |
intMode | Not yet implemented | The current game mode (eg. design, intelligence, etc) |
targetedObjectType | Not yet implemented | The type of object currently under the mouse pointer. |
boolextraVictoryFlag | Not applicable | You can trigger gameOverMessage() from your script. Use your own variables if you want to keep track of game state. |
boolextraFailFlag | ||
GameLevel | difficulty | See Difficulty Levels for more information. Note, in JS API this property is read-only. |
In Javascript, there are also several new globals:
- version – the Warzone version the script is running under
- mapName – the name of the map used for the current game
- powerType – the power type for the current game (derrick power per second before upgrades)
- scavengers – is the Scavenger Faction enabled?
- scavengerPlayer – the ID of the scavenger faction, or -1 if they are disabled
- me – the player ID that your script is running as
- scriptName – name of the script that is running (useful for include() files)
- groupSizes[] – an array defining size if each of your Groups
- playerData[] – an array of Player objects describing each player in the game (except scavengers)
- derrickPositions[] – an array of pre-placed derricks on the map
- startPositions[] – an array of player starting positions on the map
Big list of everything
For a big list of everything in the JS API, see Quick Reference
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!
Availability 3.1+
Requires:
- Warzone 3.1 or above is required to use the Javascript API
Contents
Jump to: