Simplify release process

An area for discussing new ideas and additions to Oolite.

Moderators: winston, another_commander

User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

cim wrote: Tue Jun 20, 2023 8:01 am
It wouldn't be a very big change to just add a write-only list of the Manifest IDs of all installed OXPs to the savegame itself, which would be slightly more reliable than the resource paths (that's relying on no files getting renamed after download). Really old OXPs won't have manifests, but they'll also be the most likely to have renamed resource paths.
However small that change may be - currently I do not see who could actually do it.
cim wrote: Tue Jun 20, 2023 8:01 am
Oolite itself also already has the capacity to be selective about which OXPs it loads for a particular savegame - the Scenario support at [EliteWiki] scenarios.plist - so if you wanted to maintain two savegames with different OXP sets, rather than installing and uninstalling the OXPs themselves, the tool could edit the scenario_restriction field on the savegame to set the OXPs which should be applied to it.
That is a new aspect. But I do not yet understand how we could use that for our advantage. Would an OXP demand that others be installed? Would a savegame demand what OXPs get loaded? If scenario selection happens outside the savegame, how would one ensure to choose a szenario and then find a matching savegame?
Sunshine - Moonlight - Good Times - Oolite
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Simplify release process

Post by cim »

hiran wrote: Tue Jun 20, 2023 3:38 pm
However small that change may be - currently I do not see who could actually do it.
Just needs something like this adding to PlayerEntity::commanderDataDictionary (almost anywhere in that method, doesn't really matter)

Code: Select all

[result setObject:[ResourceManager getManifestKeys] forKey:@"oxz-manifest-keys"];
and then a new method in ResourceManager.m (and corresponding entry in the .h) to return the values

Code: Select all

+ (NSArray) getManifestKeys
{
   return [sOXPManifests allKeys];
}
It'd be more complicated if you intended to read the data back in and use it elsewhere in Oolite, but for a write-only savegame entry that's all you need.

(I haven't got a working build environment for Oolite here right now, so the above is untested and not an actual commit. But it shouldn't be far off what's needed)
hiran wrote: Tue Jun 20, 2023 3:38 pm
That is a new aspect. But I do not yet understand how we could use that for our advantage. Would an OXP demand that others be installed? Would a savegame demand what OXPs get loaded? If scenario selection happens outside the savegame, how would one ensure to choose a szenario and then find a matching savegame?
OXPs can already demand that others are installed (or, indeed, not installed!) including basic versioning constraints - the requires_oxps and conflicts_oxps properties in the manifest.plist already do that, and an OXP with unmet requirements won't be loaded. That's checked both in the expansion manager (to help install dependencies) and at runtime (in case you manually remove them). There's also an optional_oxps property which doesn't enforce anything but in theory lets OXP authors say "works well with" or "extra functionality if you add this one" (e.g. Feudal works fine on its own but has extra features if you add the Planetary Landing OXP).

Savegames can't demand that particular OXPs are loaded - though if you added the manifest list to the save game, you could check for and report missing ones, which might come in useful. Oolite will generally recover reasonably well from missing OXPs (provided the player's ship is available) but you can lose equipment items or similar this way.
Savegames can say that *only* specific OXPs should be loaded, using a variety of rules. The "Strict Mode" startup option simply sets the allowed list to "none", for example. (They can also say that certain core files should not be loaded, though that's more useful for total conversion scenarios)

A scenario is a scenarios.plist entry with a pointer to the initial savegame to create a new Commander with. Once you've saved that Commander, then the scenario entry is irrelevant - all future decisions on what OXPs to load come from the savegame data and the OXP restriction list in that (which most of the time is blank, at the moment) [1]. So by editing the savegame's internal list (which it inherited from its original scenario) you can change which OXPs are loaded by it - might be useful for people who want to maintain multiple savegames with very different environments without having to constantly swap OXP folders over.

[1] You could in theory even uninstall the OXP which defined the scenario, and the savegame would still work just fine provided that OXP didn't contain anything else it needed. So e.g. you could have an OXP of "alternative starts" which just provided a bunch of scenarios but didn't change anything else.
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

cim wrote: Tue Jun 20, 2023 4:26 pm
(I haven't got a working build environment for Oolite here right now, so the above is untested and not an actual commit. But it shouldn't be far off what's needed)
Hmm. I invested time into the build environment. If you push to a branch in OoliteProject/oolite, Github will automatically build Oolite for Linux and Windows. Just download and enjoy, and if it turns out good we can merge the branch.
cim wrote: Tue Jun 20, 2023 4:26 pm
OXPs can already demand that others are installed (or, indeed, not installed!) including basic versioning constraints - the requires_oxps and conflicts_oxps properties in the manifest.plist already do that, and an OXP with unmet requirements won't be loaded. That's checked both in the expansion manager (to help install dependencies) and at runtime (in case you manually remove them). There's also an optional_oxps property which doesn't enforce anything but in theory lets OXP authors say "works well with" or "extra functionality if you add this one" (e.g. Feudal works fine on its own but has extra features if you add the Planetary Landing OXP).
I can understand that, and my OoliteStarter will try to understand such dependencies and help the user to sort them out.
cim wrote: Tue Jun 20, 2023 4:26 pm
Savegames can't demand that particular OXPs are loaded - though if you added the manifest list to the save game, you could check for and report missing ones, which might come in useful. Oolite will generally recover reasonably well from missing OXPs (provided the player's ship is available) but you can lose equipment items or similar this way.
Savegames can say that *only* specific OXPs should be loaded, using a variety of rules. The "Strict Mode" startup option simply sets the allowed list to "none", for example. (They can also say that certain core files should not be loaded, though that's more useful for total conversion scenarios)
That is what I am after: Ensure Oolite will run a savegame with the expansions it was saved with. And SaveGames cannot demand what OXPs should be loaded.
cim wrote: Tue Jun 20, 2023 4:26 pm
A scenario is a scenarios.plist entry with a pointer to the initial savegame to create a new Commander with. Once you've saved that Commander, then the scenario entry is irrelevant - all future decisions on what OXPs to load come from the savegame data and the OXP restriction list in that (which most of the time is blank, at the moment) [1]. So by editing the savegame's internal list (which it inherited from its original scenario) you can change which OXPs are loaded by it - might be useful for people who want to maintain multiple savegames with very different environments without having to constantly swap OXP folders over.

[1] You could in theory even uninstall the OXP which defined the scenario, and the savegame would still work just fine provided that OXP didn't contain anything else it needed. So e.g. you could have an OXP of "alternative starts" which just provided a bunch of scenarios but didn't change anything else.
If I tried to implement based on scenarios, I get the feeling that every savegame potentially needs to have it's own scenario. That sounds a bit like abusing the concept.

I will try to add the list of OXPs to the savegame, and I will stick to the method that I can control: via an OXP. If someone wants to contribute by providing useful code I am very happy about it. :-)
Sunshine - Moonlight - Good Times - Oolite
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

hiran wrote: Tue Jun 20, 2023 6:25 am
another_commander wrote: Tue Jun 20, 2023 5:19 am
There is also the JS property oolite.resourcePaths, which gives output similar to this:
[...]
Getting the oxp names from the list is just a matter of basic string manipulation.
That seems to be closer to my purpose.

For the OoliteStarter to know which OXPs have been used when a game was saved, I am now thinking of
an OXP with a world script with a world script that - whenever the player is about to save the game - will create the list of OXPs and store that as mission variable.
The Oolitestarter can read the savegame, get the list of OXPs and help the user to restore this status before launching the game.

Could that work?
I am getting closer with that OXP version. And I am trying to make use of the world script handler playerWillSaveGame.
But what is documented on the Wiki seems wrong. The function appears to never get called:
https://wiki.alioth.net/index.php/Oolit ... llSaveGame

Instead, what we have in the script template is getting called: https://wiki.alioth.net/index.php/Scrip ... e_Template

So now I am wondering: How come someone took the effort to really document even the string values 'standardSave', 'autoSave' or 'quickSave' if afterwards no parameter is used at all?
Sunshine - Moonlight - Good Times - Oolite
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6680
Joined: Wed Feb 28, 2007 7:54 am

Re: Simplify release process

Post by another_commander »

hiran wrote: Wed Jun 21, 2023 11:29 am
But what is documented on the Wiki seems wrong. The function appears to never get called:
https://wiki.alioth.net/index.php/Oolit ... llSaveGame

Instead, what we have in the script template is getting called: https://wiki.alioth.net/index.php/Scrip ... e_Template

So now I am wondering: How come someone took the effort to really document even the string values 'standardSave', 'autoSave' or 'quickSave' if afterwards no parameter is used at all?
Works fine here. This script:

Code: Select all

this.playerWillSaveGame = function(reason)
{
    log("playerWillSaveGame", "Saving game. Reason: " + reason);
}
produces this output:

Code: Select all

14:52:24.702 [playerWillSaveGame]: Saving game. Reason: STANDARD_SAVE
as expected. The only discrepancy in the wiki is that the strings are STANDARD_SAVE, AUTO_SAVE and QUICK_SAVE.
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

another_commander wrote: Wed Jun 21, 2023 11:55 am
hiran wrote: Wed Jun 21, 2023 11:29 am
But what is documented on the Wiki seems wrong. The function appears to never get called:
https://wiki.alioth.net/index.php/Oolit ... llSaveGame

Instead, what we have in the script template is getting called: https://wiki.alioth.net/index.php/Scrip ... e_Template

So now I am wondering: How come someone took the effort to really document even the string values 'standardSave', 'autoSave' or 'quickSave' if afterwards no parameter is used at all?
Works fine here. This script:

Code: Select all

this.playerWillSaveGame = function(reason)
{
    log("playerWillSaveGame", "Saving game. Reason: " + reason);
}
produces this output:

Code: Select all

14:52:24.702 [playerWillSaveGame]: Saving game. Reason: STANDARD_SAVE
as expected. The only discrepancy in the wiki is that the strings are STANDARD_SAVE, AUTO_SAVE and QUICK_SAVE.
That is interesting. I had to invest time to figure out that when I put both functions (with and without parameter) into the world script only the one without parameter was getting called. I am running on Oolite 1.90 Linux. But maybe I had some other issue with my script.

So my script is looking like this:

Code: Select all

this.playerWillSaveGame = function()
{
    log(this.name, "playerWillSaveGame() -> storing resourcePaths");

    missionVariables["ooliteStarter_oxpList"] = oolite.resourcePaths;
}

this.playerWillSaveGame = function(reason)
{
    log(this.name, "playerWillSaveGame(" + reason + ") -> storing resourcePaths");

    missionVariables["ooliteStarter_oxpList"] = oolite.resourcePaths;
}
The method with parameter is getting called, as you perceived it. When I remove the handler with parameter so only the other one is left, the one without parameter gets called. Maybe that is on purpose to be backwards compatible.
Last edited by hiran on Wed Jun 21, 2023 12:33 pm, edited 1 time in total.
Sunshine - Moonlight - Good Times - Oolite
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6680
Joined: Wed Feb 28, 2007 7:54 am

Re: Simplify release process

Post by another_commander »

No, Linux should be the same. My guess is that you may somehow used the function incorrectly. You can omit the argument in your script and that will work fine, but if you do include it, the event handler will have that extra bit of information to use, if it is necessary. The event handler is called by the game in any case, not by the script. The script code just catches this event and can do something with it at the time of its execution.
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

another_commander wrote: Wed Jun 21, 2023 12:20 pm
No, Linux should be the same. My guess is that you may somehow used the function incorrectly. You can omit the argument in your script and that will work fine, but if you do include it, the event handler will have that extra bit of information to use, if it is necessary. The event handler is called by the game in any case, not by the script. The script code just catches this event and can do something with it at the time of its execution.
Ok, sounds good. I removed my comment in the documentation again.
Sunshine - Moonlight - Good Times - Oolite
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

I believe we can remove something from the Oolite repository:

This document is not used by the build process.
https://github.com/OoliteProject/oolite ... anders.doc
Instead it's sibling, the odt document is used. Thus I suggest to remove this one.

Here is another specimen: I believe the file is in contradiction with manifest.plist:
https://github.com/OoliteProject/oolite ... ires.plist
Backward compatibility should not be a reason for the debug OXP as it is contained in the development builds directly.
Thus I suggest to remove the requires.plist.

Would that work?
Sunshine - Moonlight - Good Times - Oolite
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Simplify release process

Post by cim »

hiran wrote: Wed Jun 21, 2023 12:17 pm
So my script is looking like this:

Code: Select all

this.playerWillSaveGame = function()
{
    log(this.name, "playerWillSaveGame() -> storing resourcePaths");

    missionVariables["ooliteStarter_oxpList"] = oolite.resourcePaths;
}

this.playerWillSaveGame = function(reason)
{
    log(this.name, "playerWillSaveGame(" + reason + ") -> storing resourcePaths");

    missionVariables["ooliteStarter_oxpList"] = oolite.resourcePaths;
}
The method with parameter is getting called, as you perceived it. When I remove the handler with parameter so only the other one is left, the one without parameter gets called. Maybe that is on purpose to be backwards compatible.
This is just how Javascript works (generally and in Oolite).

Your first method defines this.playerWillSaveGame for that worldscript.
Your second method *overwrites* the first definition (in the same way that if you do a=2; a=3; then a has the value 3, not the values 2 and 3) [1, 2]

So with the second method in, only the second is set into the playerWillSaveGame variable after the script is executed, so that's all that Oolite can execute when looking to call that handler.

If you reverse the order of the methods in the file, only the one without the parameter will get called, as that will now be the definition that takes precedence.

The interface between Oolite and Javascript also is fairly tolerant of just making up the parameters, provided you don't expect it to do anything useful. So if you define this.playerWillSaveGame = function(size, reason, override) { ... } then that will be called (it's a callable function and it's assigned to the correct property of the worldscript) - the reason, however, will end up in the variable you've called "size", and the other two will be blank as the Obj-C side won't be expecting them so won't pass anything to them. Similarly, as you've discovered, if you omit a parameter, all that happens is that you don't on the JS side have access to the contents of that parameter.


More generally: Oolite handlers - ship script, world script, whatever - are called by calling a method in Javascript, where the method is a property of a given name on a given object. When Oolite loads a world script or ship script, it executes the content - which conventionally just defines a bunch of properties (which mostly happen to be functions) onto the object referenced by 'this' - and then stops. Then, later, the Obj-C core will call those handlers. You can use this to set up private variables and methods too, if you want, because anything run or defined in the script context is still available to the handlers by normal JS scoping rules.


[1] Not usually recommended, but sometimes useful for debugging or compatibility tweaks: there's nothing other than politeness stopping you redefining the handlers in a *different* worldscript this way.
[2] Overwriting your own worldscript's handlers is a bit more useful. e.g. for a minor bit of efficiency the Nova mission undefines almost all its event handlers after the mission is over, as they'll never be called again. https://github.com/OoliteProject/oolite ... mission.js
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

cim wrote: Wed Jun 21, 2023 3:28 pm
This is just how Javascript works (generally and in Oolite).
[...]
Thank you for taking the time to explain all this. I was not aware but have a much clearer picture now. :-)
Sunshine - Moonlight - Good Times - Oolite
User avatar
Cholmondely
Archivist
Archivist
Posts: 5364
Joined: Tue Jul 07, 2020 11:00 am
Location: The Delightful Domains of His Most Britannic Majesty (industrial? agricultural? mainly anything?)
Contact:

Re: Simplify release process

Post by Cholmondely »

It would be nice if the release of v.1.92 could be accompanied by some publicity when it happens.

In the past new releases have been accompanied by

1) a You-Tube demonstration (eg.: https://www.youtube.com/watch?v=48GvR8xgDy4 Oolite 1.86 teaser trailer)
2) notice on https://spacesimcentral.com/community/oolite/ (Cody has been doing this ever since v.1.77, back in 2013!)
3) notice on our Twitter site: https://twitter.com/Oolite (managed by Aegidian)
4) notice on https://en.wikipedia.org/wiki/Oolite_(video_game)
5) New version on Ubuntu Software Centre (currently has v1.77.1 thanks to Trusty!)

...there have been other things too, in the past...

Reference:
Popularising Oolite in Different Languages

Edited to add another
Last edited by Cholmondely on Sun Jul 02, 2023 10:24 am, edited 2 times in total.
Comments wanted:
Missing OXPs? What do you think is missing?
Lore: The economics of ship building How many built for Aronar?
Lore: The Space Traders Flight Training Manual: Cowell & MgRath Do you agree with Redspear?
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

Coming back to the original intent: Automate as many as possible steps for building/releasing Oolite.

I want to tackle the version bump into so many other files. Yet we want to manually manage version numbers.
So the question is: Where is the authorative source? Where do we define a version number so the automation can pick it up and inject it whereever else it needs to be?

Options are to use a branch with a specific name, or a tag with a specific name, or have one file that some developer needs to keep up to date...
Sunshine - Moonlight - Good Times - Oolite
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4830
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Simplify release process

Post by phkb »

hiran wrote: Sun Jun 25, 2023 7:34 pm
So the question is: Where is the authorative source? Where do we define a version number so the automation can pick it up and inject it whereever else it needs to be?
Is the "src/Cocoa/oolite-version.xcconfig" file not suitable for grabbing the version number?
User avatar
hiran
Theorethicist
Posts: 2403
Joined: Fri Mar 26, 2021 1:39 pm
Location: a parallel world I created for myself. Some call it a singularity...

Re: Simplify release process

Post by hiran »

phkb wrote: Mon Jun 26, 2023 3:57 am
hiran wrote: Sun Jun 25, 2023 7:34 pm
So the question is: Where is the authorative source? Where do we define a version number so the automation can pick it up and inject it whereever else it needs to be?
Is the "src/Cocoa/oolite-version.xcconfig" file not suitable for grabbing the version number?
Then that one shall be the master. :-)
Sunshine - Moonlight - Good Times - Oolite
Post Reply