Idea: Multiplayer script

For AI and campaign script related discussions and questions
Post Reply
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Idea: Multiplayer script

Post by aubergine »

Shadow Wolf TJC got me thinking about this...

Currently, each script is associated with a specific player:

* scavfact.js -- scavenger faction
* rules.js -- human player
* AI's -- their associated player

What if there was an additional script that was "multiplayer"? It would work like this...

1. Whenever a game event is fired, WZ sets the 'me' of the multiplayer script to the id of the player the event is for, then triggers the event handler in the multiplayer script and also the individual player script.

This will allow a single script to receive events from all players, it will just look at the value of 'me' when the event is fired to work out which player that event was for.

2. The value of 'me' in the multiplayer script is not locked, it can be changed by the script at runtime.

It's my understanding that the first thing any of the JS API C++ functions do is work out which payer is invoking them by looking at the value of 'me' in the JS env that invoked the function. So if the JS script in the multiplayer script is able to alter the value of 'me' it can pretend to be any player and thus invoke functions as if it were that player.

Some possible uses for the multiplayer script environment:
Shadow Wolf TJC wrote:Lately, I've been trying to add wind farms to Contingency, and while I've figured out how to successfully implement them for 3.1 rc2 (via having the rules.js script check all players, instead of just the host player, when using the setPower() function every second), I'm not yet able to adjust their power generation rates (based on what power upgrades each player has researched) on account that I believe that eventResearched() is only called when the player running the script researches the given item. Instead, I wish that it was called whenever ANY player researches the item (though AI scripts could still check if the research lab that completed the research belongs to them or one of their allies).
In regards to Shadow's idea, the multiplayer script would be able to invoke getResearch() for each player in turn to work out if they've researched it, or just hook to eventResearched() to be notified when players research the various techs.

Another scenario is where the same AI is in multiple slots. The AI could live in the multiplayer script so there's only one copy of most of it's functions, internal data, etc. It could create objects to store data associated with each player, but use the same instantiated code to process that data.

Yet another scenario is for campaigns and challenges. I know there's already the ability to have an 'extra' script with challenges, which is assigned to player 0, maybe that could become the multiplayer script (by having it receive all events and have an editable 'me' global). As the plot unfolds, the multiplayer script could change alliances between AI players, launch co-ordinated attacks, etc.

Obviously, a great deal of care would be required in the multiplayer script. It will be all too easy to forget to change 'me', and data relevant to each player would need to be carefully managed. Developers would need to give extra thought to all their internal/private variables, data structures, etc., to ensure they are "multiplayer aware". However, such an environment could offer a lot of new opportunities.

It's not something I'm desperate to see implemented any time soon. There are dozens of other more vital things IMHO, but just wanted to put the idea out there to see what people think of it.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
Posts: 3780
Joined: 03 Aug 2006, 19:39

Re: Idea: Multiplayer script

Post by Per »

It is an interesting idea. Let me think about for a bit.
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Idea: Multiplayer script

Post by aubergine »

Extending this idea further...

If a "shared" object is found in the multiplayer script, expose it to all other player scripts via a "shared" property on their global objects.

So, in scavfact.js, etc.: <scavfact.js><global>.shared == <multiplayerEnv><global>.shared

If no shared object is found, the shared global still exists in all the other script envs, but it's value is defined as undefined (or null if preferred).

Note: The multiplayer script would need to instantiate before all other scripts.

This means the multiplayer script can expose whatever it wants to all other environments. It also means other environments can expose whatever they want to the multiplayer script's shared object.

Obviously, other scripts could mess up that shared object. However, the multiplayer script can implement it's own version of nexus resistance circuits by defining the properties on it's shared object as non-configurable (something that my Util API makes trivially easy to do, but it's also available via standard JS property descriptors).

As an example of how this would benefit scripts...

My rules.js adds some custom events, including:

* eventPlayerDefeated(player)
* eventPlayerRevived(player)

Note: The function that determines whether a player is alive or dead is moddable. :) Part of some work I've been doing to make all the game rules completely and easily moddable whilst retaining some standard structure that prevents chaos.

Anyway, rules.js could export those events to the shared object in the multiplayer script env like so:

Code: Select all

 // in rules.js...

if (shared) {
  // tardis event handler = allows multiple listeners to be attached
  shared.tardis("eventPlayerDefeated"); // create a tardis event handler
  shared.tardis("eventPlayerRevived"); // create a tardis event handler

  eventPlayerDefeated.onOutput = function(result, params, args) {
    shared.eventPlayerDefeated.call(shared, args[0]);
    return result; // internal Hook API stuff
  }

  // and same sort of thing for eventPlayerRevived()
}
Now any script can listen to that event:

Code: Select all

 // eg. in scavfact.js...

function grabTheirGasoline(player) {
  // send cranes and diggers accompanied by ice cream vans!
}

if (shared) {
  var myEnv = this; // reference to global object in scavfact.js
  shared.eventPlayerDefeated = function(player) {
   myEnv.grabTheirGasoline(player);
  }
}
Because shared.eventPlayerDefeated() is a tardis event handler, it doesn't matter if multiple scripts try and add listeners using that exact same syntax, all of them will work properly.

So now all scripts can get the custom events and act on them. And they can share their own events, etc.

The possibilities for campaigns and challenges quickly become mind boggling :)
Last edited by aubergine on 15 Nov 2012, 06:34, edited 2 times in total.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Idea: Multiplayer script

Post by aubergine »

Oh, and if a script foolishly shares its global object or something that inadvertently references it, or indeed anything that's not properly nailed down, Dr. Reed's cybernetic consciousness will be infiltrating its circuits :twisted: <insert evil laugh here>

My API's have Nexus resistance circuits built in to them from the ground up... do yours? :ninja:
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Idea: Multiplayer script

Post by aubergine »

Another scenario where a multiplayer env would help:

viewtopic.php?f=30&t=10309

It could record all the events, orders, etc., effectively recording a game. It could then be used to play them back to create a rudimentary game replay.

The main use of this, from a scripting perspective, would be to help improve AIs -- users could send a "recording" of a game and the AI developer could pick through it to see where the AI made stupid mistakes.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
Post Reply