Closed ivan-mogilko closed 3 weeks ago
About dynamic sprites, if I am using dynamic sprites in a big game wide system I will probably make up some way to reconfigure the thing on save load to recreate the sprite - I actually right now just delete the sprites before save and later recreate them after load.
But sometimes I may want them in a room for an one off thing and let them be serialized for easyness. This is more because I was thinking if it would make sense for dynamic sprites to have a setting in themselves to not serialize instead and I concluded that no, it wouldn't make sense because it's the same as deleting and recreating.
I guess the properties for things that are static to the game like GUIs, View frames and other things that can't be deleted are interesting but regarding dynamic sprites I don't know how I would use it here in a way that would be different from the current approach I take.
Edit: oh right, perhaps it would work like if I deleted them for the save but not for the currently running game - so it wouldn't hang the game slightly on save due to the game recreating the dynamic sprites. But then I would need to also check the Valid property for each dynamic sprite instead of just assuming non-null means valid or just blindly recreating all on save load.
Yes, with dynamic sprites the idea is that you save the game without having to delete/recreate, and only recreate them as a part of post-restoring a game step, which seems more suitable and something that players may "forgive" in terms of extra taken time.
Individual selection of things that may or not be saved is probably an ideal for save system, but I did not meant it here, as that's more work, and may require good thinking about its design. This particular option here is the way to disable certain category of things completely.
Something to keep as a note (I have a strong feeling that I mentioned this somewhere earlier): if you want to avoid serializing all dynamic sprites except few particular ones, then it's still possible to save these sprites into separate files put besides the save game with DynamicSprite.SaveToFile.
Testing DynamicSprite for validity is something that is currently missing, and somehow I forgot about what happens to dynamic sprite if the image itself was not restored. I must revisit this case. Right now, I think, DynamicSprite struct is restored as-is, but without actual image, and so Graphic property is pointing towards a non-existant sprite. Of course, since you know what saves you are loading (as you told the game to not save these sprites), then you can just assume that they all are missing and recreate them altogether. But still it would be proper to have DynamicSprite being able to tell that its missing an actual image. Some solution has to be made here. Either these DynamicSprites has to be tagged as invalid by setting Graphic to something invalid (i.e. -1), or they need an extra Valid property similar to Overlays.
Also, there may be objects that are using dynamic sprites system for their internal images (Textual overlays and Graphic overlays created with "clone" argument). These images will be lost on load too. This may still be worked around in script, but may come unexpected to a user. I might either mark these objects as not Valid as well; or, alternatively, make an exception for these, as IIRC there's a internal sprite flag that tells that a dynamic sprite is a internal "possession" of an object.
But I'm very much interested in learning if this will be suitable in an actual game, for example the one where sprites are recreated after save was loaded.
Added two things:
Rebased on top of master again...
Made it so that if "Audio" is ignored, then audio playback is not reset when restoring a save. This means that music and sounds will keep playing as if nothing happened.
From my understanding that's the last thing that may be done here, as all other components, in the range that may be commanded to ignore by user script, are related to "static" game objects, so if they are not restored that should not have any side effects, and they simply keep their current states.
This functionality allows user to define a number of game parts that are not saved or not read from a save. This is meant both as complementary feature to #2489 and a problem of upgrading old saves, because it may help to ignore incompatible data completely and recreate its state in script afterwards. But also may be useful on its own, for example, as a way to reduce save file sizes in games which use alot of dynamic sprites.
As save system currently is split into a number of "components", this PR declares a list of flags, and assigns these flags to each save component. Internal Save/Restore functions accept "component selection" argument, containing a collection of component flags as a mask. Each component which flags are not found within this mask are not saved nor loaded. In the last case they are simply skipped (as save format tells the component size).
In script there's a game-wide setting
OPT_SAVECOMPONENTSIGNORE
that lets user to define which save components to ignore, using a enum:Example of use:
^ above will remove dynamic sprites (bitmaps), View frames and audio playback from the runtime serialization.
Please note again that this affects both a) saves made after this option is set and b) any saves loaded back (even if they were made before this option was added).
An important note: I did not expose all of the available component flags to script, and also made sure that any flags that are not exposed are going to be ignored if set there. The exposed components are ones that are rather "secondary" to the game state, and may be reconfigured in script more or less easily. Then there's a number of "core" components with main game state and objects like characters, scripts, current room, etc, and switching these off may make things unstable. Also, I suppose, that if user does not want to have these saved, then there's little to no sense in using standard save system at all.