Wednesday, September 3, 2014

Abiathar Confidential: A History of Backward Compatibility

I'm away from all electronic communications this week; enjoy automatically-published issues of Abiathar Confidential!

There have been a lot of Abiathar versions (over 20 if you count betas given to testers), and I always do my best to ensure you never have to run through the Dependency Collector or New Project Wizard again. Here, I provide a history of what compatibility measures are taken to make sure new versions of Abiathar can understand files produced by old versions.

The pre-release versions of Abiathar, back when it was still called Fudge, used a very simple format for the *.fudge (now *.adeps) files. It was basically:

  • The profile name
  • Whether it used default graphics
  • Names of resources
  • Local config (XML)
(To be honest, I don't remember when the XML blob got shoved onto the end of the file. It appears in v1.0 dependency objects, though.) One thing you will notice is that there is no marker for the version that saved the file. There is, as of v1.0, a version line at the beginning; that wasn't always there. In fact, it was added only a few days before the release; the testers never had a version that included it. So, when I realized that versioning is important, I had to implement backward compatibility right off the bat. Even v1.0 checks to see if there is a VERSION directive at the top and, if not, assumes the version is VersionId.PreRelease.

v1.1 added the ability to edit tileinfo in addition to displaying it, so the tileinfo line had to be extended. The new format was a metamap option character, a space, and the tileinfo file name if necessary. The metamap option character was used to get a set of policies for the handling of tileinfo e.g. whether to allow modifying it or whether it should be loaded from and saved to the MAPHEAD. When loading *.adeps files from v1.0, v1.1 gave it a default MOC of "R", a separate file that cannot be edited.

v1.2 was a fairly boring update if you're only looking for new features. It fixed a lot of bugs and changed the defaults for some settings in persist.aconf. These new defaults were not forced upon anybody and I would have no way to do so because Abiathar didn't save versioning information in the config files at this point. To get the new defaults, people had to delete persist.aconf to make Abiathar regenerate it.

v1.3 added the Level Inspector and Resource Accountant. Both of these required a huge amount of configuration and would have been totally crippled without updating persist.aconf. I had still not added versioning to config files, so the auto-update script for v1.3 just deleted persist.aconf and that was that.

v1.4 was, despite not having a lot of shocking new features, a pivotal update for Abiathar. The entire profile system was done away with, instead being replaced with a decentralized system of templates. Additionally, the XML structures used everywhere were thrown out and in came FrofConf. With this level of change going on, I gave up on backward compatibility. After v1.4, no version of Abiathar can read anything from a pre-1.4 version. Additionally, profiles.aconf was split into editor.aconf (for GUI settings) and defaults.aconf (for very complicated template stuff).

In v2.0, lots and lots of new features were added, but I took advantage of some amazing FrofConf features to ensure backward compatibility with v1.4. Here, every piece of information saved by Abiathar has a version tag. Whenever it's loaded, it calls AdaptVersion to process all the legacy entries and convert them to new structures. With load-only entries, I can read legacy information but not have to worry about it outside AdaptVersion. This is used on HuffCompressedMaps, for example, to set v2.0's MapType to "Carmack" or "Huffman".

After that, as I'm adding lots of new structures, the default value is always Nothing. All the code checks for null and will produce a "blahblahblah is not configured" dialog box. The upcoming v2.2 will check to see if AudioFormat is Nothing before trying to show the user audio-related stuff.

How do new features get enabled, then? AdaptVersion creates an in-memory default configuration file and copies important sections into the real one. In v2.1, Bio Menace templates were injected into the template list using AdaptVersion. (The Dreams template was also rebranded "Keen Dreams".) I imagine I'll use something like that in v2.2 to copy in the audio chunk layout.

So here we are. It is my goal to make sure you can always use old dependency files in new Abiathar versions to continue working seamlessly while also integrating new features for innovative modders.

No comments:

Post a Comment