Slow additions or experimental fork

Started by Simon, November 30, 2021, 06:12:09 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Simon

Hi,

here is some very-high-level strategy for the future of Lix: It's not the high-level 2022 roadmap, but even higher level.

How will I introduce breaking changes? I've been really conservative, I haven't changed the physics at all since 2017. Why is that? And how will the next 5 years look like?

Debian problem: Every 2 years, Debian, the linux distro, allows major software updates. We have a package with Lix 0.9.x in Debian, thanks to tarzeau. :lix-cool: Debian shuns non-bugfix patches in-between the releases, therefore Lix's physics updates will only land in the Debian Lix package every 2 years. The Lix game server (running on a machine that I rented, has nothing to do with Debian) accepts players from all operating systems, including Debian, but requires that everybody has the same minor version of Lix (either all have 0.9.xx, or all have 0.10.xx, ...). Therefore: If we change the physics in stable Lix releases more often, Debian players will not be able to play on the server. But I want them to be able to play.

The Debian problem is paramount in my Lix project planning. I want the Debianists to play. I don't want to lock them out of the server for over a year.

Therefore, I see two possible paths forward:

Careful addition:
  • Rework the existing server to accept players from different minor versions (0.9.xx, 0.10.xx, ...) and ensure that you only join rooms with same-version players. If this takes weeks to be nice, so be it.
  • Work on the existing problems one-at-a-time.
  • Introduce physics changes only when well-tested in singleplayer, and move all culture to the new stable. Ideally, create some unittests for physics.
  • Only extend the level format, don't replace it entirely.
  • Introduce neutral lix only after careful assession how they fit best into the existing level format.
Massive feature bloat:
  • Immediately split an experimental from stable, and run two multiplayer servers.
  • Add neutral lix, add unstable features, add new skills
  • possibly cut/change/merge skills to make room in hotkey layout
  • Change level format in whatever incompatible way I want.
  • Expect the stable and the experimental to be split for years.
The 5-year-old child in me wants to bloat 7 features and then cut 3 of them. I haven't done this in software for years. It's refreshing to make features without spending 90 % of the time on how to make it agree with the rest of the software. We can bloat dumb features and ditch them if they suck!

The software architect in me isn't so sure, warns that those 90 % will be spent anyway in the future, and wants more caffeine now. Also, I don't know if I have the free time for enough features that warrant a fork.

The community priest in me wants everybody under the same nice comfortable stable version, and no arguments that feature X will be cut in any experimental version. Debianists will always enjoy the same perks as those who run the hottest new stuff, because only highest-quality hot stuff leaves the factory in the first place.

-- Simon

Simon

#1
Nessy recommends the careful approach.
Flopsy isn't sure, weakly suggests the careful approach.

It's possible to start the careful approach with the multiplayer server, then decide again for the client side, e.g., for physics.

In the long term, I'd like one server program to handle several client versions anyway. It makes a lot of sense to start here, then. Once the server supports different physics in different rooms, we can still fork an experimental client with physics features, or proceed with careful iterations even on the client side.

-- Simon

WillLem

I strongly recommend the experimental option, because this will give you a chance to try out features in a stable(ish) environment before adding them to the main version.

There is no need to release the experimental version, after all - it can be for your own purposes. Then again, some players like to be able to experiment with new features that may or may not make it into stable, so sharing it for feedback purposes/general good fun is a good idea.

Forestidia86

Quote from: Simon on November 30, 2021, 06:12:09 AM
Introduce physics changes only when well-tested in singleplayer, and move all culture to the new stable. Ideally, create some unittests for physics.
Only extend the level format, don't replace it entirely.

I think breaking the level format should only be done if absolutely needed. Backwards compatibility has a high value in this respect since Lix has a lot of levels. Physics changes don't need to necessarily lead to much breakage.

I agree with WillLem that an experimental branch would be a good idea even in the careful approach. To have physics changes well-tested you need them tested in some way, which can be achieved with an experimental branch. An experimental branch would give the courage to pull through the physics changes, which are in the waiting line for so long.


namida

Format breakages in NeoLemmix have almost always lead to issues, including people coming along many years later with content they never got around to updating the format of - or worse, creating content for old versions when they're already long-since-obsolete.

This isn't to say "don't do it". Just "proceed with caution". Presumably, Lix would keep backwards-compatibility, and it would only be a problem for older versions loading newer levels. In this case, the user should update their software.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

Dominator_101

Debian wants you to only make major updates every 2 years? Dang, that's a heck of a lot to ask for software dev, especially in this day and age...Though, admittedly I'm unfamiliar with most things Linux, so maybe this isn't that weird.

Anyway, on the dev side of things, I think that there might be some middle ground to the two plans.

I think that reworking the server to allow multiple versions to connect to it but only allow connections to the same minor version makes sense to add in general, even regardless of Debian stuff. It might be the case that not everyone updates instantly even on other platforms (since far as I'm aware there's no auto update), and it might also be the case that you want to have someone help you test a beta feature or something without worrying about what happens if someone else mistakenly joins the server. Making this change I think can be what allows you to make riskier changes without worrying about the Debian problem.

On the topic of the level format, from my experience I would say that changing a format like that is generally the last thing I want to do, as it just causes so many headaches (what to do with old data, etc), so I would say it's at least worth exploring how something can fit in the existing format before just changing it. That said, sometimes there's just nothing you can do no matter how malleable you tried to make the initial format because of things you just didn't think about. It can be kind of a balance here; sure, you might spend X amount of time exploring how the new feature could fit in the old format, but if it takes 3X time to design the new format/change the parsing code/figure out how to handle old formats, then it might not be worth it. One thing maybe worth considering also is if you can support multiple level parsers in one version (I know nothing about how the levels are parsed now). Could it be possible to add some 'format version' to the level layout that tells the parser how to handle any given level (and assume anything without this field is the old format). Maybe not the most elegant, but sometimes better than worrying about how to update all the existing data somehow.

Another thing with experimental features, in relation to whether or not to worry about spending time making it agree with the rest of the software; you could always do a quick and dirty version of a feature first as a test (does the feature work well, is it actually as fun as we thought, etc) before doing a second pass to make it 'fit' better if needed. It obviously would require a bit of rework, but sometimes after making something once when you take a step back and think about how you would design it again I find that I have a better understanding and better ideas on how to go about it, so it might be easier to fit it in more agreeably when you already have a general understanding of what needs to be done. Also, in relation to not wanting to cut something in an experimental version, don't be afraid to cut a feature if it doesn't turn out well in testing. If a feature just isn't fun, or doesn't work well, or whatever, don't let it hang around just because of the sunk cost fallacy.

Anyway, this ended up a bit more long winded then expected :P Some of these are probably already things you've thought of, but figured it was at least worth stating in case you hadn't. I'm likely not the best coder here, but I'm always happy to bounce ideas around if you need more eyes. I even wouldn't be against getting my hands in there, but not being familiar with the source language might make that a bit trickier.

geoo

QuoteOnly extend the level format, don't replace it entirely.
I'm not sure I understand the point of this. If you add new level features, newer levels will not work as intended in older versions of the game, regardless of whether you replace the format or not. Similarly, if you keep the code for reading the old format, you will still have backward compatibility. Presumably this doesn't add much maintenance overhead as you will likely be making mostly additions, not changes, to the internal Level interface in the future. (Or does the server partially parse the level format as well?) It seems to me that many proposed additions, e.g. hatch-specific metadata, would be pretty awkward with the existing format.

QuoteIntroduce physics changes only when well-tested in singleplayer, and move all culture to the new stable.
This might not be feasible if you have features affecting multiplayer, e.g. explicit assignments of hatches to players, or neutrals. If you want to incrementally build and test new features together with the community on the central server and expect to iterate over/tweak the details, you'd either have to bump up the minor version all the time (and have a server that allows different versions to connect), or have the experimental fork with its own server (and merge an experimental feature into main whenever you're satisfied with it). Even with an experimental server, it seems more sensible to work on one feature at a time, and with the expectation that after playtesting said feature will be merged into main as soon as you're satisfied with it, or scrapped. (And thus allowing multiple versions to connect to the same server seems like a sensible addition regardless of the Debian situation, which in practice probably affects ~0 users.)

An experimental fork that has a whole bunch of features some of which we want to keep and some of which to scrap sounds like a mess, and stable and experimental being out of sync for ages sounds like a bad idea.

Simon

#7
Thanks for all the replies.

In the end, I'm eager to experiment with physics. Anything that allows wild forking is good, even if we don't fork, or if we fork and frequently merge features into stable. Some experimental forking is unavoidable anyway, there must be multiplayer playtesting before we decide to nail a feature onto the stable.

Level format: If I move to entirely new format, yes, I'll keep loading code, but ditch the saving code and encourage to convert levels to new formats. Otherwise, consequentially, I'd have to save in two formats whenever a level is expressible in the 0.9 format. The concerns of a level format changes are long-term; they'll bite me in 5 years when it comes to cutting support for older formats.

I have a lot of sentiment to have the game always load things even from 15 years ago. There will be no discussion of cutting ancient loading code if we only tack onto the 0.9 format. This is the main benefit of extending the format, even though it too breaks forward compatibility of 0.9 software. The main problem is that it will be painful to tack heavy nesting or too many switches onto tile lines in the 0.9 level format.

It's conceivable to write extra tools that convert levels/replays/tilesets/... that never ditch support even for archaic formats. E.g., in C++ Lix, I had --convert-and-overwrite in the main executable to make replays skill-slot-independent. Such tooling takes extra care to maintain.

The Debian problem will affect only few users, probably 0, I agree. Still, I don't want to break compatibility of 0.9 with the central server yet.

It has to be a middle ground, yeah.

-- Simon