Savestate Indexing System
At this point it is tradition that every one of our mods has a different savestating indexing system.
The only thing truly consistent was still the TAStools savestates, which is probably still the simplest savestating system.
TASTools-System
- Pressing savestate creates a new savestate.
- Pressing loadstate loads the most recent savestate.
- The savestate list is determined by checking all folders with the name "<Worldname>-Savestate<SavestateIndex>" (e.g. NewWorld-Savestate1)
This (imo) was a surprisingly solid system for someone who never programmed anything storage related before and I still like the way I made it.
Advantages
- There is no chance that a savestate gets accidentally overridden (If programmed correctly)
- You can fix the savestate list pretty easily yourself, if you follow the patterns
- Easy to understand
I'm still an avid believer that you should be able to easily fix your system manually if something goes wrong, meaning stuff should be stored in plain text where possible.
Disadvantages
- Can't load old savestates without headaches
- Savestates can't be named
- Savestate indexes had to be sequential, no gaps in the folders were allowed
- The savestates folder is a mess when playing on multiple worlds
LoTAS 2.0
LoTAS savestates follow the exact same principle as the TAStools savestates with minor additions ~~that were tacked on afterwards~~
Since they use the same indexing, you could just switch to LoTAS and continue using your TAStools savestates.
In addition to that, savestate naming, loading an older savestate and deleting loadstates has been added to the gui as an option, however the basic savestating system still applies.
TASmod
In an attempt to modernize the savestating system to make it work on servers, I rewrote the indexing part in a way for TASmod, that still operates under the same core principles, making it yet again compatible with LoTAS and even TAStools.
However, I tried to tackle the problem of being forced to always use sequential savestates.
Every savestate is now being assigned a savestate index. By default the savestating works the same as in TASTools. However you are now able to load a previous savestate and creating a savestate from this point on will override the new savestates after the one loaded.
This system also makes it quick to use savestates with commands, making it unnecessary to change the files of the server. What I haven't included (yet) was the ability to name a savestate.
LoTAS 3.0
For LoTAS 3 I'd like to have a savestating system which is a mix between the TASmod and LoTAS savestates which means:
- Naming savestates (LoTAS)
- Loading previous savestates via index (TASmod)
- Load the most recent savestate index (TAStools)
What I've seen already in the current LoTAS3 build folders are used to seperate savestates into worlds.
To keep with the backwards compatibility I would devise the following folder and naming structure:
.minecraft/
└── saves/
├── CoolWorld/
├── TestWorld/
└── savestates/
├── CoolWorld-Savestates/
│ ├── CoolWorld-Savestate1
│ ├── CoolWorld-Savestate2
│ └── CoolWorld-info.txt
└── TestWorld-Savestates/
├── TestWorld-Savestate1
├── TestWorld-Savestate2
└── TestWorld-info.txt
At the core, the savestates still have the old filename. Doing that, allows a person that wishes to downgrade savestates to LoTAS 2 to just move everything in a savestates folder outside to the savestates/ folder.
At the same time, it is easy to upgrade the savestates programmatically, can create the folder from the worldname.
Savestate.dat
Since we need to store the name, timestamp and index, we have to store this in an additional file like Savestate.dat
And a very controversial thing I'm gonna propose is: Keep the savestate.dat inside the savestate
That way, savestates are distinct from each other, can be edited around and so on, without relying on a central file, like it's the case in the current savestates.dat.
This makes it harder to collect the information which is then being sent to the client, but in all honesty, I don't think it's that hard...
TL:DR
- Savestate folder structure should include old filenames but with added folders
- The savestate list should be generated by searching through the folders, not by looking through a file
- Savestate.dat should lie in the savestate itself, not a central file
I'm unhappy with the current implementation of the indexing system for the following reason: The current one uses one file to monitor where each state is and what optional data it holds. This comes with one main issue:
- I cannot manually add or delete a state without breaking everything.
We can easily fix this by making the file a yaml or properties file so it's humanly readable. Additionally we can and should have everything managed by LoTAS, so that inexperienced users don't modify the state files and touch stuff they shouldn't have. Additionally with a readable file all the serialization and file update issues are gone and we can add new properties as we go along. I suggest this instead of your implementation.
The one you are recommending here has many drawbacks. First of all however: Backwards compatibility is not important. There are zero TAS projects going on right now and not a single person would switch tools mid run. Trying to get everything to work with the other mods is already impossible:
- TASmod will get a completely different stating system soon anyways
- TASTools has not been used in forever.
- LoTAS requires many files (for timer, velocity, name and more) in the state directory and will crash if they are missing.
With your implementation we also face some other issues:
- Deleting a state requires all states after to be renamed which may take ages
- Loading all states by querying through every single folder and file takes up a much longer time than reading a single file.
- The data of all states has to be parsed into a serializable format anyways to be able to send it between server and client, therefore we can just store that directly.
Deleting a state requires all folders to be renamed
Wrong. Thats what i mean with gaps in the savestate list. Current TASmod implementation doesn't rename anything on delete.
Querying all folders
We do that in Lotas2 and at least I haven't heard anyone complain that the savestate list loads too slowly... But sure, we can make a savestatelist for each world... If the user manually adds a savestate then we can add a reload button that regenerates the savestate list. The folders don't get queried, we still have all the features everyone is used to by now... And you have data that you can send off... However, the main data is not in the savestatelist... its just caching?
Also i don't mean to have LoTAS3 convert back to LoTAS2, that would be too much... just to have everything below unified into 1 definitive savestate system.
So: Make it possible to upgrade but not downgrade
Wrong. Thats what i mean with gaps in the savestate list. Current TASmod implementation doesn't rename anything on delete.
And when making a new state the last one is overriden? It's just sounds like a stupid idea to name savestates by index and then have gaps. At that point just give them a random hash and write down the sequence in another file.
We do that in Lotas2 and at least I haven't heard anyone complain that the savestate list loads too slowly... But sure, we can make a savestatelist for each world... If the user manually adds a savestate then we can add a reload button that regenerates the savestate list. The folders don't get queried, we still have all the features everyone is used to by now... And you have data that you can send off... However, the main data is not in the savestatelist... its just caching?
Sure that's a good idea. We can store stats and order in a (readable) file outside of the state and then have the state data like name, timestamp, image and what not inside of the state folder.
So: Make it possible to upgrade but not downgrade
No one will upgrade, nor downgrade, why go through the troubles of backwards compatibility. It's probably worse if we have a unified system and then 4 different implementations of savestating and loadstating. It WILL cause issues eventually.
Also what I haven't considered yet: Sharing savestates... A bit useless for LoTAS, but if you are in a project with multiple people, having 1 file would be kinda tedious... But you can import it through LoTAS with a gui... - No please no
And when making a new state the last one is overriden? It's just sounds like a stupid idea to name savestates by index and then have gaps. At that point just give them a random hash and write down the sequence in another file.
I have worked with the overriding part and I think it works quite well... If you go back one savestate then you don't need the newest savestate anymore if you made a better section. I recently found myself doing exactly that... Deleting the newest LoTAS savestate then create a savestate...
No one will upgrade, nor downgrade, why go through the troubles of backwards compatibility.
Lets think about this upgrading process... In my head it doesn't sound that difficult.
Currently all savestate worlds have a <worlname>-Savestate<index> Structure. Detect that and move it into subfolders with a worldname. Take the savestate index in the foldername and we have our SavestateIndex for that savestate. TAStools savestates are done.
Now LoTAS and TASmod have 2 different config files. Read them then decide what to do... For LoTAS we can do the same trick with getting the savestate index from the folder name and TASmod has a savestate index but no names and timestamps and whatnot, which I will not care about...
There, all three systems in 1 indexing system, make a new config file and hopefully we never have to deal with this stuff again
How about we make the first LoTAS version backwards compatible... If a new property comes on, we make it possible to update from LoTAS 3.0 to lets say 3.1... But we don't care about LoTAS2 to 3 at that point and throw out all the backwards compatibility code... Then the lovely user has the task of loading up each LoTAS version to upgrade their savestates
Added this in https://github.com/MinecraftTAS/LoTAS-Light/commit/acd38c978b3ed7858fa213abc926351bbe46ef73