owengage / fastnbt

Fast serde serializer and deserializer for Minecraft's NBT and Anvil formats
MIT License
186 stars 34 forks source link

Complete <=1.12 block support #67

Open owengage opened 2 years ago

owengage commented 2 years ago

This is a 'super issue' covering all work for pre-flattening blocks.

Feel free to try and knock something off this list!

Blocks in 1.12 and prior are stored with numeric IDs rather than names. For example, blocks with an ID of 3 are dirt blocks. This doesn't fit with the current Chunk and Block in fastanvil. Since 1.12 is no longer receiving updates, we translate the old numeric IDs into their Block equivalents on demand, rather than pollute the current Chunk/Block types with 1.12 logic.

Along with the numeric IDs, there is also 4 extra bits of information called the data value that tell you more about a given block. For example, wooden logs have a numeric ID of 17, and the two smallest bits determine if it is oak, spruce, birch or jungle logs. There is also another wooden log block with ID 162 for the other log types.

Relevant code is in fastanvil/src/java/pre13, in particular the pre13_block_names::modern_block function.

The Minecraft Wiki contains all the necessary information in it's Pre-flattening page.

TODO basics:

TODO Data value extraction:

rjp commented 1 year ago

Working through some of these. Created a macro for the coloured blocks which seems to work (from some testing in the Rust playground), assuming this is ok?

macro_rules! coloured_block {
    ($a:expr, $b:expr) => {
        {
            let col = match $b & 0b1111 {
                0 => "white",
                1 => "orange",
                2 => "magenta",
                3 => "light_blue",
                4 => "yellow",
                5 => "lime",
                6 => "pink",
                7 => "gray",
                8 => "light_gray",
                9 => "cyan",
                10 => "purple",
                11 => "blue",
                12 => "brown",
                13 => "green",
                14 => "red",
                15 => "black",
                _ => unreachable!(),
            };
            Block {
                name: format!("minecraft:{col}_{}", $a),
                encoded: format!("minecraft:{col}_{}|", $a),
                archetype: BlockArchetype::Normal,
            }
        }
    }
}
// ...
        "carpet" => {
            coloured_block!("carpet", data_value)
        }
owengage commented 1 year ago

Great, I've merged the PR you made and ticked off soem of the things in the list. Cheers!