as seen in pmmp/BedrockBlockUpgradeSchema@ebd768e5b2, this enables use of newFlattenedName in more places (by allowing the flattened values to be transformed before building the new ID), as well as reducing the number of remappedStates in general by compacting stuff which was partially transformed like color silver -> light_gray.
Prior to this commit, upgrade schemas would be applied to blockstates with the same version, as there wasn't any way to know if they should be applied or not given Mojang's tendency to forget to bump the version.
However, it occurred to me that we only need to do this if there are multiple schemas present for the same version ID, which is rarely the case.
This allows skipping costly logic for blockstates on the newest version (the common case), reducing the time taken to process the blockstate for upgrading by over 30%.
Overall, this translates into less than 10% real performance improvement for chunk loading, but it's still a worthwhile improvement.
this came up during 1.20.50 testing, where minecraft:stone[stone_type=stone] continues to have an ID minecraft:stone without the stone_type property.
This could have appeared in other ways, such as with an invalid legacy blockstate.
this significantly reduces the size of schemas when state remaps are used (see pmmp/BedrockBlockUpgradeSchema@85b83b360e).
in addition, this will likely offer a substantial performance and memory saving when walls get flattened, which will eventually happen.
since PHP emits empty JSON objects as arrays, this makes it pretty annoying to work with the schemas in other languages. However, nullability is something most languages understand pretty easily.
This should continue to support old schemas.
the old impl prevented registering more than one meta -> state mapping since the legacy numeric ID map would throw an exception if attempting to map the same ID more than once.
this reduces the footprint of RuntimeBlockMapping by a further 1 MB, as well as simplifying various parts of the code, and solidifying the immutability guarantee of BlockStateData.
this spectactularly stupid bug could also have been addressed using a [^\/] in place of the . in the pattern, but I thought it made sense to make it impossible for this to happen again by making sure the regex only sees the file name.
fixes#5129
This commit completely revamps the way that blocks are represented in memory at runtime.
Instead of being represented by legacy Mojang block IDs and metadata, which are dated, limited and unchangeable, we now use custom PM block IDs, which are generated from VanillaBlocks.
This means we have full control of how they are assigned, which opens the doors to finally addressing inconsistencies like glazed terracotta, stripped logs handling, etc.
To represent state, BlockDataReader and BlockDataWriter have been introduced, and are used by blocks with state information to pack said information into a binary form that can be stored on a chunk at runtime.
Conceptually it's pretty similar to legacy metadata, but the actual format shares no resemblance whatsoever to legacy metadata, and is fully controlled by PM.
This means that the 'state data' may change in serialization format at any time, so it should **NOT** be stored on disk or in a config.
In the future, this will be improved using more auto-generated code and attributes, instead of hand-baked decodeState() and encodeState(). For now, this opens the gateway to a significant expansion of features.
It's not ideal, but it's a big step forwards.