mojira.dev

50ap5ud5

Assigned

No issues.

Reported

MC-215960 Deleting then Restoring a Custom Dimension Removes NBT Data used to register the dimension Awaiting Response

Comments

An update on this issue, the root cause of the issue been narrowed down to one of the methods in UnboundedMapCodec in Mojang's DataFixerUpper library being too aggresive with handling erroring data entries.

There has been a working Pull Request solution made on their Github, if anyone is interested. It's a 2-3 line change.

I've tested the pull request and can confirm it works.

However, it is only a solution for new world saves created after the solution is pulled. To allow older worlds already affected by this bug to retain the Nether and End dimension, a seperate solution will be needed to reinject the removed dimension entries back into the SaveFormat.

Linked PR: https://github.com/Mojang/DataFixerUpper/pull/55

I've taken a closer look at this issue. Here are my findings into it:

How the Nether and End Dimensions are Removed

The removal of the nether and end relate to the:

  • Dimension Registration Order

  • Logic used to remove erroring dimensions in SaveFormat#getServerLifecyclePair

    • (These are MCP names, let me know if you need the mojmap name).

Dimension Registration Order

When the Dynamic<T> dynamic = nbt.get("WorldGenSettings").orElseEmptyMap();  in SaveFormat#getServerLifecyclePair is being constructed, the order of dimension registration is as follows:

  1. Overworld

  2. Datapack loaded custom dimensions

  3. Nether

  4. End

Logic used to remove erroring Dimensions

TelepathicGrunt is correct that the DimensionGeneratorSettings CODEC (GeneratorOptions.CODEC in Yarn names) will return missing dimensions.

However, that is only half of the story. The Dynamic<T> that is parsed into the DimensionGeneratorSettings CODEC originates from SaveFormat#getServerLifecyclePair.

When the custom dimension is removed, DimensionGeneratorSettings.CODEC fails to fully parse the Dynamic<T>, so the DataResult<DimensionGeneratorSettings> only return the Either#Right part of the result, which only includes the Overworld.

The crucial aspect is the Pair that is returned to the method uses the DataResult#resultOrPartial method, whose PartialResult which removes ALL objects AFTER the erroring objects, in addition to the erroring object.

i.e. The data result removes the erroring custom dimension, the Nether and the End, leaving only the Overworld.

 

When these two factors are put into effect, the subsequent ServerWorldInfo, which defines the settings for the World, will use the incorrect data. This is why the Nether and End dimensions become "missing".

Why the Nether and End Dimensions do not show after reinstating the missing datapack

When the world is loaded after the datapack is reinstated, by this time the Dynamic<T> no longer includes the nether and end in its list of dimensions. Hence, only the Overworld is parsed to the DataResult<DimensionGeneratorSettings> alongside the custom dimension.