refactor: port default content to java

Preserve the exact built-in factory, material, and remap registrations.
This commit is contained in:
Algent committed 2026-08-31 19:45:20 +02:00
1 parent f9724b9d93
commit 8d4ad03223
6 files changed
+137 -70

No files matched your search

+8
View File
@@ -812,3 +812,11 @@ generated-trait compatibility work. Scala-runtime removal remains a later projec
unchanged; only the actual client rendering remains manual.
- All 177 plain-JVM and all 92 Java 8 Forge dedicated-server tests pass. This inert singleton is not a meaningful
focused performance target; `DefaultContent.scala` is the next medium-risk target.
- Characterized `DefaultContent` against untouched Scala. One plain-JVM case freezes its one-method static and
companion surfaces. Two Forge cases freeze the five microblock factories and IDs, all 103 sorted built-in
materials, their exact implementation types and the complete legacy-name remap table.
- Ported the singleton to a Java facade/companion pair while continuing to use the existing `BlockMicroMaterial$`
overloads and Scala ranges. Registration contents, ordering and the historical meta-0-only `log2`/`leaves2`
overload behavior are unchanged.
- All 178 plain-JVM and all 94 Java 8 Forge dedicated-server tests pass. Pre-init-only registration is not a meaningful
focused performance target; `GrassMicroMaterial.scala` is the next material unit.
+36
View File
@@ -2080,3 +2080,39 @@ use `MissingMicroMaterial$.MODULE$`; static calls retain their original names an
- Java 8 Forge dedicated-server suite: 92 tests, 0 failures, 0 errors.
- Raw `javap` comparison confirms identical callable public names/descriptors and the emitted class list is unchanged.
- Missing-texture icon loading and face rendering require a client and remain on the manual checklist.
## 2026-08-31 — DefaultContent Java port
The built-in microblock registration singleton is now a Java static facade plus Java companion. `MicroblockMod$`
continues to call `DefaultContent$.MODULE$.load()` during pre-init.
### Observable behavior
No known runtime divergence. The same face, hollow, corner and edge classes retain IDs 0 through 3, and the post
class remains registered without a common-class ID. Their five multipart type names and exact singleton factories are
unchanged.
The material registry still receives the same 103 entries, sorts them by name during post-init, and maps every legacy
unlocalized key to the same registry key. Grass still uses `GrassMicroMaterial`, mycelium still uses
`TopMicroMaterial`, and the missing key still maps to `MissingMicroMaterial$.MODULE$`. The Java implementation calls
the existing `BlockMicroMaterial$` overloads with Scala inclusive ranges, preserving the reference's meta coverage.
In particular, the three-argument overload used for `log2` and `leaves2` still registers only metadata zero despite
receiving ranges through one; this port deliberately does not combine a behavior fix with the language conversion.
### ABI and source compatibility
`DefaultContent` retains its sole public static `load()V`; `DefaultContent$` retains `MODULE$` and the matching public
instance method. Both jars emit exactly `DefaultContent.class` and `DefaultContent$.class`. No audited shipping
consumer references either type.
Accepted classfile-only differences are removed Scala signature/marker attributes, a private constructor on the
facade, and a class initializer without Scala's `ACC_PUBLIC` flag. A class initializer is JVM-only and is not a
callable member.
### Validation
- `DefaultContentCharacterizationTest`: 1 plain-JVM test, unchanged from the Scala baseline.
- `DefaultContentFunctionalTest`: 2 Forge tests, unchanged from the Scala baseline.
- Complete plain-JVM suite: 178 tests, 0 failures, 0 errors.
- Java 8 Forge dedicated-server suite: 94 tests, 0 failures, 0 errors.
- Raw `javap` comparison confirms identical callable public names/descriptors and the emitted class list is unchanged.
+16 -10
View File
@@ -12,8 +12,8 @@ what breaks, and what is left. The other documents hold the reasoning.
| `JAVA_MIGRATION_MANUAL_CHECKS.md` | What no automated test can cover, and must be checked by hand in a client |
| `JAVA_MIGRATION_PROFILE.md` | The focused baseline, first measured result, findings, and exact rerun command |
Branch: `algent/java`. Base: `master`. 102 commits including the incremental-version build fix and separate
characterization and port commits for `MissingMicroMaterial`.
Branch: `algent/java`. Base: `master`. 104 commits including the incremental-version build fix and separate
characterization and port commits for `DefaultContent`.
## The one rule that matters
@@ -67,7 +67,7 @@ awk -F'"' '/<testsuite /{t+=$4;f+=$8;e+=$10} END{print "tests="t" failures="f" e
grep -o 'tests="[0-9]*" skipped="[0-9]*" failures="[0-9]*" errors="[0-9]*"' run/server/junit-out/TEST-*.xml
```
Current baseline: **177 plain-JVM tests and 92 Java 8 Forge dedicated-server tests passing.** The ignored local server
Current baseline: **178 plain-JVM tests and 94 Java 8 Forge dedicated-server tests passing.** The ignored local server
EULA is accepted in this checkout.
### ABI diff against the reference
@@ -243,7 +243,8 @@ All eight load-bearing `$class` helpers from the inventory, both registries, and
`TRedstoneTile`, `TTileChangeTile`, `TFluidHandlerTile`, `TIInventoryTile`/`JInventoryTile`, `TileMultipartClient`, and
`TRandomDisplayTickTile` Java-trait ports, plus `MultipartCompatiblity`/`MCPCCompatModule`, `MultipartMod`,
`MultipartEventHandler`, `MicroblockMod`, `MicroblockEventHandler`, and the complete `MicroblockPH`/
`MicroblockCPH`/`MicroblockSPH` packet-handler unit, plus `MultipartSaveLoad` and `MissingMicroMaterial`.
`MicroblockCPH`/`MicroblockSPH` packet-handler unit, plus `MultipartSaveLoad`, `MissingMicroMaterial`, and
`DefaultContent`.
Plus the six marker interfaces: `TSlottedPart`, `IRandomDisplayTick`, `INeighborTileChange`, `TRandomUpdateTick`,
`ISidedHollowConnect`, `IMicroMaterialRender`, plus `MultipartHelper`, `TileCache`, `PacketScheduler` and the `ControlKeyModifer` pair.
@@ -258,7 +259,7 @@ across the port. It is also where the two shim constraints in the gotchas list w
`rayTraceAll`'s index production is now characterized, closing the gap the read-path cleanup left: the index written
into `ExtendedMOP.data` is what `reduceMOP` hands back to every click, activate, harvest and pick block.
112 Java files, 30 Scala files, ~4,871 Scala lines left (non-blank; that is the metric this figure has always used).
114 Java files, 29 Scala files, ~4,816 Scala lines left (non-blank; that is the metric this figure has always used).
## What is left, and in what order
@@ -382,18 +383,23 @@ descriptors, `MODULE$`, `IMicroMaterial`, and the three client-only boundaries.
shape and inert values; one Forge test proves that `DefaultContent` registers the same singleton after client methods
and state are stripped on a dedicated server. The missing-texture render path remains client-manual.
`DefaultContent` is now Java. Its sole static/companion method and both emitted singleton types retain their exact
shape. One plain-JVM test freezes that ABI; two Forge tests freeze all five microblock factories, common IDs, the 103
sorted built-in materials and every legacy remap. The historical `log2`/`leaves2` meta-0-only overload behavior is
explicitly preserved rather than repaired during the port.
**Medium.** The `handler` packages on both sides, `ItemMicroPart`,
`MicroblockPlacement`, `PlacementGrids`, `BlockMicroMaterial`, `ConfigContent`,
`DefaultContent`.
and the remaining material/render units.
**Phase 5 is complete.** There are no Scala files left in `multipart/scalatraits/`. The client pair required the first
narrow generator relaxation: Java-trait parent linearization, explicit field-accessor recognition, and exclusion of
transient runtime caches from generated copying.
Take `microblock/DefaultContent.scala` next. At 55 nonblank lines it is the smallest remaining unit named in the
medium-risk queue. Freeze the exact facade/companion surface and the complete ordered built-in class/material
registration result before changing it; retain the existing remaps and exact `MissingMicroMaterial$.MODULE$`
registration. Keep the characterization and port commits separate.
Take `microblock/GrassMicroMaterial.scala` next. At 56 nonblank lines it is the smallest remaining material unit and
contains both `GrassMicroMaterial` and `TopMicroMaterial`. Freeze constructors, public fields/accessors, inherited
`BlockMicroMaterial` behavior, client-only boundaries and side-dependent UV/render routing. Keep actual face colour,
overlay and texture rendering on the client manual checklist, and keep the characterization and port commits separate.
**Phase 6/7, last.** `Microblock` and the microblock shape hierarchy, `MicroblockGenerator`, `MultipartGenerator`, and
all of `multipart/asm/`. The ASM subsystem should be last; freeze generated-class fixtures before touching it.
@@ -0,0 +1,67 @@
package codechicken.microblock;
import net.minecraft.init.Blocks;
import scala.collection.immutable.Range$;
public final class DefaultContent$ {
public static final DefaultContent$ MODULE$ = new DefaultContent$();
private DefaultContent$() {}
public void load() {
FaceMicroClass$.MODULE$.register(0);
HollowMicroClass$.MODULE$.register(1);
CornerMicroClass$.MODULE$.register(2);
EdgeMicroClass$.MODULE$.register(3);
PostMicroClass$.MODULE$.register();
BlockMicroMaterial$ materials = BlockMicroMaterial$.MODULE$;
materials.createAndRegister(Blocks.stone, 0);
materials.createAndRegister(Blocks.dirt, Range$.MODULE$.inclusive(0, 2));
materials.createAndRegister(Blocks.cobblestone, 0);
materials.createAndRegister(Blocks.planks, Range$.MODULE$.inclusive(0, 5));
materials.createAndRegister(Blocks.log, Range$.MODULE$.inclusive(0, 3));
materials.createAndRegister(Blocks.log2, Range$.MODULE$.inclusive(0, 1), "tile.log2");
materials.createAndRegister(Blocks.leaves, Range$.MODULE$.inclusive(0, 3));
materials.createAndRegister(Blocks.leaves2, Range$.MODULE$.inclusive(0, 1), "tile.leaves2");
materials.createAndRegister(Blocks.sponge, 0);
materials.createAndRegister(Blocks.glass, 0);
materials.createAndRegister(Blocks.lapis_block, 0);
materials.createAndRegister(Blocks.sandstone, Range$.MODULE$.inclusive(0, 2));
materials.createAndRegister(Blocks.wool, Range$.MODULE$.inclusive(0, 15));
materials.createAndRegister(Blocks.gold_block, 0);
materials.createAndRegister(Blocks.iron_block, 0);
materials.createAndRegister(Blocks.brick_block, 0);
materials.createAndRegister(Blocks.bookshelf, 0);
materials.createAndRegister(Blocks.mossy_cobblestone, 0);
materials.createAndRegister(Blocks.obsidian, 0);
materials.createAndRegister(Blocks.diamond_block, 0);
materials.createAndRegister(Blocks.ice, 0);
materials.createAndRegister(Blocks.snow, 0);
materials.createAndRegister(Blocks.clay, 0);
materials.createAndRegister(Blocks.netherrack, 0);
materials.createAndRegister(Blocks.soul_sand, 0);
materials.createAndRegister(Blocks.glowstone, 0);
materials.createAndRegister(Blocks.stonebrick, Range$.MODULE$.inclusive(0, 3));
materials.createAndRegister(Blocks.nether_brick, 0);
materials.createAndRegister(Blocks.end_stone, 0);
materials.createAndRegister(Blocks.emerald_block, 0);
materials.createAndRegister(Blocks.redstone_block, 0);
materials.createAndRegister(Blocks.quartz_block, 0);
materials.createAndRegister(Blocks.stained_hardened_clay, Range$.MODULE$.inclusive(0, 15));
materials.createAndRegister(Blocks.hardened_clay, 0);
materials.createAndRegister(Blocks.coal_block, 0);
materials.createAndRegister(Blocks.packed_ice, 0);
materials.createAndRegister(Blocks.stained_glass, Range$.MODULE$.inclusive(0, 15));
MicroMaterialRegistry.remapName(materials.oldKey(Blocks.grass), materials.materialKey(Blocks.grass));
MicroMaterialRegistry.registerMaterial(new GrassMicroMaterial(), materials.materialKey(Blocks.grass));
MicroMaterialRegistry.remapName(materials.oldKey(Blocks.mycelium), materials.materialKey(Blocks.mycelium));
MicroMaterialRegistry
.registerMaterial(new TopMicroMaterial(Blocks.mycelium, 0), materials.materialKey(Blocks.mycelium));
MicroMaterialRegistry.registerMaterial(MissingMicroMaterial$.MODULE$, MissingMicroMaterial.key());
}
}
@@ -0,0 +1,10 @@
package codechicken.microblock;
public final class DefaultContent {
private DefaultContent() {}
public static void load() {
DefaultContent$.MODULE$.load();
}
}
@@ -1,60 +0,0 @@
package codechicken.microblock
import net.minecraft.init.Blocks._
import BlockMicroMaterial._
import MicroMaterialRegistry._
object DefaultContent {
def load() {
FaceMicroClass.register(0)
HollowMicroClass.register(1)
CornerMicroClass.register(2)
EdgeMicroClass.register(3)
PostMicroClass.register()
createAndRegister(stone)
createAndRegister(dirt, 0 to 2)
createAndRegister(cobblestone)
createAndRegister(planks, 0 to 5)
createAndRegister(log, 0 to 3)
createAndRegister(log2, 0 to 1, "tile.log2")
createAndRegister(leaves, 0 to 3)
createAndRegister(leaves2, 0 to 1, "tile.leaves2")
createAndRegister(sponge)
createAndRegister(glass)
createAndRegister(lapis_block)
createAndRegister(sandstone, 0 to 2)
createAndRegister(wool, 0 to 15)
createAndRegister(gold_block)
createAndRegister(iron_block)
createAndRegister(brick_block)
createAndRegister(bookshelf)
createAndRegister(mossy_cobblestone)
createAndRegister(obsidian)
createAndRegister(diamond_block)
createAndRegister(ice)
createAndRegister(snow)
createAndRegister(clay)
createAndRegister(netherrack)
createAndRegister(soul_sand)
createAndRegister(glowstone)
createAndRegister(stonebrick, 0 to 3)
createAndRegister(nether_brick)
createAndRegister(end_stone)
createAndRegister(emerald_block)
createAndRegister(redstone_block)
createAndRegister(quartz_block)
createAndRegister(stained_hardened_clay, 0 to 15)
createAndRegister(hardened_clay)
createAndRegister(coal_block)
createAndRegister(packed_ice)
createAndRegister(stained_glass, 0 to 15)
MicroMaterialRegistry.remapName(oldKey(grass), materialKey(grass))
registerMaterial(new GrassMicroMaterial, materialKey(grass))
MicroMaterialRegistry.remapName(oldKey(mycelium), materialKey(mycelium))
registerMaterial(new TopMicroMaterial(mycelium), materialKey(mycelium))
registerMaterial(MissingMicroMaterial$.MODULE$, MissingMicroMaterial.key())
}
}