Skip to content

Instantly share code, notes, and snippets.

@mojontwins
Last active October 19, 2022 11:29
Show Gist options
  • Save mojontwins/4e2c82f1950a31ec15beb8ed518a407a to your computer and use it in GitHub Desktop.
Save mojontwins/4e2c82f1950a31ec15beb8ed518a407a to your computer and use it in GitHub Desktop.
256 Block IDs in Minecraft pre-release

256 block IDs

The Block.blocksList array is created with 256 elements. The problem is that block IDs are stored in a signed byte array, so when values are popped several arrays try to be accessed with a negative index if you stored a block ID > 127. You can overcome this limitation quite easily with a few fixes here and there and use the full 0-255 range and have up to 256 different blocks without needing more memory or creating incompatibilites with existing saves.

The trick is that you can easily convert signed byte values to unsigned ints ranging 0-255 using casting and a bitwise AND. Type casting a negative byte to an int extends bit 7 (the sign). After that, a & 0xFF will clear all bits but those in the least significant byte, so you get your 0-255 value back!

You have to change these bits of code:

Chunk.java

In getBlockId cast to int and & 0xff this way:

	public int getBlockID(int x, int y, int z) {
		return (int) this.blocks[x << 11 | z << 7 | y] & 0xff;
	}

In setBlockIDWithMetadata, the converted byte value (signed) is used to access Block.lightOpacity. Change that to use the original ID:

	public boolean setBlockIDWithMetadata(int x, int y, int z, int id, int metadata) {
		[...]
		if(Block.lightOpacity[id] != 0) {
			[...]

Same for setBlockID:

	public boolean setBlockID(int x, int y, int z, int id) {
		[...]
		if(Block.lightOpacity[id] != 0) {
			[...]

In generateHeightMap the array is also read directly:

	public void generateHeightMap() {
		[...]
		for(int i5 = i2 << 11 | i3 << 7; i4 > 0 && Block.lightOpacity[(int) this.blocks[i5 + i4 - 1] & 0xff] == 0; --i4) {

Also in relightBlock:

	private void relightBlock(int x, int y, int z) {
		[...]
		for(int i6 = x << 11 | z << 7; i5 > 0 && Block.lightOpacity[(int) this.blocks[i6 + i5 - 1] & 0xff] == 0; --i5) {

World.java

There's one instance where the chunk's block array is accessed directly which should be fixed as well: when ticking blocks.

	protected void updateBlocksAndPlayCaveSounds() {
		[...]
		for(int i = 0; i < 80; ++i) {
			[...]
			blockID = (int) chunk.blocks[x << 11 | z << 7 | y] & 0xff;

And that seems to be it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment