Conversation
The Sponge Schematic specification stores BlockData as an array of varints, but builder_read_schematic_blocks reads one raw byte per block. Palette indices below 128 encode as a single byte so small schematics load correctly, while anything with a larger palette desynchronises after the first multi-byte index and almost every block comes out wrong. builder_read_schematic now decodes the varints once into big endian integers appended to the file buffer and points sch_blockdata_array at them, reusing the existing TAG_Int_Array code path. Schematics with 128 or fewer palette entries keep the original single byte path and are unaffected. A truncated BlockData array logs a warning and leaves the remaining blocks empty instead of aborting the load.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
BlockDatain a Sponge schematic is an array of varints:builder_read_schematic_blocksreads one raw byte per block instead, in both implementations:GmProject/scripts/builder_read_file/builder_read_file.gmlbindex = buffer_peek(buffer_current, sch_blockdata_array + b, buffer_u8)CppProject/World/Builder.cpppaletteIndex = buffer->data[blockDataArray + bufferPos];A palette index below 128 encodes as a single byte, so schematics with small palettes load correctly and the bug stays invisible. As soon as the palette passes 128 entries, the first multi-byte index desynchronises the stream and nearly every block after it is read from the wrong offset.
Measurements
Spec-conformant schematics decoded with the current reader and with a varint reader:
Change
builder_read_schematicdecodes the varints once into big endian integers appended to the file buffer, pointssch_blockdata_arrayat them and setssch_blockdata_ints, reusing the existingTAG_Int_Arraycode path. The block loop keeps its random access, so neitherbuilder_read_schematic_blocksimplementation had to change and no new instance variable was added.The decode only runs when the palette has more than 128 entries, so every schematic that loads correctly today takes exactly the same path as before. A truncated
BlockDataarray now logs a warning and leaves the remaining blocks empty instead of reading past the array.Verification
CppGenwas run overGmProjectbefore and after and reportsSuccess!; the semantic difference in the generated C++ is confined tobuilder_read_schematic.BUILD.mdis out of reach on my machine, so this has not been exercised through the UI. Loading a large WorldEdit schematic before merging would be worth it.CppProject/Generatedis left untouched and needs a CppGen run to pick this up.🤖 Generated with Claude Code