Registries
Besides vanilla’s registries, HBM keeps registries of its own content kinds. Register into them from your declare()
(which runs after HBM’s) unless a section says otherwise. Use your namespace in every name you add, so two addons
cannot collide. A duplicate name is a start-up error, never a silent replacement.
Materials
Section titled “Materials”public static synchronized NTMMaterial register(int id, String name)name is the saved name (Mats.write/read) and must be unique. id is the runtime number packets carry
(Mats.matById); it must be unique too, but is never saved. Set colours, smelting and shapes on the returned material:
NTMMaterial method |
Sets |
|---|---|
colors(int solidLight, int solidDark, int molten) |
the material’s colours |
smelting(SmeltingBehavior behavior) |
how it melts (for example SMELTABLE) |
conv(NTMMaterial mat, int in, int out) |
a conversion into another material |
displayName(String displayName) |
the display name |
setAutogen(MaterialShapes... shapes) |
shapes whose items are generated |
STAINLESS = Mats.register(EX + 1, "stainless").colors(0xD8D8D8, 0x474747, 0x4A4A4A) .smelting(SmeltingBehavior.SMELTABLE).displayName("Stainless Steel");STAINLESS.setAutogen(MaterialShapes.PLATE, MaterialShapes.WELDEDPLATE, MaterialShapes.CASTPLATE);A material from Mats.register also shows in KubeJS’s HBM.materials(). Crucible smelting of items is the recipe table
hbm:material_distribution.
Bullets and tracers
Section titled “Bullets and tracers”public static synchronized BulletConfig register(Identifier id, BulletConfig config)Register your rounds under your own namespace (ntmspace:worldwar). A duplicate id throws.
Tracers are client side, in com.hbm.client.render.projectile.TracerRegistry:
| Method | Does |
|---|---|
register(BulletTracer tracer, Identifier... ids) |
one tracer for several rounds |
registerBeam(BeamTracer tracer, Identifier... ids) |
one beam for several rounds |
setBulletRenderer(Identifier id, BulletTracer renderer) / setBeamRenderer(Identifier id, BeamTracer renderer) |
one round |
model(Identifier model, Identifier texture, String part, float scale, Consumer<PoseStack> transform) |
a tracer from one OBJ part |
flare(float red, float green, float blue) |
a flare tracer |
ribbon(int dark, int light, boolean fullbright) |
a ribbon tracer |
laser(int r, int g, int b) |
a laser beam |
HBM’s client tracer audit checks only HBM’s own rounds; give yours a tracer yourself.
Hazards
Section titled “Hazards”public static <T extends IHazardType> T registerType(Identifier id, T type)
// com.hbm.hazard.HazardSystempublic static void register(TagKey<Item> tag, HazardData data)public static void register(Item item, HazardData data)public static void register(Block block, HazardData data)registerType names a hazard type so recipes, commands and data can find it; it returns the type, to initialise the
constant that holds it.
public static final IHazardType NEUTRON = HazardRegistry.registerType(Ids.of(NtmSpace.MOD_ID, "neutron"), new HazardTypeNeutron());Which items carry which hazards is also the data map hbm:hazards (items), which datapacks and addons can patch.
Fluid traits
Section titled “Fluid traits”FluidProperties.registerTrait and registerFlag add trait types to the fluid_property format. See
Fluids.
Record registries
Section titled “Record registries”Content kinds that 1.7 kept in a closed enum or static table are registries of records in HBM, most of them backed by
com.hbm.api.registry.NamedRegistry<T>. HBM’s own entries keep their 1.7 names; iteration order is registration order,
so HBM’s entries come first, in 1.7 order. Register at mod construction (or from a class initialiser that runs then), on
both sides.
| Kind | Register |
|---|---|
| RBMK column types | RBMKColumnType.register(String name, Identifier sheet, int offset, @Nullable Function<RBMKColumnType, RBMKColumn> column) |
| FEL wavelengths | ItemFELCrystal.EnumWavelengths.register(String key, double strength, String name, String wavelengthRange, int renderedBeamColor, int guiColor, ChatFormatting textColor, BeamEffect beamEffect) |
| Pedestal conditions | PedestalRecipes.PedestalExtraCondition.register(String name, @Nullable Icon icon, Test test) |
| ICF fuels | ItemICFPellet.EnumICFFuel.register(String name, int color, double react, double depl, double laser) |
| Armour hazard classes | ArmorRegistry.HazardClass.register(String name, String lang) |
| Satellite types | SatelliteType.register(String name, Supplier<? extends Satellite> factory, MapCodec<? extends Satellite> codec, @Nullable String cargo) |
| Bomber payloads | BomberPayload.register(String name, Factory factory, Drop drop) |
| Bedrock ore types | BedrockOreType.register(BedrockOreType type); the code-made chain rows use BedrockOreChainRecipes.addChainType/removeChainType |
| Custom missile warheads and fuels | ItemCustomMissilePart.WarheadType.register(...), ItemCustomMissilePart.FuelType.register(...) |
| Siren tracks | ItemCassette.TrackType.register(String name, String title, @Nullable String sound, SoundType type, int color, int volume) |
| Tool and weapon abilities | IToolAreaAbility.REGISTRY, IToolHarvestAbility.REGISTRY, IWeaponAbility.REGISTRY |
public static final EnumWavelengths XRAY = EnumWavelengths.register(NS + ":xray", 4D, "wavelengths.name.xray", "wavelengths.waveRange.xray", 0xF8E6A7, 0xF8E6A7, ChatFormatting.GOLD, entity -> {});public static final ItemCassette.TrackType TRACK_DISEMBODIED = ItemCassette.TrackType.register( NS + ":DISEMBODIED", "Ducc", NS + ":alarm.ducc", ItemCassette.SoundType.LOOP, 0xb3a8c1, 50);NamedRegistry<T> itself: register(value), get(name), name(value), contains(name), values().
Custom item renderers
Section titled “Custom item renderers”// com.hbm.client.render.item.CustomItemRenderers (client)public static void register(String name, Supplier<CustomItemRenderer> factory)
// com.hbm.client.render.MachineItemNamespaces (client)public static synchronized void add(String namespace)CustomItemRenderers.register adds a renderer an item definition’s hbm:custom_item model can name (a ported 1.7
IItemRenderer). Name yours <ns>:<name> and register from your client set-up, before the first resource load.
CustomItemRenderers.register("ntmspace:plushie", RenderSpacePlushie.Item::new);On 26.1 an item definition of any namespace can name hbm:machine_obj. Below 26.1 each loader needs a per-item
“render this yourself” callback, so call MachineItemNamespaces.add(ns) to bind your namespace’s OBJ machine items to
HBM’s item renderer (NeoForge: from the mod constructor; Fabric: any time during client initialisation). Forge 1.20.1
needs no call.
Survey scanner findings
Section titled “Survey scanner findings”public static void addFinding(int index, Finding finding)public record Finding(Predicate<Block> matches, String message, ChatFormatting colour) {}Inserts a finding at index of the report order (0 = first, findings().size() = last). A block counts for the first
finding it matches.
Other extension points
Section titled “Other extension points”Smaller tables HBM keeps in code, each with a public method to add to it. Call them at mod construction (from
declare()) unless the row says otherwise.
| Add | Call |
|---|---|
| Shape items for your material (plates, wires, …) | ModAutogenItems.registerAutogen(DeferredRegister.Items items, NTMMaterial mat, MaterialShapes... shapes), after mat.setAutogen(...) with the same shapes; items are <ns>:<shape base>_<material> |
| A missile item a launch pad can fire | TileEntityLaunchPadBase.registerLaunchable(Item item, MissileFactory factory); MissileFactory.create(level, x, y, z, targetX, targetZ) returns the missile entity. An earlier registration wins over HBM’s default, so this can also change what an HBM missile item launches |
| A tool that counts as a screwdriver, wrench, … | IToolable.ToolType.<TYPE>.register(Supplier<? extends Item> item) (SCREWDRIVER, HAND_DRILL, DEFUSER, WRENCH, TORCH, BOLT) |
| A gun modifier | XWeaponModManager.register(String name, M mod), name <ns>:<path>; saved by name; bind it to its item and guns with a WeaponModDefinition |
| Armour that protects against a hazard class | ArmorRegistry.registerHazard(Item item, HazardClass... hazards) (appends) |
| Power armour fist and gun behaviour | ArmorPAWeapons.registerMelee(Item chest, IPAMelee component), registerRanged(Item chest, IPARanged component) |
| A glyphid kind in hive swarms | TileEntityGlyphidSpawner.addSwarmMember(Supplier<? extends EntityType<? extends EntityGlyphid>> type, int[] chance); chance is {base, soot scaling, soot threshold} |
| A named NBT structure | NBTStructure.registerStructure(SpawnCondition spawn); a second condition under the same name throws |
| A SILEX tiny waste item | SILEXRecipes.addTinyWaste(String tinyItemId, String fullItemId): the tiny item runs the full item’s row |
| A foundry mold output | ItemMold.MoldMulti.add(NTMMaterial mat, Supplier<ItemStack> out), ItemMold.MoldBlock.override(mat, stack) on a mold from ItemMold.getMold(stack) |
| An item in an HBM creative tab | .tab(HbmTab.X) on the chain, or ModTabs.addTo(HbmTab tab, RegistryObject<? extends Item> item) |
| A furnace fuel | a neoforge:furnace_fuels data map for NeoForge (Dejson: dev.golem.core.dejson.DataMaps.furnaceFuels().burnTime(id, ticks) then .register()), plus dev.golem.core.registry.Fuels.register(Map<Supplier<Item>, Integer>) from registered() for Fabric and Forge (a no-op on NeoForge) |
| A machine as a CC: Tweaked peripheral | com.hbm.api.computer.ComputerComponents.register(Class<BE> type, String name, Map<String, Method<BE>> methods, Supplier<? extends Block>... blocks); Method.call(machine, arguments) returns the result array. One component per block entity class |
Client side:
| Add | Call |
|---|---|
| A WIAJ cannery presentation for an item | Jars.register(String itemId, CanneryBase cannery) (com.hbm.wiaj.cannery) |
| A bomber skin | RenderBomber.registerSkin(String name, Skin skin), by the name EntityBomber.setSkin stores; a name registered twice throws |
| An entity renderer inside HBM’s registration | HbmEntityRenderers.addExtension(sink -> sink.register(type, provider)) (see Registering content) |
NTM: Space’s computer component, for example:
Map<String, ComputerComponents.Method<TileEntityMachineStardar>> methods = new LinkedHashMap<>();methods.put("getCurrentPlanet", (stardar, args) -> new Object[] {Orbit.bodyOf(stardar.getLevel()).name});ComputerComponents.register(TileEntityMachineStardar.class, "ntm_stardar", methods, SpaceMachinesD.MACHINE_STARDAR);Machines in hbmMachines.json
Section titled “Machines in hbmMachines.json”public static void register(IConfigurableMachine machine)Adds your machine to HBM’s hbmMachines.json config. Call before the config is read (it is read at common setup), for
example from declare(). IConfigurableMachine has getConfigName(), readIfPresent(JsonObject obj) and
writeConfig(JsonWriter writer), plus static grab(obj, name, default) helpers.