{"id":43822648,"url":"https://github.com/PaperMC/DataConverter","last_synced_at":"2026-02-17T15:00:54.882Z","repository":{"id":38327306,"uuid":"374456724","full_name":"PaperMC/DataConverter","owner":"PaperMC","description":"Rewrite of the dataconverter system for performance. ","archived":false,"fork":false,"pushed_at":"2025-12-31T16:54:46.000Z","size":947,"stargazers_count":73,"open_issues_count":3,"forks_count":10,"subscribers_count":12,"default_branch":"master","last_synced_at":"2026-02-08T09:54:39.566Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PaperMC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"PaperMC","open_collective":"PaperMC"}},"created_at":"2021-06-06T20:24:13.000Z","updated_at":"2025-12-31T16:54:51.000Z","dependencies_parsed_at":"2023-12-17T19:00:32.774Z","dependency_job_id":"76a3284f-8320-4015-bacb-473e60718d37","html_url":"https://github.com/PaperMC/DataConverter","commit_stats":{"total_commits":118,"total_committers":7,"mean_commits":"16.857142857142858","dds":0.1694915254237288,"last_synced_commit":"61cb9900990bb6c0cae4201c126dfdfa2102934c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PaperMC/DataConverter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaperMC%2FDataConverter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaperMC%2FDataConverter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaperMC%2FDataConverter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaperMC%2FDataConverter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaperMC","download_url":"https://codeload.github.com/PaperMC/DataConverter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaperMC%2FDataConverter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29548201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T14:33:00.708Z","status":"ssl_error","status_checked_at":"2026-02-17T14:32:58.657Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-06T02:00:29.837Z","updated_at":"2026-02-17T15:00:54.875Z","avatar_url":"https://github.com/PaperMC.png","language":"Java","readme":"DataConverter\n==\n\nThis mod completely rewrites the dataconverter system for Minecraft.\nPlease note that this fabric mod is not to be used. It is published\nand maintained here for the sole purpose of being able to update\nto snapshot versions. By updating to snapshot versions, more testing\ncan be done throughout the update process, and diffs between\nversions can be tracked more easily.\n\nThis mod will never have a released version. Above everything else\nI want worlds to convert correctly, so I cannot publish this mod in\ngood conscience. This mod does not account for datafixers registered \nby other mods. When you use this mod, you completely accept the risk \nthat dataconverters _WILL NOT RUN_ on your mods' data. Your world \ndata _WILL BECOME CORRUPT_ as a result, and it is entirely **YOUR FAULT**.\n\nIf you want to use this mod, please use [Paper](https://github.com/PaperMC/Paper).\nBecause plugins cannot register datafixers with DFU, there is no risk\nof non-vanilla datafixers being skipped. Plugins that run things through\nDFU are not affected, because this mod only redirects Vanilla calls to\nDFU to use the new converter system - so it does not affect DFU. It just\ndoesn't use it.\n\n\n# Technical overview\n\n### DFU Schema\n\nDFU uses Schema's to define data layouts for types. They don't define all fields \nin the type, just the parts that need to be looked at for conversion. For example, \nhere is the schema specification for Enderman (V100, 15w32a):\n```java\n        schema.register(map, \"Enderman\", (string) -\u003e {\n            return DSL.optionalFields(\"carried\", References.BLOCK_NAME.in(schema), equipment(schema));\n        });\n```\n\nThis specifies that the root CompoundTag for Enderman contains a `BLOCK_NAME` at path \"carried.\"\nIt should be obvious that Schemas tell DFU's type system where to look if a datafixer wants to convert\nBLOCK_NAME in this case. \nMore complicated schemas exist, for example (V100 again):\n```java\n        schema.registerType(false, References.STRUCTURE, () -\u003e {\n            return DSL.optionalFields(\n                \"entities\", DSL.list(\n                    DSL.optionalFields(\"nbt\", References.ENTITY_TREE.in(schema))\n                ), \n                \"blocks\", DSL.list(\n                    DSL.optionalFields(\"nbt\", References.BLOCK_ENTITY.in(schema))\n                ), \n                \"palette\", DSL.list(References.BLOCK_STATE.in(schema))\n            );\n        });\n```\n\nThis schema specifies that the root tag of `STRUCTURE` contains 3 paths: `entities`, `blocks`, and `palette`.\n\nIn the `entities` path, it specifies that it's a List and that the list contains fields, so it is typically\na `CompoundTag`. This `CompoundTag` contains a field called \"nbt\", and the value represents an `ENTITY_TREE`.\n\nThe `blocks` path is similar to the `entities` path, except its \"nbt\" field represents a `BLOCK_ENTITY`, not\nan `ENTITY_TREE`.\n\nFinally, the `palette` field represents a list _of_ `BLOCK_STATE`.\n\nThis aspect of DFU is the cleanest, and allows Mojang to define types easily and reliably - datafixers\njust need to define what type they want to modify, and the type system of DFU will navigate to the\ntypes and run them through the datafixer.\n\n### DataConverter DataWalker\n\nLike the DFU Schema, the DataWalker is designed to specify the data layout of types for\ndataconverters. However, the DataWalker's responsibly isn't to lay out the data - it's to\nactually _run_ the converters. For example, take the schemas above, here are the DataWalker\nimplementations:\n\n```java\n        MCTypeRegistry.ENTITY.addWalker(VERSION, \"Enderman\", (data, fromVersion, toVersion) -\u003e {\n            WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, data, \"carried\", fromVersion, toVersion);\n\n            // only return something if we want the root tag to change, but we don't - so ret null. Don't worry about this,\n            // no DataWalker is actually recommended to do this.\n            return null;\n        });\n```\n\nAs you can see, the DataWalker is simply a piece of code that calls converters.\n\nFor the more complicated Schema:\n\n```java\n        MCTypeRegistry.STRUCTURE.addStructureWalker(VERSION, (data, fromVersion, toVersion) -\u003e {\n            final ListType entities = data.getList(\"entities\", ObjectType.MAP);\n            if (entities != null) {\n                for (int i = 0, len = entities.size(); i \u003c len; ++i) {\n                    WalkerUtils.convert(MCTypeRegistry.ENTITY, entities.getMap(i), \"nbt\", fromVersion, toVersion);\n                }\n            }\n\n            final ListType blocks = data.getList(\"blocks\", ObjectType.MAP);\n            if (blocks != null) {\n                for (int i = 0, len = blocks.size(); i \u003c len; ++i) {\n                    WalkerUtils.convert(MCTypeRegistry.TILE_ENTITY, blocks.getMap(i), \"nbt\", fromVersion, toVersion);\n                }\n            }\n\n            WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, data, \"palette\", fromVersion, toVersion);\n\n            // only return something if we want the root tag to change, but we don't - so ret null. Don't worry about this,\n            // no DataWalker is actually recommended to do this.\n            return null;\n        });\n```\n\nThere are no helper functions for converting a single field inside a list, so the list must be iterated over\nmanually. However, as you can see for the `palette` converter, there is a helper function for converting\nlists of just one data type.\n\n\nWhile DFU Schema and DataWalker are fundamentally different ways of performing data conversion for subtypes,\nthey will both effectively end up doing the same thing. They are both designed to simply run converters\non types contained within another type. However, DataWalker is much faster because it does _not_ depend \non an extremely large type system backend to the traversing for it - it does the traversing itself.\nWithout the DFU type system, the vast majority of performance overhead and complexity has been eliminated\nalready. \n\n### DFU DataFix\n\nDataFix is the overall class responsible for making modifications to data. This is where the actual\n_conversion_ process takes place. Because the DataFix classes can get extremely complicated, I'm only \ngoing to show a simple DataFix class (for V109, 15w33a):\n\n```java\npublic class EntityHealthFix extends DataFix {\n    private static final Set\u003cString\u003e ENTITIES = ...; // unused set of entities with Health\n\n\n    public EntityHealthFix(Schema schema, boolean changesType) {\n        // schema specifies the version\n        super(schema, changesType);\n    }\n\n    public Dynamic\u003c?\u003e fixTag(Dynamic\u003c?\u003e entityRoot) {\n        // while the variable names say float and int, really the type is `Number` - it can be\n        // any Number. But I've named them according to what we _expect_ them to be, as that's\n        // very important to the datafix here.\n        Optional\u003cNumber\u003e healthFloat = entityRoot.get(\"HealF\").asNumber().result();\n        Optional\u003cNumber\u003e healthInt = entityRoot.get(\"Health\").asNumber().result();\n        float newHealth;\n        if (healthFloat.isPresent()) {\n            newHealth = ((Number)healthFloat.get()).floatValue();\n            entityRoot = entityRoot.remove(\"HealF\");\n        } else {\n            if (!healthInt.isPresent()) {\n                return entityRoot;\n            }\n\n            newHealth = ((Number)healthInt.get()).floatValue();\n        }\n\n        return entityRoot.set(\"Health\", entityRoot.createFloat(newHealth));\n    }\n\n    public TypeRewriteRule makeRule() {\n        return this.fixTypeEverywhereTyped(\"EntityHealthFix\", this.getInputSchema().getType(References.ENTITY), (typed) -\u003e {\n            return typed.update(DSL.remainderFinder(), this::fixTag);\n        });\n    }\n}\n```\n\nThe converter is fairly straightforward - update the Health tag to be a float. If `HealF` exists, then use\nthat - else, try to use the `Health` tag. If none exist, do nothing.\n\nThe makeRule() method is there to tell DFU it wants to modify all `ENTITY` types.\n\nSomething you need to note is that Dynamics are Copy-On-Write (they do SHALLOW copies, not DEEP). This is \nwhy you will see lines like this:\n```java\n            entityRoot = entityRoot.remove(\"HealF\");\n```\nYou will see in a moment that DataConverter is _not_ Copy-On-Write. This is something very important\nthat you need to keep in mind if you want to look at both DataConverter's converters and DFU's.\n\n\n### DataConverter\n\nDataConverters are going to the same job of DataFix. Take an input data, do converting, and return \nan output data.\nHere's the converter for the health fix:\n```java\n        // version must be specified to the DataConverter\n        MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter\u003c\u003e(VERSION) {\n            // versions are provided in the convert method. Not used much, but there just in case.\n            @Override\n            public MapType\u003cString\u003e convert(final MapType\u003cString\u003e data, final long sourceVersion, final long toVersion) {\n                final Number healF = data.getNumber(\"HealF\");\n                final Number heal = data.getNumber(\"Health\");\n\n                final float newHealth;\n\n                if (healF != null) {\n                    data.remove(\"HealF\");\n                    newHealth = healF.floatValue();\n                } else {\n                    if (heal == null) {\n                        return null;\n                    }\n\n                    newHealth = heal.floatValue();\n                }\n\n                data.setFloat(\"Health\", newHealth);\n\n                // null once again indicates we have no need to change the root tag. Rarely is this ever needed,\n                // but sometimes it is. See V135's passenger fix - it needs to change root tag because the Riding\n                // entities are swapped with passengers.\n                return null;\n            }\n        });\n```\n\nYou will notice that no Optionals have been used. Null is to indicate when values do not exist (or when\nthe type is not as requested).\n\nThe code does basically the same thing. However, it uses MapType instead of Dynamic for reading and writing to\nthe underlying `CompoundTag`. Why not just write to `CompoundTag` directly? Technically I also need to support\nread/write operations to JSON data (see ADVANCEMENTS type). So the MapType is an abstraction.\n\nPerformance impact is low since operations are not Copy-On-Write and do not go through a type system.\nDataConverters are simple enough that no optimising is really needed, because the performance problem\nof DFU simply doesn't exist: its type system. In fact, the only DataConverter I ever optimised was the \nchunk flatten converter (DataConverterFlattenChunk).\n\nDataConverters tend to stay simple because there is no type system to deal with at all, so all the complexity\ncomes from the logical data changes occurring. This makes debugging them easy. For example, take a look\nat the MinecartSpawner Schema/DataWalker (V99, pre-converters):\n\nDataWalker:\n```java\n        // Yes, two walkers are allowed: but only for the same version. Later versions need to redefine\n        // them all, if they're needed.\n        MCTypeRegistry.ENTITY.addWalker(VERSION, \"MinecartSpawner\", new DataWalkerBlockNames(\"DisplayTile\"));\n        MCTypeRegistry.ENTITY.addWalker(VERSION, \"MinecartSpawner\", MCTypeRegistry.UNTAGGED_SPAWNER::convert);\n```\n\nSchema:\n```java\n        schema.register(map, \"MinecartSpawner\", () -\u003e {\n            return DSL.optionalFields(\"DisplayTile\", References.BLOCK_NAME.in(schema), References.UNTAGGED_SPAWNER.in(schema));\n        });\n```\n\nThey look the same right? Well they are. It turns out, the root tag of MinecartSpawner is also an `UNTAGGED_SPAWNER`.\nWhile this is completely acceptable in DataConverter, because it's just going to run convert(), DFU chokes a bit.\n\nWell what happens if you shove a MinecartSpawner through DFU?\n\nThis.\n\u003cdetails\u003e\n\u003csummary\u003eComplete mess\u003c/summary\u003e\n\nclass_3602 -\u003e EntityHorseSplitFix\n\nclass_1167 -\u003e EntityTransformFix\n\nYup that's right, this stacktrace doesn't even point to any DataFix that even _touches_ Minecarts or \nSpawners. It doesn't even point anywhere near one. So good luck figuring that one out from the stacktrace.\nI figured this out only by curious inspection, and only wanted to see if DFU could even handle it.\n\nImagine this happening to some data you actually care about though. You cannot debug it. \nI remember during 1.16 when Paper was trying to fix massive lag problems caused by errors in DFU.\nIt took basically _5_ or so people to cobble together a solution, and that solution was _total trash_. No \noffense to anyone involved (I was involved), but that's just the best we could've done with DFU. An issue \noccurs, and you just have to pray that one of the few people who understand this system can do something \nabout it.\n\n```text\njava.lang.IllegalArgumentException: Couldn't upcast\n\tat com.mojang.datafixers.TypedOptic.lambda$apply$0(TypedOptic.java:60) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.Optional.orElseThrow(Optional.java:403) ~[?:?]\n\tat com.mojang.datafixers.TypedOptic.apply(TypedOptic.java:59) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.Typed.get(Typed.java:48) ~[datafixerupper-4.0.26.jar:?]\n\tat net.minecraft.class_3602.method_4982(class_3602.java:19) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_1167.method_4984(class_1167.java:30) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Fold.lambda$null$2(Fold.java:48) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Fold.lambda$null$2(Fold.java:48) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$null$3(FunctionType.java:93) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.optics.ListTraversal.lambda$wander$0(ListTraversal.java:19) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$wander$4(FunctionType.java:94) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.lambda$mapRight$1(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Right.map(Either.java:99) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either.mapRight(Either.java:166) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$right$6(FunctionType.java:104) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.FunctionType$Instance.lambda$first$1(FunctionType.java:81) ~[datafixerupper-4.0.26.jar:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat java.util.function.Function.lambda$compose$0(Function.java:68) ~[?:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.functions.Comp.lambda$null$5(Comp.java:69) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.types.Type.capWrite(Type.java:167) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.types.Type.lambda$readAndWrite$9(Type.java:159) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.serialization.DataResult.lambda$flatMap$10(DataResult.java:138) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.util.Either$Left.map(Either.java:38) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.serialization.DataResult.flatMap(DataResult.java:136) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.types.Type.readAndWrite(Type.java:158) ~[datafixerupper-4.0.26.jar:?]\n\tat com.mojang.datafixers.DataFixerUpper.update(DataFixerUpper.java:84) ~[datafixerupper-4.0.26.jar:?]\n\tat net.minecraft.class_2512.method_10693(class_2512.java:466) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3977.method_17907(class_3977.java:37) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3898.method_17979(class_3898.java:863) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3898.method_17256(class_3898.java:520) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1764) ~[?:?]\n\tat net.minecraft.class_1255.method_18859(class_1255.java:144) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3215$class_4212.method_18859(class_3215.java:545) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_1255.method_16075(class_1255.java:118) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3215$class_4212.method_16075(class_3215.java:554) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_3215.method_19492(class_3215.java:280) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_20415(MinecraftServer.java:749) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_16075(MinecraftServer.java:737) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_1255.method_18857(class_1255.java:127) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_16208(MinecraftServer.java:722) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_3774(MinecraftServer.java:505) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_3735(MinecraftServer.java:338) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.class_1132.method_3823(class_1132.java:67) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_29741(MinecraftServer.java:645) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:257) ~[intermediary-fabric-loader-0.11.3-1.16.5.jar:?]\n\tat java.lang.Thread.run(Thread.java:831) [?:?]\n```\n\u003c/details\u003e\n\nTL;DR big stacktrace gives only misleading information.\n\nThis concludes the general technical overview. If you want to contribute, you should first\ntake a look at a variety of DataFix's I have ported over. There you can see how I handled\ncomplicated DataFix's and very basic ones (like simple item/block/entity renames) and how I\nexpect converters to be laid out. You can start at `MCTypeRegistry` - this is where all converters\nand walkers are registered.\n\n\n## Comparison\n\n### Bugs fixed\n- Minecart Spawner's do not fail to convert for pre converter data.\n- Flower pot items convert correctly (there were _several_ problems...)\n- Fix logs like `Unable to resolve BlockEntity for ItemStack` - Mojang did not specify the full\n  Item name -\u003e Block Entity map. I have code that will ensure the map includes everything.\n- Fix incorrect potion conversion from ancient versions (pre converters). Not sure why DFU breaks here...\n- Tamed wolf collar colours are not managled during the Flattening conversion\n- Incorrect handling of modern entity items that have entity NBT contained\n within them (spawn eggs, item frames)\n\n### Known bugs\nThis data converter is new. Of course there are going to be bugs. Please take backups before using, \nand if you find problems you need to open a report with the relevant logs and world data. And then\nthey will actually get fixed, because this system is actually debuggable.\n\nAs time goes on, this converter will become more reliable than DFU since this converter is more easily\ndebugged. So fixing things is actually practically possible.\n\n\n### Performance\nThe new data converter is at minimum 30 times faster than DFU for converting freshly generated 1.7.10 worlds\nto 1.17 (this runs through all data converters, so it's a solid test).\nWhen chunks contain a lot of data (like shulkers with lots of items), the converter can be up to 200 times faster.\n\nThis is fast enough in my testing to completely obsolete the usage of Force Upgrading. I tested force upgrading\nthis world:\n[Realm of Midgard v30](https://www.curseforge.com/minecraft/worlds/seven-hills/files/2580365)\n\nMy SSD is a Samsung 970 EVO 1TB (NVMe). So the Disk I/O should be minimized.\nConversion process broke down like this:\n- ~75% was spent on reading/writing the chunk data (this INCLUDES decompression/compression)\n- ~25% was spent _converting_ the data\n\nSo basically, the vast majority of time is spent on read/write. Why bother force upgrading? \nLiterally a waste of your time with DataConverter.\n\n## Conclusion\nNew converter system makes force upgrading _obsolete_, that's how fast it is. New converter system is new,\nso please do backups before using - or else you put your world data at risk.\n","funding_links":["https://github.com/sponsors/PaperMC","https://opencollective.com/PaperMC"],"categories":["Java"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPaperMC%2FDataConverter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPaperMC%2FDataConverter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPaperMC%2FDataConverter/lists"}