RFC: Map IDs
-
For review & discussion, below is a design for the concept of a 'map-id'
Why have map-Ids?
To motivate the concept, there a number of problems today:
(A) Today maps are identified by their name. This has several drawbacks:
- Name collisons: It is difficult to know the full set of names that exist for all maps and so name collisions do occur. When map name collision occurs, the engine has no way to know one map from another.
- Lack of versioning information: Knowing just the name of a map does not tell you the version of that map. The engine today assumes that there only exists one version of any map, a latest, and has no capability for multiple versions of a map.
(B) Somewhat related, lack of versioning design for maps:
- Version meaning was never well defined
- Version value changes were manual
- The game engine (to my knowledge) never even used the version value found in map XML files
- Engine is not able to cope with old map versions, it assumes that any referenced map means the latest version of that map.
(C) The Engine is clunky about knowing if a map is actually installed
(D) Map-Name is overloaded: Ideally a map name would be just for display. You could update it, and everything would still work fine. That is not the case. For example map-skins have a somewhat complex way to encode the map name in the name of the map-skin and thereby identify the map. This is an exampel of an 'overload' of the map name because the map name is not only being used for display purposes, but also as the link between skin and map.
Introducing: 'map-id'
- Each map would be given a map-id, a UUID
- Map-id would live in the 'map.yml' file
- Re-using an existing UUID invalidates a map
- Changes to the UUID indicate a new version
map_name: example map # Generate a new UUID with: https://www.uuidgenerator.net/ map_id: e9d54edc-a828-4424-abd4-73a6b7b0320f games: - game_name: Great Game file_name: game-file.xml
Benefits of a Map-ID
- (A) MAJOR: Map makers can make any change they want to a map without worrying about breaking save games
- (B) Players connecting to each others games generally won't have to worry about map versions. All versions of each map will always be available, the game engine will be able to prompt to download for just about any version.
- (C) Map-ID uniquely identifies maps, removes the problems of using 'name'. While map names could still collide, the engine would be able to distinguish the maps.
- (D) Map-id being changed to a new value potentially solves versioning
- (E) Map-id solves a problem for skins, using map-id we can know exactly which map a map-skin is targetting.
Changes to Game Client (the engine)
To incorporate map-id, there are a number of systems that would be updated to use it.
Map Storage
To be able to store multiple versions, maps would need to be stored slightly differently on disk. Today we have:
{user-home}/ triplea/ downloadedMaps/ {map_slug_name}/ map.yml description.html preview.png map/ polygons.txt : : baseTiles/ : :
To be able to accommodate multiple versions, we can add a 'versioned' folder under the 'map_slug_name', the name of the folder would be the version number. To illustrate this:
{user-home}/ triplea/ downloadedMaps/ {map_slug_name}/ {version}/ <<< <<< <<< map.yml description.html preview.png map/ polygons.txt : : baseTiles/ : :
So, for example, we could have '270bc' installed with versions {3, 4, 100} in the following folder listings:
triplea/ downloadedMaps/ 270bc/ 3/ map.yml : : 4/ map.yml : : 100/ map.yml : :
In the above, each 'map.yml' contains a 'map-id'. The game engine can read the above and would know which versions are installed and their corresponding map-ids.
Map Detection
When checking if a map is installed, we'll need to do so by ID. When communicating which map is being played, we'll need to use the map id.
Map Download
Client would display latest version number on the download screen
Missing Maps & Missing Map Download
First, we could clean up the game-engine code for 'is-map-installed' to very cleanly know which map-ids are already installed. If a given map-id is then not installed, we can add an endpoint to the server that the client would query for a download-url. EG: "This map is not available on your system, but it is available for download, would you like to download it?"
Out of Date Map Detection
The 'version' of a map can be known by the name of the folder it is stored in. With this, we can drop the time stamp checks of last commit to last modified date and instead compare the latest version installed with latest on the server. This should work as version values will be simple, guaranteed ascending, numbers.
Changes to Lobby & Lobby Screens
We'll want to show the map version on the game hosting screen. The map-id should also become part of meta-data for lobby games. Before joining a game, a game-client warning can appear to ask a user to download a specific version if they do not have have it.
Loading Save Games
We'll need to embed the map-id into save games and read that back when loading save games. If the map-id is missing, we can prompt to download it, otherwise we can load up the correct version of the map.
Map scanning/loading
The game engine will need to be aware that multiple maps can be stored and update to scan for the 'map-id' in 'map.yml' files and to note the version number of map folders.
Changes to server
- The server would need to add 'map-id' to what it parses from the 'map.yml'
- It would need to keep track of which 'git-SHA' maps to which ID. When ever we see a new ID, we start recording a new database row so that we always know which 'map-id' corresponds to which 'git-SHA'
- Server would assign the 'version' value to each 'map-id'. Version would start at '1', and increment by '1' each time the 'map-id' changes.
- We should go ahead and start storing the per-SHA download URL in database and return that value as the download-URL for the client map-list query.
- Server would need to prune old versions from the download list and attach a 'version' field for the client
Map Skin Compatibility
Map-skins and map compatibility get complex. While map version and ID can advance, it is unlikely for someone to udpate all map skins to reference the new map-id. Likely when the map-id in a skin changes, the server will assume that the skin compatibility has only changed at that point. This implies that skins will need a 'skin-id', a 'skin-version', and the server would keep track of which 'skin-versions' map to which 'map-versions'