Page 1 of 3

OXP Variables

Posted: Sun Sep 13, 2009 10:59 pm
by PhantorGorth
OXP Variables

Here is a suggestion for making OXPs more user configurable:

An OXP may include a variables.plist file that lists variables that are created on loading and sets to the value stored in the save file or default value if that variable doesn't exist in the save file (e.g for a new commander). The value would be editable from an option on the F2 screen. The variables.plist file would contain a list of variable names, their types, and something that says what value each variable can take such as fixed option list of text values or a number range, etc.. It should also include the default value and maybe a short description for the configuration screen. This value would be saved into the save file on the next save. If you unload the OXP the values for its variables would be ignored on loading and not saved next time.

This variable would be made accessible to scripts and therefore could used for all sorts of ways of configuring an OXP such as turning on or off OXP features such as ship availabilities. AI behaviours etc. (assuming all those things are scriptable in the first place). I imagine it would be useful during testing as well so you can try out different setting until you are happy and then set those as the defaults or hardcode some or all of the the values and remove those hardcoded ones from the plist file.

I would also imagine the variable name would automatically be prefixed by the OXP name in the script to prevent name clash and would also appear in the configuration screen without prefix but grouped by OXP name.

I see this as ideal for complex OXPs where there is some controversy over what is included. (An example is the OSE OXP where from my reading of this board there are lots of people who would like to have parts optional.) An OXP developer could then set up options in their OXP that the user can configure and the developer would be able to have the OXP alter safely without the user risking breaking the OXP by hacking changes manually. Obviously configurability of an OXP would be down to the developer.

This suggestion should also be backwardly compatible with all existing OXPs as none of them have the variables.plist file and so have no variables to load or save.

Phantor Gorth

Posted: Mon Sep 14, 2009 4:45 am
by Thargoid
Basically formalising OXPConfig, which we already have?

Any such list would also need to differentiate between different scripts within the OXP, as there's nothing to stop two scripts within the same OXP using the same variable name, as an entirely separate entity in each case.

The idea has some merit for me (although whether it goes much beyond OXPConfig's functionality is questionable), although it is yet another item within an OXP that needs to be maintained and updated when things are added/remove/modified in a script. It may make working with and using an OXP simpler, but it will make actually writing and maintaining them a little more complex.

Posted: Mon Sep 14, 2009 7:10 am
by PhantorGorth
Thargoid wrote:
Basically formalising OXPConfig, which we already have?

Any such list would also need to differentiate between different scripts within the OXP, as there's nothing to stop two scripts within the same OXP using the same variable name, as an entirely separate entity in each case.
OK I haven't played with OXPConfig but from it's description it is about altering existing declared variables within an OXP. I don't think it saves the values either. (Someone can correct me there.) Maybe I am ill-qualified to make this suggestion because others may think I don't know really what I am talking about which could be true. I am just putting my programmers head on and looking at the setup as I see it.

This idea is different as it is effectively creating an array of new variables unique to the OXP that are essentially a bunch of constants from the point of the scripts and hence shouldn't be altered by any script. They are still technically variables because you can use the F2 to modify them. So if two or more scripts use a particular "variable" there would be no issue as you wouldn't be declaring them in the code. The most likely way to access them is via a function such as ConfigVar("OXPName", "VarName"), though I am not saying that is the best way to implement it as I can see possible issues there with differing variable types. I would leave that detail to the implementer to decide.
The idea has some merit for me (although whether it goes much beyond OXPConfig's functionality is questionable), although it is yet another item within an OXP that needs to be maintained and updated when things are added/remove/modified in a script. It may make working with and using an OXP simpler, but it will make actually writing and maintaining them a little more complex.
Can't argue with that point assuming you are using these variables. If your OXP doesn't use them then it is no harder than before.

Phantor Gorth

Posted: Mon Sep 14, 2009 7:56 am
by Kaks
To allow OXPConfig - or a similar mechanism - to work with all possible OXP options, you need a way to specify which variables need to be changed, what values should be entered, and what to write as configurations options on a config screen, and all that info must come from inside your own oxp.

Thinking about it, there's already a pure js (& JSON) way to formalise OXPConfig without the need for yet another .plist.

Whithin the main script, just after this.name, this.author etc. you could have

Code: Select all

this.configOptions=[
	{
		option:'myNrEnemies',
		display:'enemy aggressiveness',
		values:[
			{display:'easy',value:1}, 
			{display:'normal',value:3},
			{display:'hard',value:5},
			{display:'impossible',value:8}
		]
	},
	{
		option:'myPlanetNum'
		display:'number of planets',
		values:[
			{display:'one',value:1},
			{display:'some',value:3},
			{display:'many',value:10}
		]
	}
];
edit: sorry, used curly braces where I should have used square brackets. Corrected now!

If OXPs use something like that, OXPConfig could look to find if a script has got configOptions, and then figure out the variables that can be set, (in this case myNrEnemies & myPlanetNum) and how.

That lot above can be navigated like this, assuming that aScript is the variable pointing at the script you want to set the options for:

aScript.configOptions[0].option (= 'myNrEnemies')
aScript.configOptions[0].display (= 'enemy aggressiveness')
aScript.configOptions[0].values[0].display (= 'easy')
aScript.configOptions[0].values[0].value (= 1)
edit2: changed the variable name slightly to avoid confusion with the Script class...

and when it finally comes to set the option:

Code: Select all

aScript[aScript.configOptions[0].option]=aScript.configOptions[0].values[0].value;
which translates to

Code: Select all

aScript.myNrEnemies=1;
myNrEnemies can then be accessed within your own script as

Code: Select all

this.myNrEnemies
The scary thing is that the example above is possibly the simplest way that such a thing could be implemented...

The not-so scary thing is that, apart from being quite a bore to both read & write, it is actually quite simple, in programming terms...

Hope this helps!

Kaks

Posted: Mon Sep 14, 2009 9:11 am
by PhantorGorth
Kaks wrote:

and when it finally comes to set the option:

Code: Select all

Script[Script.configOptions[0].option]=Script.configOptions[0].values[0].value;
which translates to

Code: Select all

Script.myNrEnemies=1;
myNrEnemies can then be accessed within your own script as

Code: Select all

this.myNrEnemies
My Javascript is limited (I am more a PL/SQL and VBA programmer) but shouldn't that be more like:

Code: Select all

Script[Main_Script.configOptions[0].option]=Main_Script.configOptions[0].values[0].value;
which translates to

Code: Select all

Script.myNrEnemies=1;
myNrEnemies can then be accessed within your own script as

Code: Select all

this.myNrEnemies
as the initial configOptions are only setup in the main script. Main_Script and Script could be the same but not always.

But anyway that sort of method looks good and would definitely remove the need for another plist file but we still need script analysing code to be put in to OXPConfig or a new interface written.

Phantor Gorth

Posted: Mon Sep 14, 2009 9:19 am
by Svengali
To clarify what OXPConfig is. It's a utility to change settings (fixed property-names) and stores (and reloads) these settings. My maingoal was to use only a few missionVariables, so a savedgame wouldn't get much bigger. The property-names (this.logging, this.audio, this.extraA and this.extraB) are choosen to give scripters a better orientation and to keep it simple. That's why the properties are only boolean, they are representing a bitmask $0F and every oxp has max.16 values then. All supported oxps have to be in a database to get a fixed sorting order for storing and reloading.

Making it independent from a database would need to store a lot more infos to relate values to a oxp. This is always the weak point - it's for sure possible, but would need a lot more work. So if somebody wants to do it - feel free to adopt OXPConfig (Kaks, PhantorGorth?). I have no plans to do it, even if I'm already thinking about some bigger changes, e.g. storing the values as hex and adding a trigger (this.oxpcNotifyOnChange()) so the oxps gets a clue that something is changed, storing integer values for special oxps, ...

Posted: Mon Sep 14, 2009 10:15 am
by PhantorGorth
I am not sure I am capable (hence why I put this in the Suggestion Box forum) but I would need to look at the OXPConfig code and get a better feel for what it would entail before committing myself to such a thing.

Phantor Gorth

Posted: Mon Sep 14, 2009 11:15 am
by PhantorGorth
@Kaks
Thinking some more on the method you suggested doesn't that imply that each script in an OXP could have a different value to one of these variable to each other as you setting up multiple copies of the variable in each script that are theoretically independent? I was looking for something more global in behaviour. So if you can store the values in one place (e.g. a javascript object created in the main script) and reference that throughout the rest of the OXP's scripts it would have thought it would require less set up in each script.

Phantor Gorth

Posted: Mon Sep 14, 2009 2:32 pm
by Thargoid
If it's not a dumb question, what's the "main script"?

If an OXP has a few worldscripts running, plus a few more scripts specifically tied to ships or other entities, then how do you define what is the main one?

In theory you could already do this (set up a worldscript and then use worldscript based calls in all the other scripts to refer to the settings in that main script) but it seems a very awkward way of doing things.

Plus I would guess there are probably times when you might want variables that are co-named but independent and different from script to script?

I'm still not clear as to what this would offer over and above what OXPConfig already does.

Posted: Mon Sep 14, 2009 3:55 pm
by PhantorGorth
Thargoid wrote:
If it's not a dumb question, what's the "main script"?

If an OXP has a few worldscripts running, plus a few more scripts specifically tied to ships or other entities, then how do you define what is the main one?

In theory you could already do this (set up a worldscript and then use worldscript based calls in all the other scripts to refer to the settings in that main script) but it seems a very awkward way of doing things.

Plus I would guess there are probably times when you might want variables that are co-named but independent and different from script to script?

I'm still not clear as to what this would offer over and above what OXPConfig already does.
I don't think you really are getting my point at all. I was asking about setting up a way to do global setting for an OXP at the level of an OXP not editing any old variable you just happen to be being using in the code. Yes you would have co-named variables in differing scripts this is normal programing but these are not normally the type of variables to be exposed to the user. And if they are then they should be named uniquely within the OXP. The important point to note is that I am pedantically calling them variables where for most part they should be treated as read only constants. In fact maybe I am not suggesting it does more than OXPConfig but asking for a formalisation within the Oolite program. Mind Svengali stated that OXPConfig only does 16 boolean variables so I could say I am asking for an extension on that. Without trying to disrespect Svengali's work with OXPConfig I would have to say that having a setting called "Exclude_Star_Wars_Ships" is clearer to the user than "extraA".

As to "main script" I was only responding to that term because Kaks mentioned it so I assumed that there must be an initial script run on loading but I haven't written an OXP yet so I wouldn't know. My original suggestion was based on the repeated requests I keep seeing regarding the issue of large OXPs and people (this includes me) wanting most of their content but wanting to take small parts out. (OSE in particular.) So I put this suggestion based on the little bits I know or can surmise.

I am sorry if I am getting stuff wrong and if this suggestion is redundant but I am trying to put a useful structure to the things I want and other people are asking for.

Phantor Gorth

Posted: Mon Sep 14, 2009 5:50 pm
by Svengali
PhantorGorth wrote:
The important point to note is that I am pedantically calling them variables where for most part they should be treated as read only constants. In fact maybe I am not suggesting it does more than OXPConfig but asking for a formalisation within the Oolite program. Mind Svengali stated that OXPConfig only does 16 boolean variables so I could say I am asking for an extension on that. Without trying to disrespect Svengali's work with OXPConfig I would have to say that having a setting called "Exclude_Star_Wars_Ships" is clearer to the user than "extraA".
That's what OXPConfig is doing too. extraA has a description uniquely for every oxp .-)
Image

But as I've said before, if Oolite itself or a third-party app will do something like this I'll be pretty happy and OXPConfig is gone in the same moment. But I'm not so optimistic that oxpers will use this then. OXPConfig is there for more than a year and only a few scripters (Eric,Thargoid and me) have used it since then. Oxpers are proud about their creations (me too) and probably don't like to see it splitted into parts. And the discussion about configuring ship-oxps has started a few weeks ago, so we don't have a direction for now.

Probably it's time to ask the devteam if there is a plan to implement a configuration-tool for oxps in Oolite?

btw: Nice ideas PG and a nice example Kaks .-)

Posted: Mon Sep 14, 2009 11:38 pm
by Kaks
Hi, as far as I can tell there are no plans for any oxp configuration/settings screen within Oolite.

And now I'll try to explain myself a bit more: I don't think there's anything wrong with the way OXPConfig does things, but it looks to me that PG was asking for something with a bit more flexibility, and if I ever get enough time I might just be able to do so.

The rough Idea I mentioned this morning would enable each oxp to define exactly what they're happy to have modified - and how - by this hypothetically expanded OXPConfig.

And each option will have the name the oxp maker wants to give it, and its possible settings could more than just 2 options that can be set true or false. While they're good, and they do a terrific job as it is, a good user interface should strive to hide a program inner workings from the user - in 90% of the cases, inner workings prove to be an unnecessary distraction.

About possible huge savegame files, if what I had in mind this morning works as it should, all a new version of OXPConfig would need to save is 1 string per oxp:

First of all, I 'maed a mistook' or two with my example above ( used curly braces where I should have used square brackets, corrected now - and yes I shouldn't have used Script as an arbitrary variable name to illustrate those .configOptions I was talking about. Hey, it was early in the morning, and I had just woken up! ).

Assuming that the this.configOptions array above were inside version 0.1 of an oxp that calls itself 'KaksTestOXP', one string representing the options chosen by the player would be:

Code: Select all

"{oxp:'KaksTestOXP', version:0.1,options:[2,1]}"
and assuming the oxp version matched the saved information, OXPConfig could easily do something like this:

Code: Select all

worldScripts['KaksTestOXP'][worldScripts['KaksTestOXP'].configOptions[0].option]=worldScripts['KaksTestOXP'].configOptions[0].values[2].value;
worldScripts['KaksTestOXP'][worldScripts['KaksTestOXP'].configOptions[1].option]=worldScripts['KaksTestOXP'].configOptions[1].values[1].value;
which would translates to

Code: Select all

 worldScripts.KaksTestOXP.myNrEnemies=5;
 worldScripts.KaksTestOXP.myPlanetNum=3;
then OXPConfig could do something like

Code: Select all

if (worldScripts['KaksTestOXP'].configOptionsChanged) worldScripts['KaksTestOXP'].configOptionsChanged();
Wait a minute! Where does that configOptionsChanged thing come from?

Well, this morning I blithely assumed most configurable oxps would check their configurable stuff only inside a shipWillLaunchFromStation event, and that OXPConfig would have had the time to update the internal script variables.

Still, a configurable oxp might want to alter something - or present a mission screen - well before the player launched from the main station.

A way to do so is to add a pseudo event inside the main script oxp, to handle the changed variables. It could look something like this:

Code: Select all

this.configOptionsChanged = function() {
  if (this.myNrEnemies == 1){

    ...

  } else if (this.myNrEnemies ==3) {

    ...

  }
     ...
     ...
}
And another thing:
Q: How would this enhanced OXPConfig figure out if a script is the main script?
A: Well, it's the one that has got configOptions defined.

Inside OXPConfig, the outer loop that finds the configurable options could look a lot like this

Code: Select all


for (scriptName in worldScripts) {
 if(worldScripts[scriptName].configOptions{
   //bingo! it's a main script! 
   var aScript = worldScripts[scriptName];
     ...
     ...

 }
}
There's a lot more that would need to be figured out, I'm sure, but the main point I'm trying to make is that there's nothing - apart from time & effort required - = to stop anybody from upgrading OXPConfig to the point that's indistinguishable - for the end user - to what PG is talking about. All variables will be internal to each oxp, and all permitted settings for those variables will also be internal to each oxp.

Anyway, all this thinking is starting to hurt my brain!

If I get the time - unlikely, but this last month I managed to find tons of extra time for Oolite I didn't know I had - I might just be able to make all this stuff into something vaguely usable.

I personally think that the opt-in idea behind OXPConfig is a pretty sensible one. There might not be too many OXPs compatible with it, but we've got more than this time last year!

Cheers,

Kaks.

PS edited n-times to try & clarify the most disjoined concepts. hope I managed to do so!

Posted: Mon Sep 14, 2009 11:53 pm
by Kaks
PhantorGorth wrote:
My Javascript is limited (I am more a PL/SQL and VBA programmer) but shouldn't that be more like:

Code: Select all

Script[Main_Script.configOptions[0].option]=Main_Script.configOptions[0].values[0].value;
which translates to

Code: Select all

Script.myNrEnemies=1;
myNrEnemies can then be accessed within your own script as

Code: Select all

this.myNrEnemies
No. In my example the .configOptions are going to be defined inside each main script, and the variables to be modified are internal to each oxp. That way you don't get any conflict with identically named variables in different main scripts. An example that works is:

Code: Select all

Main_Script[Main_Script.configOptions[0].option]=Main_Script.configOptions[0].values[0].value;
which translates to

Code: Select all

Main_Script.myNrEnemies=1;
myNrEnemies can then be accessed within Main_Script as

Code: Select all

this.myNrEnemies

Posted: Tue Sep 15, 2009 7:02 am
by PhantorGorth
That's really looking good Kaks and your re-vamped example makes a bit more sense to me but I do have a few questions:

This method you have come up with supports enumerated list of options. How could we support numeric values that can be within a fixed range? (I am sure OXP developers would want that.)

How would your method allow re-use of the same setting between two scripts in the same OXP without the need to have the user configure two settings?

What method of version migration to you suggest if you go, say, from OXP version 0.1 to 0.2, for example? (Would earlier version configurations be ignored? Or would the developer have to write a OXPversionchanged() function that handles the conversion process?)

I can surmise that OXPConfig would do the saving to the save file.

Regards,

Phantor Gorth

...

Posted: Tue Sep 15, 2009 7:07 am
by Lestradae
Hi guys,

As OSE has been mentioned I just wanted to say that I am perfectly willing to "allow" a configuration oxp to give players the option to supress certain shiptypes and oxp'ers the option to switch some stuff (ships, equipment) off selectively for the duration of a mission or somesuch without having to hack the oxp or override it with scripts.

I would have to have clear instructions as to what I need to put in that that works, though.

The idea to be able to configure one's oxps from outside is one I think is very good, though, a metalevel to the oxps themselves, and even more autonomy for players as to what game they would like to play.

Cheers 8)

L