Save/Load revisited

Save/Load revisited

Requests for features in the spring code.

Moderator: Moderators

Post Reply
User avatar
KingRaptor
Zero-K Developer
Posts: 838
Joined: 14 Mar 2007, 03:44

Save/Load revisited

Post by KingRaptor »

A certain bumped 3 year old thread reminded me of my partially completed work on save/load support for ZK. Since I'm working on SP content/functionality for ZK at the moment, this was, as they say, relevant to my interests.

As I recall, the developer consensus was that engine support for savegames beyond the existing Lua API is unlikely to ever be provided. Out of curiosity, is this still the case?

There were two reasons I previously postponed work on ZK's save/load system, which I'll bring up here:

1) Units and features do not remember their unitIDs/featureIDs
Mod-side solution is to map the old unitIDs to the new ones, and have gadgets use the map to get the updated unitIDs when loading. This can be difficult and bug-prone, especially in more compelx gadgets.
Engine feature request: Allow Spring.CreateUnit to take a unitID argument (and featureID arg for Spring.CreateFeature), allowing the gadget to recreate the units/features with their original IDs and eliminate the need for a mapping function. Throw an error if the ID is already taken or out of bounds.

2) The loaded game starts at t=0, rather than the time of the saved game (i.e. n gameframes in)
Since SP (e.g. chicken mode, missions) often relies on time ingame to schedule events, this is highly undesirable.
Mod-side solution: Save the gameframe and use it as an offset in every instance where gameframe/gameseconds is used. Difficult and bug-prone.
Engine feature request: Game starts at saved time upon loading a game.

Would these be too hard/time-consuming or considered too hacky to implement?
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6240
Joined: 29 Apr 2005, 01:14

Re: Save/Load revisited

Post by FLOZi »

I was looking at 1 recently for 'hot swapping' units in a gadget but it isn't feasible there (due to tombstoned unitIDs), however, I think it might be feasible for this - My view is no guarantee of anything, mind.
abma
Spring Developer
Posts: 3798
Joined: 01 Jun 2009, 00:08

Re: Save/Load revisited

Post by abma »

not sure if this helps, at list it bumps this thread:

backlink to the feature request: http://springrts.com/mantis/view.php?id=3041
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Save/Load revisited

Post by gajop »

Not sure if you want us to discuss it here or on mantis, but there are a couple of things I'd like to mention:
1) I want a /load that work in-game as well, preferably without the need of a Spring restart. Textures may also need saving as well?
2) It may be expensive to save the whole lua state, it would be great to be able to at least somehow mark things transient.

Btw, full engine saving aside, it'd be great if we could get that ID param for units/features create methods soon, as it would make full lua or engine assisted saving mechanisms much easier.
abma
Spring Developer
Posts: 3798
Joined: 01 Jun 2009, 00:08

Re: Save/Load revisited

Post by abma »

kloot implemented 1) Units and features do not remember their unitIDs/featureIDs

see https://github.com/spring/spring/commit ... 8697105a02
User avatar
KingRaptor
Zero-K Developer
Posts: 838
Joined: 14 Mar 2007, 03:44

Re: Save/Load revisited

Post by KingRaptor »

Good to hear; would #2 be possible as well?
User avatar
Anarchid
Posts: 1384
Joined: 30 Nov 2008, 04:31

Re: Save/Load revisited

Post by Anarchid »

I'm the necroer of topics
I'm the poster of bump-posts
I subvert the engine api
I replace its function calls

Awaken, awaken, awaken awaken
Load the save that must be taken


It has come to my mind that - provided it is possible to poison the SpringRTS Lua API by replacing functions with impostors - should be possible to implement issue 2) with a rather small amount of code.

Here's the plan:

1) in gadget handler:

Code: Select all

GG.gameFrameOffset = 0;
local UnpoisonedGetGameFrame = Spring.GetGameFrame;
Spring.GetGameFrame = function() return UnpoisonedGetGameFrame() + GG.gameFrameOffset end
(and similar override for gadget:GameFrame)
2) In save/load gadget:

Code: Select all

GG.GameFrameOffset = MagicallyExtractFromSaveData();
If this works, this should resolve issue 2 with approximately 20 LOC (maybe add same amount as needed to poison widget land too), as opposed to manually subverting 462 mentions of gameframe in (for example) ZK.

(note that many of those would actually be localized, so actual linecount for "brutal approach" is lower)

This should also seamlessly subvert any userland widgets, which is a clear benefit.

It is probably important to first subvert the function to ensure all localizations are also subverted, and then set the value of game frame offset, which is only available after save/load gadget does its thing.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Save/Load revisited

Post by zwzsg »

Anarchid wrote:This should also seamlessly subvert any userland widgets, which is a clear benefit.
No, you have to do it once in the gadget handler, and once in the widget handler.

Some gadgets and widgets will still fails, especially those that needs to do stuff at the start of the game:
- They may detect game started by looking at frame number, by using GameStart or a similar callings, by checking, or simply by running code when the gadget/widget is loaded.
- Sometimes the action at the beginning of the game has to be done again. Sometimes it must not be done again (for exemple, spawning commander). Sometimes values must be stored (like, times per teams on a KOTH gadget).
You can't apply a blanket strategy to automatically fix every gadget transparently.

Well coded widgets may be more resilient, since it always was possible to switch widgets on and off midgame.


But otherwise, yes, the idea of overriding Lua API in the save/load gadget works. I use it myself. But it's unclean. And has issues when gadgets race to be the first to run.
User avatar
KingRaptor
Zero-K Developer
Posts: 838
Joined: 14 Mar 2007, 03:44

Re: Save/Load revisited

Post by KingRaptor »

*bump*

Thanks to GoogleFrog's work, the ZK implementation of save/load is almost fully functional. But I've had two major issues I still can't solve:

1) gadget:Load() is called after gadget:GamePreload().
Currently I know of no other way to detect whether this is a loaded savegame, which means I can't block unwanted things happening in GamePreload.

2) The player still isn't assigned to the right team on game load (even though startscript.0 lists the correct player name). Trying to work around by moving all players with Spring.AssignPlayerToTeam() doesn't work either.
Here is a save (Zero-K v1.3.9.0, Comet Catcher Redux) that demonstrates the issue, and the startscript used to generate it.

Does anyone know of a workaround for either of these issues?
abma
Spring Developer
Posts: 3798
Joined: 01 Jun 2009, 00:08

Re: Save/Load revisited

Post by abma »

2) The player still isn't assigned to the right team on game load (even though startscript.0 lists the correct player name). Trying to work around by moving all players with Spring.AssignPlayerToTeam() doesn't work either.
does the player0's name in script.txt match the name in springsettings.cfg ?

https://springrts.com/wiki/Springsettings.cfg#name
User avatar
code_man
Posts: 260
Joined: 19 Jan 2014, 13:10

Re: Save/Load revisited

Post by code_man »

So save/load is actually workign well?
I can try it myself if its reasonably supported.
User avatar
KingRaptor
Zero-K Developer
Posts: 838
Joined: 14 Mar 2007, 03:44

Re: Save/Load revisited

Post by KingRaptor »

abma wrote:
2) The player still isn't assigned to the right team on game load (even though startscript.0 lists the correct player name). Trying to work around by moving all players with Spring.AssignPlayerToTeam() doesn't work either.
does the player0's name in script.txt match the name in springsettings.cfg ?

https://springrts.com/wiki/Springsettings.cfg#name
Ah, no it doesn't.

(Still makes it annoying to test unless you already have a lobby client or equivalent that supports it; "why u no just use the name in startscript?!" But if it'll work correctly in the release version then I guess it's fine.)
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: Save/Load revisited

Post by AF »

I would think that something such as the Eris or Pluto projects would be the route towards save/load. We'd be able to serialise an entire lua VM and save to disk, then load it, call a few API calls to tell the game it's just been reconstituted, and resume without needing special save/load mechanisms in game content ( beyond UI )
User avatar
code_man
Posts: 260
Joined: 19 Jan 2014, 13:10

Re: Save/Load revisited

Post by code_man »

AF wrote:I would think that something such as the Eris or Pluto projects would be the route towards save/load. We'd be able to serialise an entire lua VM and save to disk, then load it, call a few API calls to tell the game it's just been reconstituted, and resume without needing special save/load mechanisms in game content ( beyond UI )
Sounds like a reasonable approach.
It may be needed or atleast useful if save/load functions would be there to override some of the behavior tough.

Also i havent checked up but, does save/load support multiplayer with different players?
Post Reply

Return to “Feature Requests”