If you've become accustom to using the Warlock Scripting Language, but want more power, then Javascript is the way to go. It has all the features of a object-oriented scripting language, and provides all the same functionality that a standard script offers as well, making it a very powerful (and superior) alternative.


Javascript TutorialsEdit

If you're unfamiliar with Javascript, and would like a general tutorial (not Warlock-oriented), we recommend any of the following links:

Note that some of these tutorials are browser-based, but the language basics are all the same.

WSL PrimerEdit

It would be best to understand all of the concepts in the Warlock Scripting Language if you want to understand all that's available to you in Javascript, as some of the more advanced concepts (match/matchWait, actions) are also available in Javascript.

Javascript APIEdit

Warlock pre-defines several special variables and lists that are usable by your script for retrieving data from the game, performing game-related functions, and other misc. utilities.

The "arguments" arrayEdit

Arguments passed to your script via the entry in Warlock are put into this array. It is a basic Javascript array, so you can loop through it and access it like a normal array, i.e.:

for (i in arguments) {
  if (arguments[i] == "-help") {

The "script" objectEdit

The script object is basically a 1-to-1 mapping of functions from the Warlock Scripting Language. In general, the syntax is exactly what you would expect. For example, in WSL you might have the following script:

put prep spell 10
waitfor You are fully prepared
put cast

pause 5
echo Spell has been cast!

Which would map to the following Javascript:

script.put("prep spell 10");
script.waitFor("You are fully prepared");

script.echo("Spell has been cast!");

Basic Command TableEdit

This table shows the mapping from a 1 line WSL example to a Javascript example

WSL Example Javascript equivalent
put 'Hello script.put("'Hello");
echo Waiting... script.echo("Waiting...");
pause 3 script.pause(3);
move north script.move("north");
nextroom script.waitNextRoom();
wait script.waitForPrompt();
waitfor You feel fully prepared script.waitFor("You feel fully prepared");
waitforre You feel fully .+ script.waitForRe("You feel fully .+");
exit script.exit();
setVariable x 1 script.setVariable("x", "1");
getVital health foo foo = script.getVital("health");
getComponent mechlore exp Mechanical Lore mechlore = script.getComponent("exp Mechanical Lore");
To retrieve a server side variable called x: var x = script.getVariable("x");

Actions and MatchesEdit

The biggest difference in the Javascript interace is the way that actions and match/matchWait are performed. The basic execution/flow is similar, but in Javascript we use function objects rather than labels, and a match array for match/matchWait. Let's first take a look at an example matchWait

match Locked mind lock
match NotLocked Overall state of mind: clear
put exp primary

  # do something

  # do something else

In this script, we are telling Warlock to wait for a match from a list of 2 possible text matches, and when that match happens, to jump to the specified label. In Javascript, we create a match array, where each match is associated with a function instead of a label, and pass that to matchWait. The above script would look like this in Javascript:

function locked () {
 // do something

function notLocked () {
 // do something else

var matches = new MatchList(); // starts recording text to be compared at matchWait()
matches.match("mind lock", locked);
matches.match("Overall state of mind: clear", notLocked);
script.put("exp primary");


var matches = new MatchList(); // starts recording text to be compared at matchWait()
var locked = matches.match("mind lock");
var notLocked = matches.match("Overall state of mind: clear");
script.put("exp primary");
var match = matches.matchWait();

if(match == locked) {
  // do something
} else if(match == notLocked) {
  // do something else

In addition to match() is matchRe() which compiles the given text as a Regular Expression. The function passed to matchRe should have an argument that stores the matches from the regex.

  • matchRe(regex, function)
    • regex: a regular expression in string form
  • matchRe(regex, ignoreCase, function) - Not implemented
    • ignoreCase: true/false. whether or not to ignore case when matching text against the regular expression (default: false)


function mindState(groups) {
  script.echo("State of mind is " + groups[1]);
var matches = new MatchList();
matches.matchRe("Overall state of mind: (\\w+)", mindState);

If you need to reuse a MatchList object, the method restart() is available to restart recording. Also match(), matchRe(), and matchWait() will restart recording if it isn't recording already.
If you need to pass some arguments to your function, you can use an anonymous function to call your function.

function talk(person, message) {
  script.put("'}" + person + " " + message);

matches = new MatchList();
matches.match("Eanur just arrived", new Function() { talk("Eanur", "Nice boots."); });

An action in Javascript looks the same as a match, but due to the nature, a matchWait is not required (since it is more of an event-based API). In WSL you might have the following code:

action goto ReadPaths when Obvious paths:

 # executed when the game receives "Obvious paths" like a match

Which, when translated to Javascript would look like:

function readPaths() {
 // executed when the game receives "Obvious paths" like a match

script.addAction(readPaths, "Obvious paths:");

In WSL, you also have the ability to read regex match-groups from Actions via the $1-$9 special variables. An example snippet from WSL below:

action goto MovedRoom when Obvious paths: (.+).
move north

  setvariable paths $1
  # $0 == Obvious paths: northwest.
  # $1 == northwest
  echo paths = %paths

Instead of using special variables, we pass in all match groups as arguments to your action function. The first argument is always the "entire" match (also known as regex group 0), then every argument after that is a group matching from your regex. The above script would translate to:

function movedRoom (text, paths) {
 // text == Obvious paths: northwest.
 // path == northwest
 script.echo("paths = " + paths);

script.addAction(movedRoom, "Obvious paths: (.+).");


Including another JS script into your initial script is possible using the built in include function.

// Include ranged.js


WSL has the command TIMER to keep track of elapsed time. JS has script.setInterval(command, period) and script.setTimeout(command, delay). They have the same semantics as the typical usage as in [1].

Special VariablesEdit

This is a table of all the other special variables provided by Warlock, and an explanation of each variable's value.

Variable name Value
roundtime An integer describing the amount of time left in the current roundtime (or 0).
casttime An integer describing the amount of time left in the current casttime (or 0). (Only seen in GS4)
leftHand A string with the contents of the left hand.
rightHand A string with the contents of the right hand.
spell A string with the spell currently being prepared.
monstercount An integer containing the number of monster-bolded NPCs in the room.