Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading JGRPP savegames in official OpenTTD gives "too new" instead of "modified version" error #8987

Open
James103 opened this issue Apr 10, 2021 · 5 comments
Labels
enhancement Issue would be a good enhancement; we accept Pull Requests!

Comments

@James103
Copy link
Contributor

James103 commented Apr 10, 2021

Version of OpenTTD

1.11.0

Expected result

Attempting to load a JGRPP savegame (with version >= 0x8000) in the official master or release branch results in the error
Game Load Failed - Savegame is made with a modified version.

Actual result

Attempting to load a JGRPP savegame (with version >= 0x8000) in the official master or release branch results in the error
Game Load Failed - Savegame is made with newer version.

Steps to reproduce

  1. Download and run any JGRPP version of OpenTTD.
  2. Using JGRPP, save a game.
  3. Download and run the latest official release or nightly version of OpenTTD.
  4. Using the official release or nightly, attempt to load the savegame that was saved using JGRPP.
  5. The loading fails with Game Load Failed - Savegame is made with newer version as it attempts to load a savegame whose version is approx. 0x8000 greater than the current latest savegame version.

Justification

The following text explains why using STR_GAME_SAVELOAD_ERROR_PATCHPACK would be more helpful instead of STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME:

/* Patchpacks for a while considered it a good idea to jump a few versions
* above our version for their savegames. But as time continued, this gap
* has been closing, up to the point we would start to reuse versions from
* their patchpacks. This is not a problem from our perspective: the
* savegame will simply fail to load because they all contain chunks we
* cannot digest. But, this gives for ugly errors. As we have plenty of
* versions anyway, we simply skip the versions we know belong to
* patchpacks. This way we can present the user with a clean error
* indicate he is loading a savegame from a patchpack.
* For future patchpack creators: please follow a system like JGRPP, where
* the version is masked with 0x8000, and the true version is stored in
* its own chunk with feature toggles.
*/

@TrueBrain
Copy link
Member

TrueBrain commented Apr 10, 2021

This ticket presents a solution rather than a problem, so it is always a bit tricky to look through that.

I am not a fan of using 0x8000 marker to detect patch-packs. For JGRPP it holds true, but JGRPP is not the only patchpack out there. There are several others, which use other ways to fiddle with their savegame versions. The block you reference shows this clearly. So if we would be to use 0x8000 it is specially for JGRPP, not for any patchpack.

That said, under this ticket is of course the question: when you load a savegame from a patchpack (any patchpack), it says it is made with a newer version. Which strictly seen is true, and as such, not a bug. But we could maybe be nicer about these things.

What I have been thinking for a while, that maybe we should include a string in the savegame to indicate what "version" it is. We set it to "vanilla", JGRPP can set it to "JGRPP", and any other patchpack to what-ever the want to be called. That means that if we spot a mismatch, we can tell where the savegame came from.

The other approach is to upstream some parts of the savegame system JGRPP uses, which allows us to detect if there are blocks we don't understand. That also makes it possible to give a more clear error.

All in all, there is a bit of investigation that needs to be done here, to solve the question: "can we better tell users when they are using the wrong patch-pack".

But, using 0x8000 is a no for me. As always, we have to keep the broader view, and not a narrow one :)

@TrueBrain TrueBrain added the enhancement Issue would be a good enhancement; we accept Pull Requests! label Apr 10, 2021
@FLHerne
Copy link
Contributor

FLHerne commented Apr 10, 2021

In case it's not clear -- the quoted comment including For future patchpack creators: please follow a system like JGRPP, where the version is masked with 0x8000 is already present in OpenTTD's saveload.h (since d8c8f4e).

It seems strange to 'officially' recommend this approach and then decline to support it. Also, JGR's has been by far the most-used patchpack for several years, so there will be many existing savegames even if future versions switch to a hypothetical alternative.

@TrueBrain
Copy link
Member

That is fair; I guess I didn't write that part as a "official" recommendation, but your reasoning is sound to me. We have to be a bit careful, as it is fairly recent we added that (as you pointed out).

I still think that we should do better in making it more clear where savegames came from, but as I said, this ticket presents a solution, not a problem, which makes that a bit hard.

FLHerne added a commit to FLHerne/OpenTTD that referenced this issue Apr 10, 2021
…ad JGRPP savegames

Previously 'newer version' which was unhelpful.
@JGRennison
Copy link
Contributor

The current savegame header is a fixed 8 bytes in size, and doesn't include any spare bits which could be used to indicate "extended header follows", because of that there isn't an obvious place to put such a version string as suggested above.
You could make such a header conditional on the savegame version in the header, but you would need to handle the case where you're trying to load a savegame with a version number which suggests that the header should be there, but without such an extended header actually being present.

You could this in a chunk, but it's also worth noting that historically patchpacks have had different chunk headers which aren't ordinarily readable by trunk. (SpringPP and ChillPP both had this, my branch only has this for extra-large chunks).

For what it's worth more recent versions of my branch do include the complete version string in the extended version info chunk, specifically so that user of my branch get a friendlier error message when trying to load saves from an even newer version of my branch.
However you'd need to include a reasonably complete parser for the chunk format to get at it, which is probably not what you want.

@TrueBrain
Copy link
Member

Personally, I am not against vanilla being to read (and also use) your extended version info chunk, but I know that indeed it won't be trivial to get there :) It is just the more proper solution .. tnx for explaining this in high detail, much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Issue would be a good enhancement; we accept Pull Requests!
Projects
None yet
Development

No branches or pull requests

4 participants