Stable Values
Use stable Nows value objects from mc/shared-main before crossing into native Minecraft APIs.
Some APIs may still change or behave unevenly because they do not have enough real-world use cases and test coverage yet.
Stable Values
Stable values are small Java objects that describe Minecraft concepts without tying your mod code to one native class name. Use them for reusable setup and adapter API inputs.
Identifiers With McId
Use McId when you want a namespace/path value instead of passing raw strings through your code.
McId machineId = McId.parse("my_mod:machine");
registries.registerItem(machineId);
Keep raw strings for short one-off calls. Use McId when ids are stored, passed around or generated.
List<McId> generatedItems = List.of(
McId.parse("my_mod:copper_gear"),
McId.parse("my_mod:steel_gear"));
Positions, Vectors And Directions
McBlockPos, McVec3 and McDirection are for callbacks and stable logic that should not care whether the native version uses BlockPos, Vec3, Direction or renamed variants.
void rememberClick(McBlockPos pos, McDirection face) {
lastClicked = pos;
lastFace = face;
}
Use native Minecraft position classes when you are directly mutating the world, querying block states or calling vanilla APIs. Use stable values when you are storing configuration, dispatching callbacks or passing data into generated code.
Snapshots In Events
McWorldSnapshot, McEntitySnapshot and the event context records are intentionally read-only. They let stable callbacks inspect state without holding native game objects beyond the tick where they were created.
MinecraftApi.events(context).stableLevelTick(level -> {
McWorldSnapshot world = level.world();
if (!world.clientSide()) {
LOGGER.debug("Ticking {}", world.dimensionId());
}
});
If your listener must place blocks, damage entities or open menus, use the native event overload or a version-specific code path.
Item Stacks
Use ItemStackSpec when all you need is an id and count.
ItemStack stack = registries.itemStack(ItemStackSpec.of("minecraft:stone", 2));
Use McItemStack when the stack should travel through stable APIs with optional NBT data.
McItemStack prize = McItemStack.of("my_mod:token", 4);
ItemStack nativePrize = registries.itemStack(prize);
If you are outside RegistryApi and must hand a stable stack to native code, use NativeItemStackBridge as a narrow conversion point.
Results And Small Enums
McInteractionResult, PackTarget, SlotRole, SlotRule, ProgressDirection, EquipmentSlot, ItemRarity, BlockMaterial, BlockSound, BlockRenderType, BlockShapeSpec and MapColor exist to describe intent. They are not meant to mirror every Minecraft enum.
BlockSpec.builder("my_mod:glass_pipe")
.material(BlockMaterial.GLASS)
.sound(BlockSound.GLASS)
.renderType(BlockRenderType.CUTOUT)
.noOcclusion()
.build();
When an enum does not describe what you need, that is a signal to use native Minecraft code for that feature.