supertux
supertux copied to clipboard
Level backwards compatibility
Some gameplay features can change after merging a PR. For example, the frog enemy may suddenly have different jump heights. This can break existing levels which rely on specific behaviour of the game (example: mr ice block wall jump levels). It is possible to add a version information to the levels which can be used to decide on which features must be disabled for this level to work correctly. However, old behaviour would need to be kept in the code, which makes the code much more difficult to understand.
We have a (version x) stamp already in level files. If we extend that, that could work very well.
It is possible to add a version information to the levels which can be used to decide on which features must be disabled for this level to work correctly. However, old behaviour would need to be kept in the code, which makes the code much more difficult to understand.
-
I think the gameplay features that matter most are the high level behaviors of badguys, and these usually have a corresponding art change to indicate them. For example, original (fire-avoiding) Igel vs updated (rolling) Igel; or (flying-snowball-like) spidermite vs (larger, with fall/retract stages) tarantula.
-
Having multiple versions of behavior for (visually) the same object could be confusing. For example, if Tux could only swim on newer levels, players might on older levels try to jump into water and unexpectedly fall off the bottom of the level, which would be frustrating and make it unclear when water is safe. It would also be surprising if e.g. a Snowball were no longer squishable, a regular Stalactite could randomly choose when to fall, or a Spiky were fireproof in one level but not another.
-
Having old and new behavior in a single class would risk accidentally changing the old behavior whenever the new behavior is tweaked.
Consequently, I think the most practical versioning approach would be to, whenever a badguy's behavior changes significantly (which usually comes with an artwork change, anyway), to make a new copy of its class with a slightly different name. For example, if WalkingLeaf has a major change, put original WalkingLeaf in walkingleaf.cpp, and new WalkingLeaf2 in walkingleaf2.cpp, and move the original WalkingLeaf to an "Old" category in the level editor. As migrating to the new version would likely require minor level adjustments anyway, replacing the old with the new version should be done level by level. Minor behavior changes (like making WalkingLeaf 5% faster or having Frogs jump at a slightly steeper angle) are unlikely to harm most older levels that much. This approach does come at the cost of increased code duplication, but I think that would be easier (albeit more tedious) to work with than having classes that do too many things.
Not supporting backwards compatibility would be another option. Levels bundled with SuperTux can be updated before a release and levels from somewhere else, e.g. from AddOns, self-made or from the internet, can be designed such that they work for one version and may be broken in any other version. A version stamp could still be used to show a warning in the editor when the level is opened in a different release version.
Not supporting backwards compatibility would be another option.
Level backwards compatibility does not need to be a binary decision; levels don't suddenly and entirely break as things change so much as progressively degrade, and the choice is how much to mitigate that. Breakage with physics tweaks or added swimming may be unavoidable; on the other hand, things like tileset id changes, renaming sprites, and major badguy behavioral changes can be mitigated by not doing them, adding redirections, providing automatic upgrade scripts, or keeping older badguy code and images around. Increasing the effort required to keep levels up to date will either push tedious upgrade work on people making their own or published addon levels, or shrink the population of addon levels with every release; I don't think either of these possibilities would be good for the game in the long run.
version stamp could still be used to show a warning in the editor when the level is opened in a different release version.
There already is a version field for levels, that hasn't changed in a while; it's currently set to 3. Maybe it should be increased whenever SuperTux makes a new major release? One could exactly encode versions using larger numbers like 700100 for version 7.1.
I think the version number could be the release number with additional information, e.g. patch number, commit id if the build is not a release. Instead of encoding the version as an integer, it could also simply be saved as string, e.g. "7.1" for version 7.1.
Level backwards compatibility is not desirable, it would introduce many gameplay inconsistencies, chaos in the game's code + it's easy to traverse game versions.