dscalzi / ItemCodexLib

Library to dynamically retrieve items by alias, enum, or legacy data. (1.8-1.13)
MIT License
4 stars 2 forks source link

Library Improvements #3

Open dscalzi opened 5 years ago

dscalzi commented 5 years ago

Add a UUID for items.

Currently minecraft has no static id to represent items across different versions. With the removal of item ids, we are left with string identifiers which are likely to change with every version bump. Spigot's enum identification usually matches these changes across versions.

Eg.

1.13 -> SIGN 1.14 -> OAK_SIGN

This is not a problem for most applications, however an issue arises when plugins want to store item id information in a database, say for a shop plugin. The data would need to be transformed, either manually or via a script each time these changes occur.

Solution

We tag each item with a UUID. These tags will remain static across versions. For example, SIGN would be tagged with the same id that OAK_SIGN is tagged with in the 1.14 version. This would be an additional field in the ItemEntry class, such as versionSafeId.

This will required us as library maintainers to preserve a mapping of which item ids were renamed per version. I would like to preserve compatibility from 1.8 to present (at least until these older versions are dropped). We should be able to use the legacy id to generate these mappings for items which were added prior to 1.13. As such, the only mapping we should need is from 1.13 -> 1.14 and so forth.

File Merging

Currently we preserve a single items.json file. This is fine if our intention is to support only the latest version of minecraft. As mentioned in the previous section, item identification within spigot changes between each major version bump. The API utilities already are able to handle a merged file, as they will only load items for which a mapping in the spigot enum is found.

To perform the merge, the following would be required.

  1. Externalize the items.json file to its own project/repo and store a unique one for each major version (1.8 - 1.14).
  2. In the merging function, specify which versions the merged file should be compatible with.
  3. Take the oldest specified version and copy all of the data into the merged file.
  4. For each subsequent version, match against the version data already present. If not present, prepend the data to the top of the file. Each version section should have clear boundaries to make editing the file easier. (There are no comments in json, maybe a dummy propery or object).
  5. If the data is present, we need to ensure that the underlying identifiers are the same. If they aren't we will need to version segregate the item data. The API implementation would need to be updated to account for this.

This could be delivered to the end user in several ways.

The merge functionality should probably be written in groovy, so that if we do decide to ever make it a gradle plugin, a rewrite would not be required.

Items.json Generation Library

Updates are currently done by hand, which can be tedious. This could be automated.

We would create a Typescript library called ItemCodexScribe. The generation function would require two inputs, the items.json for the previous version, the spigot enum file, and a mapping for updated item data (ex, SIGN -> OAK_SIGN). For each enum entry, we would..

We could also add utility functions to assist in creating a mapping, such as scanning the enum file and reporting which entries are present in the old version, but arent in the latest. We would need to examine these values and determine which were updated and which were removed.


Of these three tasks, the item UUID should be figured out first as the generation and merging functions depend on it to a certain degree.

dscalzi commented 5 years ago

cc @HyKurtis

dscalzi commented 5 years ago

The merged JSON can take the following form

[
    {
        "uuid": "8d6f24b7-489f-4511-a210-890d580c808f",
        "data": {
            "1.14": {
                "spigot": {
                    "material": "OAK_SIGN"
                }
            },
            "1.13": {
                "spigot": {
                    "material": "SIGN"
                }
            }
        },
        "legacy": {
            "id": 323,
            "data": 0
        },
        "aliases": [
            "sign",
            "oaksign"
        ]
    },
    {
        "uuid": "c345ecc5-3987-45ad-96e4-6ac3494ffc52",
        "spigot": {
            "material": "STONE"
        },
        "legacy": {
            "id": 1,
            "data": 0
        },
        "aliases": [
            "stone",
            "rock"
        ]
    }
]

The spigot property would remain at the top level of the ItemEntry. Version specific data would be encapsulated inside of the data object, The API would select the version closest to the one running on the current server and load that in.