-
Notifications
You must be signed in to change notification settings - Fork 56
Block Set API
Finds every wood type, leaves type or whatever else you define that's installed, from any mod, and lets you register a block for each one.
Say you want a shelf made of every wood in the game. You can't know at compile time which mods the
player has. This detects them at runtime and calls you back once per type, so you register
mymod:oak_shelf, biomesoplenty:maple_shelf and so on, for whatever is actually there. Then
Runtime Resource Packs generates the models and textures for them.
Detection is automatic: it looks at every registered block and guesses sibling ids (maple_log next
to maple_planks), which gets most mods right without special casing.
WoodType and LeavesType come built in. To register a block per wood type:
public static void init() {
BlockSetAPI.addDynamicBlockRegistration(MyMod::registerShelves, WoodType.class);
}
private static void registerShelves(Registrator<Block> event, Collection<WoodType> woodTypes) {
for (WoodType wood : woodTypes) {
ResourceLocation id = MyMod.res(wood.getVariantId("shelf")); // mymod:oak_shelf
Block block = new ShelfBlock(wood.copyProperties());
event.register(id, block);
// register it back onto the type, with a unique key
wood.addChild("mymod:shelf", block);
}
}Important
Always addChild your block back onto the type. That's what makes type swapping and the resource
generation helpers find it later. One child per block or item is enough, not both.
A BlockType is an id plus a bag of children. getVariantId, getBlockOfThis(key),
mainChild(), getReadableName(). WoodType adds planks, log, canBurn(), getColor(),
copyProperties() and conversions to vanilla's own WoodType/Boat.Type.
Once things are registered you can move between types:
Block spruceShelf = BlockSetAPI.changeBlockType(oakShelf, oakType, spruceType);That's also how "this recipe, but in every wood" works, see ResourceSink.addBlockTypeSwapRecipe.
Example: BlockSetRegistryExample
Subclass BlockType and BlockTypeRegistry. The registry looks at a block and says whether it
defines a new type; the type declares its children:
public static class FlowerTypeRegistry extends BlockTypeRegistry<FlowerType> {
protected FlowerTypeRegistry() {
super(FlowerType.class, "flower_type");
}
@Override
public Optional<FlowerType> detectTypeFromBlock(Block block, ResourceLocation blockId) {
if (block instanceof FlowerBlock f) return Optional.of(new FlowerType(f));
return Optional.empty();
}
@Override
public FlowerType getDefaultType() {
return POPPY;
}
public static final FlowerType POPPY = new FlowerType((FlowerBlock) Blocks.POPPY);
}@Override
protected void initializeChildrenBlocks() {
// guesses ids like "double_poppy" next to "poppy"
var doubleFlower = findRelatedEntry("double", BuiltInRegistries.BLOCK);
if (doubleFlower != null) this.addChild("double_flower", doubleFlower);
this.addChild("flower", shortFlower);
}Register the definition on init with BlockSetAPI.registerBlockSetDefinition(new FlowerTypeRegistry()).
For mods detection gets wrong, add a finder by hand. It only applies if that mod is installed, so it's safe to add unconditionally:
WoodTypeRegistry.INSTANCE.addSimpleFinder("some_mod_id", "yellow_wood")
.log("yellow_wood_log")
.planks("yellowish_plank")
.childBlock("stick", "stick_light_yellow")
.build();BlockSetAPI.addBlockTypeRemover(type, id) drops a wrongly detected one.
extra_debug in the common config dumps every detected type to .minecraft/debug/, and
extra_children_debug also lists their children.
BlocksColorAPI is the same idea for the 16 dye colors. It groups colored block families
automatically, modded ones included:
DyeColor color = BlocksColorAPI.getColor(stack.getItem());
Block newBlock = BlocksColorAPI.changeColor(oldState.getBlock(), color);
Item redTerracotta = BlocksColorAPI.getColoredItem("terracotta", DyeColor.RED);Example: BlockColorExample
Basics Platform Helpers Registration Networking Events Configs Config Screen
Resources Runtime Resource Packs Texture Manipulation Resource Helpers Block Set API
Client Custom Models Item Rendering Rendered Textures Post Shaders GUI Toolkit Colors
World Block and Item Interfaces Additional Item Placements Improved Entities Fake Levels World Data Dispenser Behaviors
Utilities Codec Utilities Misc Helpers Commands
Datapacks Villagers Soft Fluids Map Markers Spawn Boxes Global Datapack Folder