Loading of .schem and .limatica files result in wrong schematic with switched block types
etcsebd opened this issue ยท 1 comments
Minecraft version
1.16
Mod version and malilib version
Mod Versions: 1.16.3-0.0.0-dev.20200913.215807 and 1.16.4-0.0.0-dev.20201103.1184101
malilib Version: 1.16.4-0.10.0-dev21+arne.2
Description of the bug
TLDR:
Loading certain, but not all, .schem or .litematic files result in schematics in which block types are switched around.
For example blocks that should be air are cobblestone while blocks that should be cobblestone are air. But no blocks that where
not defined in the BlockStatePalette appeared.
Long description:
My program (Minecraft Map Maker) is able to transform pictures into either .schem or .litematic schematics to be imported into Minecraft. A big picture is turned into multiple schematics to reduce server load while pasting them into the world.
I got a bug report that certain, but not all, schematics produced by this program are loaded wrongly into Minecraft.
This was repeatable. A certain picture would produce multiple schematics, of which some where loaded wrongly while the rest worked without problems. This happened every time that picture was processed. It made no difference which output format the user choose.
For example, if the .litematic file describing the left corner of the picture would be loaded wrongly, the .schem file describing the same part of the picture would be loaded wrongly too. If the .litematic file of the right corner was loaded correctly, the .schem file was loaded correctly too.
A wrongly loaded schematic was marked by switched around block types.
For example, if the schematic was made out of mostly air, a line of cobblestone, one line of coal, and one line of snow, the air would become cobblestone, the cobblestone air, the coal would be snow and the snow would be coal. There were no blocks included that were not defined in the BlockStatePalette. This switch was total, every block of one type would become the other type and the other way around.
Opening the schematic did not show any abnormalities. The BlockStatePalette and the Block States matched the expected schematic.
When loading the same .schem file with WorldEdit, it did load the expected schematic.
-> The schematics behave as if Litematica is switching the order of the BlockStatePalette around while loading it. This would explain the switching of all blocks from one type to another.
Example Files:
Because i can not add the schematics directly to this bug report, not even as .zip file, i will add two Dropbox links that point to two schematics, one .schem, one .litematic, both describing the same schematic, showing this behavior.
https://www.dropbox.com/s/4yr648ustnz1axm/BuggedSchematic.litematic?dl=0
https://www.dropbox.com/s/olrcl4o9tq440mt/BuggedSchematic.schem?dl=0
I hope this was helpful and i wish you happy hunting.
Turidus
This is caused by the discrepancy that Litematica currently always allocates minecraft:air
as ID 0 in the palette (even if air is not present in the schematic, I believe), whereas your program does not.
I might change this in future versions, as I do consider it a minor flaw. It was (at least partially) implemented like this to avoid the need to iterate through and initialize the backing data array to the air ID. This would especially be an issue when converting between schematic formats, especially in the case of converting from a multi-region schematic into a single region schematic, in which case the entire volume of the destination schematic will not get set to a specific block state, only the parts where the sub-regions of the source schematic are. But this conversion stuff only really applies to the 1.12.2 version atm, the other versions don't have that conversion code yet (at least not the same more recent code). For the older versions it was just an early implementation decision (vanilla also does or at least did that), but stemming from the same issue, that when you allocate an int or long array in Java, it gets initialized as 0, and when saving a schematic only non-air blocks are actually set, so the initialization value should generally represent air.