Skip to content

Block state ids greater than 256 are converted to 256 in chunk sections that use the global palette #445

Description

@garboit

Description

If a chunk section has just switched to use the global palette and an additional block with block-state id > 256 is added, it will instead be registered as the block state with id 256 (BlockId { kind: NoteBlock, state: 6 })

Reproduction Steps

Run the following test in base/src/chunk.rs

    #[test]
    fn fill_chunk_section_with_unique_states() {
        let mut section = ChunkSection::default();

        //maximum amount of blocks before the global palette is used
        let max_block_states = (1 << MAX_BITS_PER_BLOCK) - 1;

        //place unique block states
        for i in 0..max_block_states {
            section.set_block_at(0, 0, 0, BlockId::from_vanilla_id(i + 1)).unwrap()
        }

        //the chunk section should still use a local palette.
        assert!(section.blocks.palette().is_some());

        //the next block should cause this chunk to use the global palette

        let highest_block_state = BlockId::from_vanilla_id(257);
        section.set_block_at(0,0,0, highest_block_state);
        assert_eq!(section.block_at(0, 0,0).unwrap(), highest_block_state);
    }

Output:

Left:  BlockId { kind: NoteBlock, state: 6 }
Right: BlockId { kind: NoteBlock, state: 9 }

The reason for this is that when the chunk section switches to the global palette, it still returns the old index:

let index = p.index_or_insert(block);
self.resize_if_needed();
index

An easy fix would be:

let index = p.index_or_insert(block);
self.resize_if_needed();
if self.palette.is_none() {
    block.vanilla_id() as usize
} else {
    index
}

It would probably be good, if the palette returned a slice instead of an index, because then the compiler would have caught this error, but I don't have enough experience with rust to say whether this is really a better approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions