From fd29e0a73782b07feaf63c4e4e4d1fea07482907 Mon Sep 17 00:00:00 2001 From: Algent Date: Fri, 4 Sep 2026 22:47:31 +0200 Subject: [PATCH] fix: preserve microblock state dispatch --- JAVA_MIGRATION_HANDOFF.md | 2 +- docs/migration/HISTORY.md | 11 ++ .../codechicken/microblock/Microblock.java | 30 ++-- .../MicroblockCharacterizationTest.java | 130 +++++++++++++++++- 4 files changed, 155 insertions(+), 18 deletions(-) diff --git a/JAVA_MIGRATION_HANDOFF.md b/JAVA_MIGRATION_HANDOFF.md index fe45d49..21a5faf 100644 --- a/JAVA_MIGRATION_HANDOFF.md +++ b/JAVA_MIGRATION_HANDOFF.md @@ -16,7 +16,7 @@ migration checkout; `codex/tile-compatibility-fixes` was deleted after its fixes ## Current state and next target -**523 plain-JVM tests and 237 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **224 Java +**526 plain-JVM tests and 237 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **224 Java files and 9 Scala files / 747 nonblank Scala lines**. The packaged inventory has 443 classes. Review follow-up: restored packet-scheduler callback mutation behavior with the original Scala hash-map traversal, diff --git a/docs/migration/HISTORY.md b/docs/migration/HISTORY.md index 3d0ffbd..269893c 100644 --- a/docs/migration/HISTORY.md +++ b/docs/migration/HISTORY.md @@ -1697,3 +1697,14 @@ differences belong in the [divergence ledger](../../JAVA_MIGRATION_DIVERGENCES.m This fixes an extension-contract regression, without claiming a demonstrated current-pack gameplay failure. Evidence is under ignored `run/conversion-review/`; migration-plan changes remain deferred until the review fixes are complete. + +### 2026-09-04 — Microblock state accessor compatibility + +- Restored virtual shape/material getters and setters for geometry, material lookup, drops, pick-block, NBT and + description/incremental packets. The backing fields, JVM signatures and serialized formats remain unchanged. +- Three new regression cases compiled against the original Scala jar pass there, fail on the unfixed Java port + and pass unchanged after the fix. The test material explicitly implements the original Scala interface defaults + and uses the retained registry companion so the same test source compiles against both versions. +- Build/style checks, 526 JVM tests and 237 Java 8 Forge tests pass. ProjectRed extends `Microblock`, and consumers + use its shape/material accessors, but no supplied consumer overriding those accessors was found. Evidence is + under ignored `run/conversion-review/`; no migration-plan changes were made. diff --git a/src/main/scala/codechicken/microblock/Microblock.java b/src/main/scala/codechicken/microblock/Microblock.java index d037f01..fe7c17c 100644 --- a/src/main/scala/codechicken/microblock/Microblock.java +++ b/src/main/scala/codechicken/microblock/Microblock.java @@ -81,23 +81,23 @@ public abstract class Microblock extends TMultiPart implements TCuboidPart { } public int getSize() { - return shape >> 4; + return shape() >> 4; } public int getShape() { - return shape & 0xF; + return shape() & 0xF; } public void setShape(int size, int slot) { - shape = (byte) (size << 4 | slot); + shape_$eq((byte) (size << 4 | slot)); } public int getMaterial() { - return material; + return material(); } public MicroMaterialRegistry.IMicroMaterial getIMaterial() { - return MicroMaterialRegistry.getMaterial(material); + return MicroMaterialRegistry.getMaterial(material()); } public abstract int itemClassID(); @@ -114,7 +114,7 @@ public abstract class Microblock extends TMultiPart implements TCuboidPart { ItemMicroPart.create( amount, size | itemClassID() << 8, - MicroMaterialRegistry.materialName(material))); + MicroMaterialRegistry.materialName(material()))); } } return items; @@ -126,7 +126,7 @@ public abstract class Microblock extends TMultiPart implements TCuboidPart { for (int itemSize = 4; itemSize > 0; itemSize /= 2) { if (size % itemSize == 0 && size / itemSize >= 1) { return ItemMicroPart - .create(itemSize | itemClassID() << 8, MicroMaterialRegistry.materialName(material)); + .create(itemSize | itemClassID() << 8, MicroMaterialRegistry.materialName(material())); } } return null; @@ -134,17 +134,17 @@ public abstract class Microblock extends TMultiPart implements TCuboidPart { @Override public void writeDesc(MCDataOutput packet) { - MicroMaterialRegistry.writeMaterialID(packet, material); - packet.writeByte(shape); + MicroMaterialRegistry.writeMaterialID(packet, material()); + packet.writeByte(shape()); } @Override public void readDesc(MCDataInput packet) { - shape = packet.readByte(); + shape_$eq(packet.readByte()); } public void sendShapeUpdate() { - getWriteStream().writeByte(shape); + getWriteStream().writeByte(shape()); } @Override @@ -155,14 +155,14 @@ public abstract class Microblock extends TMultiPart implements TCuboidPart { @Override public void save(NBTTagCompound tag) { - tag.setByte("shape", shape); - tag.setString("material", MicroMaterialRegistry.materialName(material)); + tag.setByte("shape", shape()); + tag.setString("material", MicroMaterialRegistry.materialName(material())); } @Override public void load(NBTTagCompound tag) { - shape = tag.getByte("shape"); - material = MicroMaterialRegistry.materialID(tag.getString("material")); + shape_$eq(tag.getByte("shape")); + material_$eq(MicroMaterialRegistry.materialID(tag.getString("material"))); } public boolean isTransparent() { diff --git a/src/test/java/codechicken/microblock/MicroblockCharacterizationTest.java b/src/test/java/codechicken/microblock/MicroblockCharacterizationTest.java index 31a8dc5..2b68b84 100644 --- a/src/test/java/codechicken/microblock/MicroblockCharacterizationTest.java +++ b/src/test/java/codechicken/microblock/MicroblockCharacterizationTest.java @@ -106,7 +106,7 @@ class MicroblockCharacterizationTest { if (MicroMaterialRegistry.getMaterial(MATERIAL_NAME) == null) { MicroMaterialRegistry.registerMaterial(MATERIAL, MATERIAL_NAME); } - MicroMaterialRegistry.setupIDMap(); + MicroMaterialRegistry$.MODULE$.setupIDMap(); materialId = MicroMaterialRegistry.materialID(MATERIAL_NAME); microClass = allocateInstance(TestMicroClass.class); } @@ -247,6 +247,85 @@ class MicroblockCharacterizationTest { assertSame(loaded, tile.changedPart); } + @Test + void overriddenStateDrivesGeometryMaterialAndItems() { + AccessorMicroblock part = new AccessorMicroblock(); + assertEquals(5, part.getSize()); + assertEquals(2, part.getShape()); + assertEquals(materialId, part.getMaterial()); + assertSame(MATERIAL, part.getIMaterial()); + assertEquals(2.5f, part.getStrength(null, null)); + assertTrue(part.isTransparent()); + assertEquals(11, part.getLightValue()); + assertEquals(2f, part.explosionResistance(null)); + + part.setShape(7, 3); + assertEquals((byte) 0x73, part.shape()); + assertEquals(1, part.shapeWrites); + ItemMicroPart previous = MicroblockProxy.itemMicro(); + ItemMicroPart item = new ItemMicroPart(); + MicroblockProxy.itemMicro_$eq(item); + try { + List drops = part.getDrops(); + assertEquals(3, drops.size()); + assertItem(drops.get(0), item, 1, 7 << 8 | 4); + assertItem(drops.get(1), item, 1, 7 << 8 | 2); + assertItem(drops.get(2), item, 1, 7 << 8 | 1); + part.setShape(6, 1); + assertItem(part.pickItem(null), item, 1, 7 << 8 | 2); + } finally { + MicroblockProxy.itemMicro_$eq(previous); + } + part.setShape(8, 15); + assertEquals(-8, part.getSize()); + assertEquals(15, part.getShape()); + } + + @Test + void overriddenStateIsWrittenToDescriptionsNbtAndUpdates() { + AccessorMicroblock part = new AccessorMicroblock(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + part.writeDesc(output(bytes)); + assertArrayEquals(new byte[] { (byte) materialId, (byte) 0x52 }, bytes.toByteArray()); + NBTTagCompound tag = new NBTTagCompound(); + part.save(tag); + assertEquals((byte) 0x52, tag.getByte("shape")); + assertEquals(MATERIAL_NAME, tag.getString("material")); + + bytes.reset(); + RecordingTile tile = new RecordingTile(); + tile.output = output(bytes); + part.bind(tile); + part.sendShapeUpdate(); + assertArrayEquals(new byte[] { (byte) 0x52 }, bytes.toByteArray()); + } + + @Test + void overriddenSettersReceiveLoadedStateAndNetworkUpdates() { + AccessorMicroblock part = new AccessorMicroblock(); + NBTTagCompound tag = new NBTTagCompound(); + tag.setByte("shape", (byte) 0x31); + tag.setString("material", MissingMicroMaterial.key()); + part.load(tag); + assertEquals((byte) 0x31, part.shape()); + assertEquals(MicroMaterialRegistry.getMissingId(), part.material()); + assertEquals(1, part.shapeWrites); + assertEquals(1, part.materialWrites); + + part.readDesc(input((byte) 0x42)); + assertEquals((byte) 0x42, part.shape()); + assertEquals(2, part.shapeWrites); + RecordingTile tile = new RecordingTile(); + part.bind(tile); + part.read(input((byte) 0x63)); + assertEquals((byte) 0x63, part.shape()); + assertEquals(3, part.shapeWrites); + assertEquals(1, part.materialWrites); + assertEquals(1, tile.renderMarks); + assertEquals(1, tile.partChanges); + assertSame(part, tile.changedPart); + } + private static void assertTrait(Class type, Class[] interfaces, Set methods) { assertTrue(type.isInterface()); assertArrayEquals(interfaces, type.getInterfaces()); @@ -315,7 +394,7 @@ class MicroblockCharacterizationTest { return (T) unsafe.getMethod("allocateInstance", Class.class).invoke(field.get(null), type); } - private static final class TestMicroblock extends Microblock { + private static class TestMicroblock extends Microblock { private static final Cuboid6 BOUNDS = new Cuboid6(0, 0, 0, 0.5, 0.75, 1); @@ -339,6 +418,40 @@ class MicroblockCharacterizationTest { } } + private static final class AccessorMicroblock extends TestMicroblock { + + private int overriddenMaterial = materialId; + private byte overriddenShape = 0x52; + private int materialWrites; + private int shapeWrites; + + private AccessorMicroblock() { + super(MicroMaterialRegistry.getMissingId()); + } + + @Override + public int material() { + return overriddenMaterial; + } + + @Override + public void material_$eq(int value) { + materialWrites++; + overriddenMaterial = value; + } + + @Override + public byte shape() { + return overriddenShape; + } + + @Override + public void shape_$eq(byte value) { + shapeWrites++; + overriddenShape = value; + } + } + private static final class TestMicroClass extends MicroblockClass { @Override @@ -388,6 +501,19 @@ class MicroblockCharacterizationTest { private static final class TestMaterial implements IMicroMaterial { + @Override + public boolean isSolid() { + return !isTransparent(); + } + + @Override + public void loadIcons() {} + + @Override + public boolean canRenderInPass(int pass) { + return pass == 0; + } + @Override public IIcon getBreakingIcon(int side) { return null;