New Wiki Page on OXP Dependencies

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

Post Reply
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

New Wiki Page on OXP Dependencies

Post by PhantorGorth »

Just to let people know I have just added a page to the wiki regarding how to handle OXP dependencies with Javascript.

It can be found at: http://wiki.alioth.net/index.php/Handli ... JavaScript

Regards,

Phantor Gorth
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5525
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

A simpler way to do it may be to use a small timer to delay the check for the dependency OXPs. That way you can be sure that everything that will be loaded has been (presuming you don't set the timer too short), and can take appropriate action.

It may also be clearer in your code to use either worldScripts.OXP_B.startUp() or worldScripts["OXP_B"].startUp() syntax. Both are equivalent but it may be clearer in your example scripting if you only use one of them (currently both are in there). Personally I would recommend the latter as it can deal with spaces whereas the former one can't.

Also a couple of other points. OXP_B etc is perhaps not the best term to use, as it's the scripts (and script names) that you're referring to within the OXP, not the OXP itself. Remember you may well have more than one script being loaded for a given OXP.

Secondly in your example, this.startUp() for OXP_B would run twice. Once when called by your example script, and a second time automatically when the game parses the OXP_B script in the normal fashion. This may cause problems for some scripts.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Thargoid wrote:
A simpler way to do it may be to use a small timer to delay the check for the dependency OXPs. That way you can be sure that everything that will be loaded has been (presuming you don't set the timer too short), and can take appropriate action.
I agree that timers should be mentioned as an option to. It works more general because you don't check against a specific oxp but just make sure your startup code runs after all other startup codes that don't use timers itself.

And dependencies are not only present during startup. Using timers is also useful for witchspace jumps were your code must run last. e.g. the rock_hermit_locator adds buoys to pirate coves. In order to do so it must run after the pirate cove addition script. The method of deleting the shipExitedWitchspace handler won't work there.
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

Post by PhantorGorth »

Thargoid wrote:
A simpler way to do it may be to use a small timer to delay the check for the dependency OXPs. That way you can be sure that everything that will be loaded has been (presuming you don't set the timer too short), and can take appropriate action.
I made reference to this technique as not supporting dependencies chains (if not too clearly). It works for a single level of dependency and that's it.
It may also be clearer in your code to use either worldScripts.OXP_B.startUp() or worldScripts["OXP_B"].startUp() syntax. Both are equivalent but it may be clearer in your example scripting if you only use one of them (currently both are in there). Personally I would recommend the latter as it can deal with spaces whereas the former one can't.
Agreed. I will change it to one of the syntaxes for consistency.
Also a couple of other points. OXP_B etc is perhaps not the best term to use, as it's the scripts (and script names) that you're referring to within the OXP, not the OXP itself. Remember you may well have more than one script being loaded for a given OXP.
I know exactly what you mean. Maybe "OXP_A_Script" format?
Secondly in your example, this.startUp() for OXP_B would run twice. Once when called by your example script, and a second time automatically when the game parses the OXP_B script in the normal fashion. This may cause problems for some scripts.
Actually you are wrong and I have stated this in the example.
Wiki Page wrote:
"Finally Oolite will try to call OXP_B's startUp function which also has been deleted and will also therefore be skipped."
The whole point of the method is that the startUp functions after being called are deleted so they do not exist to be called again. I have also tested this method quite thoroughly.
Last edited by PhantorGorth on Sun Nov 07, 2010 11:31 am, edited 1 time in total.
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

Post by PhantorGorth »

Eric Walch wrote:
Thargoid wrote:
A simpler way to do it may be to use a small timer to delay the check for the dependency OXPs. That way you can be sure that everything that will be loaded has been (presuming you don't set the timer too short), and can take appropriate action.
I agree that timers should be mentioned as an option to. It works more general because you don't check against a specific oxp but just make sure your startup code runs after all other startup codes that don't use timers itself.

And dependencies are not only present during startup. Using timers is also useful for witchspace jumps were your code must run last. e.g. the rock_hermit_locator adds buoys to pirate coves. In order to do so it must run after the pirate cove addition script. The method of deleting the shipExitedWitchspace handler won't work there.
I was only interested in loading dependencies for this wiki page when I wrote it, but your point for shipExitedWitchspace is valid as other events won't get loaded again on game restart. I would not recommend a timer at all for loading dependencies though. A separate section on that page for other dependencies issues should cover that rather than combining them as that would be confusing.
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

Nice addition to the wiki! However, I do have a couple of suggestions for -err- streamlining the template.

I personally wouldn't differentiate between 'old style' & 'new style' script & use a local function to provide a more generic approach:

Code: Select all

this.runOtherStartUp = function(s) {
    if (worldScripts[s].startUp) worldScripts[s].startUp(); // Call the other startUp.
    if (worldScripts[s].startUp) delete worldScripts[s].startUp; // Make sure the other startUp is run only once.
};
then call the new function on either of the scripts...

Code: Select all

this.runOtherStartUp('Oxp_B');
this.runOtherStartUp('Oxp_Old');
You might also want to show a 'shortcut' for this piece of code:

Code: Select all

      // Test for existence of an OXP that isn't required but effects the way this OXP works.
      if (worldScripts["Oxp_X"])
      {
         this.Oxp_X_Exists = true;
      }
      else
      {
         this.Oxp_X_Exists = false;
      }
i.e.

Code: Select all

      // Test for existence of an OXP that isn't required but effects the way this OXP works.
      this.Oxp_X_Exists = !!worldScripts['Oxp_X'];
Of course, the shortcut is not as 'easy' for beginners to read as the first one (one ! ensures we're dealing with a boolean value, the other 'flips' the boolean value the right way round), however it is easier to modify... :)

Just my 2p's worth! :D
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

Post by PhantorGorth »

Kaks wrote:
Nice addition to the wiki!
Thanks.
However, I do have a couple of suggestions for -err- streamlining the template.

I personally wouldn't differentiate between 'old style' & 'new style' script & use a local function to provide a more generic approach:

Code: Select all

this.runOtherStartUp = function(s) {
    if (worldScripts[s].startUp) worldScripts[s].startUp(); // Call the other startUp.
    if (worldScripts[s].startUp) delete worldScripts[s].startUp; // Make sure the other startUp is run only once.
};
then call the new function on either of the scripts...

Code: Select all

this.runOtherStartUp('Oxp_B');
this.runOtherStartUp('Oxp_Old');
That would work nicely and does simply it. I will probably change that. I will still need to specify that you should do the delete at the beginning of your startUp as it is there to prevent dependency loops causing an infinite calling loop.
You might also want to show a 'shortcut' for this piece of code:

Code: Select all

      // Test for existence of an OXP that isn't required but effects the way this OXP works.
      if (worldScripts["Oxp_X"])
      {
         this.Oxp_X_Exists = true;
      }
      else
      {
         this.Oxp_X_Exists = false;
      }
i.e.

Code: Select all

      // Test for existence of an OXP that isn't required but effects the way this OXP works.
      this.Oxp_X_Exists = !!worldScripts['Oxp_X'];
Of course, the shortcut is not as 'easy' for beginners to read as the first one (one ! ensures we're dealing with a boolean value, the other 'flips' the boolean value the right way round), however it is easier to modify... :)
That's nice too but the syntax is not obvious at all even to me so I would like to see other's opinions first on whether to change that part.
User avatar
Micha
Commodore
Commodore
Posts: 815
Joined: Tue Sep 02, 2008 2:01 pm
Location: London, UK
Contact:

Post by Micha »

PhantorGorth wrote:
Kaks wrote:

Code: Select all

      // Test for existence of an OXP that isn't required but effects the way this OXP works.
      this.Oxp_X_Exists = !!worldScripts['Oxp_X'];
Of course, the shortcut is not as 'easy' for beginners to read as the first one (one ! ensures we're dealing with a boolean value, the other 'flips' the boolean value the right way round), however it is easier to modify... :)
That's nice too but the syntax is not obvious at all even to me so I would like to see other's opinions first on whether to change that part.
That's the point of comments - to explain code which is not easily readable.
The glass is twice as big as it needs to be.
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

Post by PhantorGorth »

Micha wrote:
That's the point of comments - to explain code which is not easily readable.
Can't argue with that.
User avatar
PhantorGorth
---- E L I T E ----
---- E L I T E ----
Posts: 647
Joined: Wed May 20, 2009 6:48 pm
Location: Somewhere off the top left of Galaxy 1 map

Post by PhantorGorth »

I have updated the page.

http://wiki.alioth.net/index.php/Handli ... JavaScript

Regards,

Phantor Gorth
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: New Wiki Page on OXP Dependencies

Post by ocz »

Is this still state of the art? I've got my share of problems using the worldScripts[stringWithScriptName] method.

Also: I believe there is a ";" missing in line 22 of the main code example.

> if (worldScripts["OXPAdditionalCargoSpaceWorkaroundScripts"].startUp) log("Yes");
Exception: TypeError: worldScripts.OXPAdditionalCargoSpaceWorkaroundScripts is undefined
Active script: oolite-debug-console 1.82
oolite-debug-console.js, line 844:
}


OXPAdditionalCargoSpaceWorkaroundScripts.js does exist and is listed in world-scripts.plist. Is startUp() auto deleted after it run in the startup phase?
User avatar
Norby
---- E L I T E ----
---- E L I T E ----
Posts: 2577
Joined: Mon May 20, 2013 9:53 pm
Location: Budapest, Hungary (Mainly Agricultural Democracy, TL10)
Contact:

Re: New Wiki Page on OXP Dependencies

Post by Norby »

ocz wrote:
OXPAdditionalCargoSpaceWorkaroundScripts.js does exist
Do not use the name of the file but the content of this.name within.
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: New Wiki Page on OXP Dependencies

Post by ocz »

Norby wrote:
Do not use the name of the file but the content of this.name within.
I'm sorry, I'm not catching your drift. Could you give a small syntax example?

var f = worldScripts["IAmAScriptFilesNameWithoutTheJs"].andIamAMethod();

this.f() is than a function defined in "IAmAScriptFilesNameWithoutTheJs.js", right?
User avatar
Norby
---- E L I T E ----
---- E L I T E ----
Posts: 2577
Joined: Mon May 20, 2013 9:53 pm
Location: Budapest, Hungary (Mainly Agricultural Democracy, TL10)
Contact:

Re: New Wiki Page on OXP Dependencies

Post by Norby »

Scripts in Oolite should begin with a this.name definition, which is the key in the worldScripts array if the js file is added into any Config/world-scripts.plist . Your example is working only if the filename without .js and the content of this.name within the file is equal.
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: New Wiki Page on OXP Dependencies

Post by ocz »

OOOHHHHHHhhhh...........!!!!
You meant this.name from the file header.

"use strict";
this.name = "OXPAdditionalCargoSpaceWorkaround Script";
this.author = "ocz";
this.copyright = "2015 ocz";
this.licence = "CC BY-NC-SA 4.0";

It is actually used for something! Totally forgot about it. My bad.
Post Reply