This page documents how MachineType registration works in PrototypeMachinery and the relevant load order constraints.
Chinese original:
Two supported paths:
- Code (Kotlin/Java): build a
MachineTypeand enqueue it viaMachineTypeRegisterer.queue(...) - Scripts (CraftTweaker / ZenScript): register through
mods.prototypemachinery.MachineRegistry
Both paths converge in PreInit and are stored into MachineTypeRegistryImpl.
- Enqueue + processing:
src/main/kotlin/common/registry/MachineTypeRegisterer.kt - Registry implementation:
src/main/kotlin/impl/machine/MachineTypeRegistryImpl.kt - Script bridge & builders:
src/main/kotlin/integration/crafttweaker/zenclass/ZenMachineRegistry.ktsrc/main/kotlin/integration/crafttweaker/zenclass/ZenMachineTypeBuilder.ktsrc/main/kotlin/integration/crafttweaker/CraftTweakerMachineTypeBuilder.kt
-
PreInit:
PrototypeMachinery.preInit(...)callsMachineTypeRegisterer.processQueue(event)- flushes the queued MachineTypes into
MachineTypeRegistryImpl
- flushes the queued MachineTypes into
-
Forge Block Registry Event:
BlockRegistereriteratesMachineTypeRegistryImpl.all()- creates and registers one
MachineBlockper MachineType
- creates and registers one
Therefore: MachineTypes must be registered/enqueued in PreInit (or earlier), otherwise you will miss the block registration stage.
Core usage:
// During mod construction or PreInit
MachineTypeRegisterer.queue(myMachineType)Entry: mods.prototypemachinery.MachineRegistry
Bundled example script:
src/main/resources/assets/prototypemachinery/scripts/examples/machine_registration.zs
Recommended approach is to reference structures by id and resolve lazily:
#loader preinit
import mods.prototypemachinery.MachineRegistry;
val m = MachineRegistry.create("mymod", "my_machine");
m.name("My Machine");
m.structure("example_complex_machine"); // structure id (lazy resolve)
MachineRegistry.register(m);CraftTweakerMachineTypeBuilder.structure(String) resolves from StructureRegistryImpl when MachineType.structure is first accessed.
MachineTypeRegistryImpl.register(...)throwsIllegalArgumentExceptionon duplicate ids.MachineTypeRegisterer.processQueue(...)catches the exception and logs it, instead of crashing the game.
The registry uses concurrent containers (e.g. ConcurrentHashMap) for safe access.
However, it is still recommended to respect the lifecycle:
- register in PreInit
- avoid registering new MachineTypes during runtime unless you fully understand the downstream impact (blocks, rendering, UI, ...)