Page 1 of 1

rules.js for map-mods - feedback wanted...

Posted: 10 Oct 2012, 05:50
by aubergine
Hi All,

I'm currently in the process of updating the Enhanced SitRep mod to work on Warzone 3.1 RC 3. It adds much better game situation reporting, with a bunch of custom messages and so on (see the topic for more info and, soon, a new release).

I wanted to create this topic to get some feedback of some future plans I have for the mod. My ultimate hope is that it will eventually become a standard part of Warzone (3.2 branch or later) and I want it to be flexible from a map-modding perspective.

The mod is essentially a custom rules.js that's been extended to do a bunch of additional stuff, and then split in to several small JS files to allow granular modding by map makers.

Of course, map makers can already bundle their own custom rules.js (I assume?) so why would anyone want to use my version instead? Well, one of the drawbacks I foresee is that if rules.js in Warzone changes, you'd have to go round editing/updating all your maps which will be a real PITA. But, if you can just override bits of rules.js, sort of editing it's "settings" without the need to change the bulk of its code, your map-mods would be much more resilient to changes in the game's version of rules.js.

As I mentioned there's a bunch of small js files that can be overridden, they are currently:
  • multiplay/skirmish/rules.spectators.js // Define which players on the map are spectators
  • multiplay/skirmish/rules.init.enableStructures.js" // Structrues to enable for all players
  • multiplay/skirmish/rules.init.enableComponents.js // Components to enable for all players
  • multiplay/skirmish/rules.init.enableTechnologies.js // Technologies to enable for all players
  • multiplay/skirmish/rules.init.structureLimits.js // Structure limits for all players
  • multiplay/skirmish/rules.init.baseType.js // Effect of baseType setting for all players
  • multiplay/skirmish/rules.init.humanPlayer.js // Additional set-up for localhost human payer
  • multiplay/skirmish/rules.init.spectatorPlayer.js // Additional set-up for spectator players
  • multiplay/skirmish/rules.report.msg.js // Situation reporting taxonomy (report definitions)
  • multiplay/skirmish/rules.victory.js // Victory conditions and "is player alive" determination
I'm not sure if that's granularity overkill, but my assumption is that in most cases you'd want fine-grained control over which bits of the game rules to customise?

Player set-up

Modding the scripts above will allow everything from starting techs to base type effects to be customised via a map-mod, for all players, the localhost human player and spectators.

Spectator support

I know there's issues with implementing full spectator support currently, but in 3.2 there's new JS API features that might make life a lot easier.

For example, spectator players could have all their buildings/units automatically removed and a sat uplink placed at their starting position so they can see whole map.

Also, they can be excluded from game victory conditions so they don't ever see a "game over" message.

Victory conditions

Over the past year I've seen people requesting things like:

* King of the hill type games
* Ability to have a "best of 3" type match
* Ability to "restart/reset the map" without exiting the game
* Tower-defence type scenarios

I perceive that these things could be handled, in the WZ 3.2 branch, via custom victory conditions, etc.

Situation reporting

The SitRep mod has a customisable taxonomy that makes it pretty easy to create new situation reports - eg. audio messages, console messages, etc.

This would enable custom reporting to be added to your maps, eg. you could override the main taxonomy (rules.report.msg.js) or just make small tweaks to it (via rules.victory.js).

The SitRep stuff is based on game events. Each time an event is triggered it gets "transcribed" in to a string (eg."objectSeen.defense.antiair.Enemy") and that's used to find an appropriate situation report object in the rules.report.msg file.

As well as being able to play audio and stuff like that, javascript functions can be triggered as well - so you can do all sorts of crazy stuff if you want to. (Note: Currently only from perspective of localhost human player, but I'm working on some other stuff that will allow this stuff to be used in AIs, etc).

Feedback wanted

So, basically I'm looking for any feedback you might have as a map maker. What sort of things would you want to mod, how would you want to mod them, what are use cases / requirements, etc? I'm keen to tailor this mod to your needs (:

Re: rules.js for map-mods - feedback wanted...

Posted: 11 Oct 2012, 23:39
by aubergine
Any comments?

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Oct 2012, 02:36
by NoQ
What i'd really like to have is a "soft include" directive in JS, which includes a file (or even a folder, something like rules.js.d/10-spectators.js etc., if you know what i mean), and fails silently if not found(without an error, probably returns the number of files included). And then add such directive to the base game's rules.js. This could be a map-modding heaven.

As for spectators ... i think a player should be considered to be a spectator if it has a satlink pre-placed, and then at most one truck and one CC (forced by FlaME) and nothing else. Then satlink is spared, everything else is removed (since no-bases mode is already controled by js), and victory conditions are disabled.

It could be fancy to have a report of what players research (eg. "NoQ has just researched engineering", "NoQ has started researching Machinegun", i did it for 2.3 but i think it's not possible in 3.1 (waiting at least for chat()).

Will probably write more when i have a bit better connection ...

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Oct 2012, 10:04
by Per
Another idea is to have overrides on the event level instead of file level. Say, if a map comes with its own rules-override.js file, the game will check if an event is present in that file before checking the main rules.js

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Oct 2012, 20:31
by aubergine
@NoQ:

A soft include() is great idea! And I like too the idea of "include anything in this directory if it exists", primarily because that would allow normal mods to link with rules.js for all games, and still allow map mods to link with rule.js on a map-specific basis.

Maybe call the functions: includeIfFound(filepath/filename) and includePath(filepath/filemask), the latter including all .js files in the path unless otherwise stated by a filemask (eg. "foo*.js" to pull in all js files starting with "foo").

I will implement the spectator = player slot with pre-placed sat-uplink, that should be easy to do and actually make my code much cleaner.

Victory conditions are already disabled for spectators, and they are not tracked as allies or enemies (from perspective of victory condition checks for other players), regardless of whether they are in an alliance or not. So hopefully that angle is already covered.

For research, yes it will require 3.2 branch. If chat() can be updated to allow "hidden" messages, I can make rules.js report new research to spectators, the spectator's rules.js will then completeResearch() so they get intel report, and also drop them a console message so they can easily monitor who researches what. Also, in 3.2 player names are accessible via API's playerData object so it will be very user friendly :)

@Per:

Would the mod want to "own" the event, in other words if mod listens for even then rules.js is not allowed to? Or would the mod expect to share the event (and maybe return false from the listener if it wants to stop rules.js being told)?

If the latter, then that's fairly easy to achieve with some code I already have. The mod would listen to event in usual manner, just like normal, and even if the rules.js is also listening to the same event, it will just work :) Basically I define the event handler as a global accessor property (getter/setter) so when a script listens for the event, it's function actually gets put in to an array (via the setter). Then, when the event is triggered, the getter calls each function in the array in turn, passing the event args in - the script listening to events is none the wiser and requires no modifications at all :) I can easily extend that code to allow an event listener to return false to prevent other listeners in the array from being fired.

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Oct 2012, 21:21
by aubergine
Hrm, with spectators being defined as player slots that have pre-placed sat-uplink, the player game set-up screen could make it obvious what slots are for spectators by placing an eye icon in the team column (so instead of team letter, a spectator slot would show eye icon)...

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Oct 2012, 21:25
by aubergine
One other thing I'd love to do for spectators, but not sure how, is when a player designs a droid, make that design available to the spectator so they can view it in the design tool to see it's stats. (they wouldn't be able to make droids because they have no factories/trucks)

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Nov 2012, 13:54
by Per
aubergine wrote:Would the mod want to "own" the event, in other words if mod listens for even then rules.js is not allowed to? Or would the mod expect to share the event (and maybe return false from the listener if it wants to stop rules.js being told)?
The mod event should override the base rules.js event. Allowing the mod event to decide if the rules.js event should also be called afterward using a return value from the mod event might be a good idea, too. However, I'm not entirely sure how this should be done, code-wise. The mod script may have to run in its own script context (ie has totally separate globals). Another way to solve it would be duplicate set of events with a mod suffix (ie <event name>_mod(parameters))...

I'm still not clear on why a "soft include" is necessary or desirable. Is not what you really want a way to just drop a 'map.js' into a '<map>.wz' and have it be run when it exists (checked by the c++ code), and any events in that file be run instead of any existing event handlers (also checked by the c++ code)?

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Nov 2012, 18:14
by aubergine
It would be non-desirable for WZ to just start automatically loading scripts -- what if they are not needed in the current scenario?

Having an includePath() allows script devs to easily choose when to include a bunch of files and where from.

For example, a challenge could have several missions, with the scripts associated for each mission in separate folders. When the challenge starts, it includepath("challenges/mychallenge/mission1"). When that mission is complete, it includePath("challenges/mychallenge/mission2") and so on.

Also, I now have a fairly robust dependency checking api that can load includes on-demand. So I might want to put my main scripts (the ones that rely on a bunch of smaller API scripts) in to a folder and includePath() to load those, which in turn triggers my dependency checker to load various scripts that they require.

Re: rules.js for map-mods - feedback wanted...

Posted: 12 Nov 2012, 18:20
by aubergine
Oh, and regarding the events, I have two APIs that allow some cool stuff with Events:

* Events API keeps track of what events are available, allows custom events to be created and allows multiple listeners to be added to events. It also hooks event handlers...
* Hook API allows any function (including event handlers) to have input/output hooks. Input hooks can change the arguments and optionally prevent a function from being run. Output arguments can modify the return value. Note: Functions need specifically "hooking" before they can accept input/output hooks, I decided to do it this way to avoid adding unused overhead to all functions.

Re: rules.js for map-mods - feedback wanted...

Posted: 15 Nov 2012, 04:34
by aubergine
If includePath() gets implemented, ideally its return value should be an array of the files loaded. I can then integrate that in to my dependency checker to report all those files as being available...