User:WolfieMario/Minecraft Map Updater

Notice: This page describes a file format to be used by a program I plan to write. As of this writing, the program does not actually exist in any form; I will update this article with links to the program once it exists. If you somehow stumbled onto this page, feel free to ask questions or make suggestions on the Talk page - although I won't necessarily follow through on a suggestion unless I find it useful and fitting enough to implement. --WolfieMario 22:31, 5 August 2013 (UTC)

The Minecraft Map Updater is a Python-based world patching tool (using pymclevel for level manipulation) which can be used to update, patch, or "refresh" Minecraft maps. It is intended mainly for adventure maps which are frequently being updated (as it allows players to play on an updated copy of the map without losing their progress), but it can also be used for other purposes such as integrating new content into a server.

The Updater uses an updater.dat file created by the map's authors/distributors to determine exactly how it is supposed to patch old and new versions of a map together. The actions taken by the Updater depend on the contents of the updater.dat file and the versions of the maps being patched together. Although the updater.dat format is complicated and provides many settings for a map maker, the Minecraft Map Updater itself is designed to be simple for end-users to use, with minimal settings.

Minecraft Map Updater
The Minecraft Map Updater presents the user a simple GUI, where they can select a world to update (the "source map"), a world to patch their source map with (the "update map"), and a directory and name for the world the program is to output (the "output map"). The source and update maps may be given as world folders, level.dat files, or updater.dat files. Regardless of how they are given, the source and update maps must have a level.dat file each, and the update map must also have an updater.dat file. In addition, the output map directory must be empty, or the user is warned that map corruption may occur.

Note that Bukkit splits worlds into three folders (" ", " _nether", and " _the_end"), so if a user is using a Bukkit world as the source or update map, or wishes the output map to be split as a Bukkit world, they may check the relevant checkboxes. The user will be notified about these checkboxes when selecting such a world, and will be warned if one or more dimension folders cannot be found. Note that when selecting such worlds, the main (overworld) dimension's folder, level.dat, or updater.dat must be selected.

The Patch button becomes enabled once all of these settings are provided, as long as the source map's version is less than that of the update map. The Refresh button appears in place of the Patch button if the source and update maps have the same version and Refreshing has been enabled. Information about the update map is also presented to the user when the update map has been selected - this information is provided by the updater.dat and level.dat files.

Versions
Updater.dat files contain map version strings in them, used to distinguish versions of the map and decide which versions are older or newer. A version string can be anything, but for the purposes of comparing version order, the Updater will only read numbers, delimited by any other characters to distinguish major and minor sub-versions. For example, "1.2.0", "1.2.6", "1.24.0", and "2.0.0" are ordered from oldest to newest, and "12w25b" comes after "aaa1aa3aa26a". Note that "1.5.2" matches "1w5a2" and even "1.5.2.0". Note that negative version numbers are not possible, as the minus sign is interpreted just as any other character; "-2.4" matches "2.4" and "2-4". Also, although "0", "null", and "minecraft" would all be interpreted as the same version, the value "unknown" is reserved and cannot be an actual version number.

Updates
The updater.dat file of the update map is meant to contain information about how the Updater is to patch the map. This information is packaged into individual "updates", which decide what blocks, entities, and other data to copy from the update map to the source map, and what information to reset or delete in the source map.

These updates always go from one version of the map to another (these are an update's "from version" and "to version", respectively), and not all updates packaged in an updater.dat need to be used. Some updates are "version-strict", meaning they cannot be used unless the map is being updated from the exact "from version" the update is specified for. If an update is not version-strict, it can update maps which are older than this "from version" as well.

The user will never have to worry about the details of these updates or versions, as they will be handled by the Updater.

Restrictions
There are a number of restrictions on the use of the Updater, to reduce the risk of world corruptions. These are grouped into two categories: strong and loose restrictions. Strong restrictions cannot be ignored. Conversely, loose restrictions only alert the user with warnings, which can be ignored (or even hidden altogether by a setting in the updater.dat of the update map).

Strong Restrictions:


 * Both the source map and the update map must have a level.dat file.
 * The update map must have an updater.dat file.
 * The updater.dat file must not be invalid (e.g. missing required fields or having tags of the wrong data type).
 * The source map's version must not match the update map's version in order to Patch.
 * The source map's version must match the update map's version in order to Refresh, and the Refresh feature must be enabled in the updater.dat of the update map.
 * If the update map is version-strict, the source map must be "compatible".

Loose Restrictions:


 * Users are warned when an updater.dat claims to be intended for a newer version of the Minecraft Map Updater than their current version.
 * Users are warned when the output map's directory is not empty and they attempt to Patch or Refresh.
 * Users are warned when attempting to Patch or Refresh if the source map and update maps' internal mapNames (in the updater.dat files) do not match, or if the source map does not have an updater.dat (and thus its name cannot be verified).

Update Processes
Whether the user chooses to Patch or Refresh the map, if the process is not aborted, files will be copied into the output map's directory. Neither process causes any changes to the source map or update map, but files in the output map's directory may be overwritten if it is not empty when the process begins (the user is warned if this is the case).

Note that the updater.dat of the update map decides how files are copied. Depending on settings, various files will be copied from the source map and various files from the update map, after which these files will be modified until the patching/refreshing process is complete. After a Patch or Refresh process has completed, the update map's updater.dat is always copied to the output map.

Patching
When the Patch button is clicked, the updater will check for various restrictions, and if a "loose restriction" is violated (and warnings aren't disabled), the user will be warned and given an option to cancel the operation. If no restrictions are violated, or the user chooses to continue the patch anyhow, the Updater will queue updates from the updater.dat of the update map, and execute them.

If the updater.dat itself is not marked version-strict, the queue is built with the following algorithm:


 * 1) Define "current version" as the version of the source map. If the source map lacks an updater.dat, assume the current version is "unknown".
 * 2) Find any updates with the lowest "from version" which is not less than the current version.
 * 3) If no such versions exist, skip to step 7.
 * 4) From these updates, select one which also has the highest "to version". Ties are broken by using the first such update found.
 * 5) Queue the selected version, and redefine "current version" as this update's "to version".
 * 6) If the current version is still less than the update map's version, go back to step 2.
 * 7) Finally, queue a special, unversioned update. This update will always be the final update in the queue.

Note that an update will never be queued in an "incompatible" position. An update with a "from version" less than the current version is considered incompatible for that position, as is a version-strict update whose "from version" does not match the current version. Also note that if the current version is "unknown" because the source map lacks an updater.dat, it will only match a version-strict "from version" if its value is also "unknown" (if it's not version-strict, it will match any "from version").

The special final update implicitly has a "from version" and "to version" equal to the updater.dat's version, and can be considered "version-strict" if the updater.dat itself has been marked version-strict. Because this update is mandatory, the above algorithm cannot be used if the updater.dat is version-strict (as the above algorithm does not guarantee that the "to version" of the update preceding the final update matches the update map's version).

If the updater.dat is version-strict, then a different approach, using a backtracking algorithm, is applied. If the algorithm cannot find a solution where the final update is not considered incompatible, the process will abort altogether and the user will be notified that "The map you are trying to update is too old and cannot be updated directly to this version. You must first update this map to one of the following versions: ", followed by a list of known versions which would not cause the process to abort (this list is generated based on the "from version"s of all updates which would allow the process to succeed).

Finally, if the queue is successfully built and the process does not abort, files are copied to the output directory and all updates are applied onto them sequentially in the order in which they were queued.

Refreshing
If the source map and update map are of the same version, then in place of the Patch button, a Refresh button will appear. It will only be enabled if the update map's updater.dat has been set to support the Refresh feature.

If the user clicks the Refresh button (and no warnings appear or they do not cancel), the map will be "updated" with the same special unversioned update which is normally at the end of an update queue. The Refresh function is practical in maps where the special update has been configured to "refresh" the map (for example, reverting any changes which have happened in a certain area, or restoring entities or dispenser contents). Note that the Refresh feature should not be enabled for maps where the special update can revert a user's progress, unless this is intended (the updater.dat can be configured to warn the user if necessary).