Blog from March, 2012

With all the recent activity around scavengers, I decided to make a backport that adds the missing scavengerPlayer constant to the JS API in the Warzone 3.1 branch. For more information, see backport.scavengerPlayer.js (smile)

Update: v0.2 now released - turns out that scavs should always be player 7, except on maps that have more than 8 players in which case they should be the value of maxPlayers. This is for backwards compatibility reasons.

structureIdle.js v0.1 released

This backport fixes a bug in the structureIdle() function whereby it wasn't checking the structure's construction status before returning true.

For more information and to download the backport, see backport.structureIdle.js.

Warzone 3.1 beta 5 has landed!

In terms of the JS API there's just a single change: DROID_SUPERTRANSPORTER has been added.

It might seem a small change but now we can properly differentiate between the two droid transporters! There's still no properties that tell us how many units are on them though.

version.js v0.2 released

I've also updated version.js to more accurately report Warzone 3.1 Beta 4. I'm waiting to see what happens in the next Warzone release before adding support for Beta 5.

API Version History

I've now completed the first pass at documenting the JS API version history, specifically what features have been added, removed or changed in the JS API.

The Compatibility Matrix section now provides some great resources for scripters:

I still need to investigate objects (like base object, droid object, etc) to complete the project, but the information gathered so far is already very useful. Hope it helps (smile)

dorder.js v0.1 released

Dorder.js adds missing DORDER constants to your JS environment, allowing you to issue a wider range of orders to droids.

Get it while it's hot: backport.dorder.js (smile)

Initial backportFunction()

I've finally finished my first draft at a function that will replace an existing non-configurable JS API function in the global scope with a custom function I supply.

It achieves the following goals I'd set myself:

  • The result must be completely transparent to JS scripts - other than including a backport library there should be no other code changes or noticeable effects.
  • The original functions must still be easily available
  • It should be easy to determine if a function has been backported
  • It should be trivially easy to enable backporting on JS API functions, which are all read-only and non-configurable.
Here's the result so far:
function backportFunction(sFuncName,fNew) {
  // store funcs where eval can get at them
  eval("backportFunction.fOld = "+sFuncName);
  backportFunction.fNew = fNew;
  // make sure it's not already backported
  if (!!backportFunction.fOld.backport) return;
  // construct the backport
  var backport = "function "+sFuncName+"(){return "+sFuncName+".run.apply(this,arguments);} "+sFuncName+".backport = backportFunction.fOld; "+sFuncName+".run = backportFunction.fNew;";
  // now do the eval
  eval.call(null,backport);
  // clear up our mess
  delete backportFunction.fOld;
  delete backportFunction.fNew;
}

That took a surprisingly long time to build – almost 3 hours due to difficulties testing and debugging in Warzone's JS environment, not to mention some interesting side-effects caused by the way JS API functions are created.

Anyway, now let's say I want to customise the JS API's enumDroid() function. It's read-only, non-configurable, and to this day I still have no idea how to determine where its actually stored despite doing lots of sniffing around the WZ JS environment to find out just what exactly is available to us.

I'll just use something simple in this example – I'll keep the same functionality as the original enumDroid() but I'll send a "running" message to the console whenever enumDroid() is called:

backportFunction("enumDroid",function() {
  console("running");
  return enumDroid["backport"]();
});

After making that call, the global enumDroid() function is now under my control. Whenever it's called, it transparently calls the new function I've passed in. As you can see, enumDroid() now has a new property ".backport" that's a reference to the original enumDroid() function from the JS API - so I can still get at the original whenever I want to.

In my script I just use enumDroid() as usual, my little hack is completely transparent. Every time enumDroid() is called, I get a "running" message in the console window to show it's working. Awesome win!

My next task is to think of a neat way to modularise all the things I want to apply to enumDroid(). For example, there's a bunch of properties that would randomly appear, some that were buggy and some that were missing depending on the Warzone version the script is running in. I want to find a way of dynamically adding "hacks" that fix bugs, backport features or extend what the JS API functions do.

The various enum functions are a good place to start as they all work in roughly the same way - you call them with some parameters and they return a list of objects. I've already got working prototypes for backporting enumBlips() to 3.1 Beta 1, and adding things like the .canHitAir and .canHitLand properties to droid objects in enumDroid() and enumStructure(), plus loads of other useful bits and pieces.

Anyway, it's 5:30am and I've got a day full of meetings tomorrow so I need to head to bed.