Startup registry
HBMEvents.registry is the one startup event. It lets a startup script add content that is data only: today, crucible
and foundry materials. New fluids come from KubeJS’s own fluid registration plus a datapack file, see
Fluids below.
HBMEvents.registry(event => { event.material('zinc').displayName('Zinc').colors(0xA8B3B5, 0x4E5A5C, 0xC6CFD0).smelting('SMELTABLE') event.material('brass_scrap').smelting('SMELTABLE').smeltsInto('copper', 2, 1)})When it runs
Section titled “When it runs”HBM posts the event once, right after KubeJS has loaded the startup scripts. Each call only records a request. HBM adds the materials later, once every mod’s registries are filled and before any datapack loads, on the client and on the server. The log then says:
[HBM] Added 2 material(s) from startup scriptsA request that cannot be applied is logged and skipped, never thrown into the game. For example:
[HBM] Script material 'zinc' skipped: the name is taken[HBM] Script material 'brass_scrap' skipped: smeltsInto names no material: brassMistakes the builder can see at once (a bad name, an unknown smelting behaviour, a non-positive amount) are thrown as script errors on the line that made them.
event.material(name)
Section titled “event.material(name)”Starts a new material and returns its builder.
name: lower-case letters, digits and_only. Anything else throwsA material name is lower case letters, digits and _: <name>.- The name must not be taken by any material, HBM’s or another mod’s. Check with
HBM.materials()in a server script. - Only callable while the event runs. Calling it later throws
HBMEvents.registry is over; ....
Builder methods
Section titled “Builder methods”All return the builder, so they chain. Each is optional.
| Method | Default | Meaning |
|---|---|---|
displayName(text) |
the name in title case (brass_scrap becomes “Brass Scrap”) |
The name players see. |
colors(solidLight, solidDark, molten) |
0xFF4A00, 0x802000, 0xFF4A00 |
Colours as 0xRRGGBB: the light and dark solid shades (items, slag) and the molten colour (crucible, foundry, casting). |
smelting(behavior) |
NOT_SMELTABLE |
How the material behaves in a crucible, see below. Case-insensitive. An unknown value throws. |
smeltsInto(material, in, out) |
itself, 1, 1 | Melts into another material: in units of this make out units of that, as coal melts into carbon. in and out must be above 0. material must already exist when HBM applies the request (HBM’s, another mod’s, or a script material requested earlier). |
The builder also has name (read-only) with the requested name.
smelting values:
| Value | Meaning |
|---|---|
NOT_SMELTABLE |
Cannot be smelted, and does not belong in a smelter (like diamond) |
VAPORIZES |
Cannot be smelted: the material would vaporize |
BREAKS |
Cannot be smelted: the material does not survive the heat |
SMELTABLE |
Melts normally (most metals) |
ADDITIVE |
Not smeltable on its own, but can go into a crucible (like coal) |
How items become the material
Section titled “How items become the material”HBM does not create items for script materials (no ingots, plates or other auto-generated shapes: those need models
built into the mod). Instead, any item counts as the material through the common c: item tags:
| Tag | Shape | Amount per item |
|---|---|---|
c:nuggets/<name> |
nugget | 8 |
c:billets/<name> |
billet | 48 |
c:ingots/<name> |
ingot | 72 |
c:gems/<name> |
gem | 72 |
c:crystals/<name> |
crystal | 72 |
c:dusts/<name> |
powder | 72 |
c:dusts_tiny/<name> |
tiny pile | 8 |
c:plates/<name> |
plate | 72 |
c:wires/<name> |
wire | 9 |
c:storage_blocks/<name> |
block | 648 |
Amounts are in HBM’s material units: 72 is one ingot, shown in game as 144 mB (two millibuckets per unit). HBM knows more
shapes (dense wires, cast and welded plates, pipes, gun parts, …); HBM.material('<name>').tags lists every shape’s
tag. Ore tags (c:ores/<name>) do not melt.
An item melts in a crucible only when the material it melts into (smeltsInto, itself by default) is SMELTABLE or
ADDITIVE. A material left at NOT_SMELTABLE is known to HBM but its items do not melt.
A material_distribution row for one of the item’s tags (see the datapack section) wins over this tag lookup.
Tag your items in a server script with KubeJS’s tag event, or in a datapack:
ServerEvents.tags('item', event => { event.add('c:ingots/zinc', 'kubejs:zinc_ingot') event.add('c:nuggets/zinc', 'kubejs:zinc_nugget')})kubejs:zinc_ingot here is any item: one from another mod, or one made with KubeJS’s own startup item registration.
Client and server must match
Section titled “Client and server must match”Materials are saved by name, but the game sends them over the network as numbers. A script material’s number is worked out from its name alone, so the same startup scripts give the same numbers on every side, whatever else is installed. That only holds if the client and the server run the same startup scripts. Ship your startup scripts with the client pack as well as the server.
Fluids
Section titled “Fluids”There is no fluid builder in HBMEvents.registry, and none is needed:
- Register the fluid with KubeJS’s own startup fluid registration (see the KubeJS documentation for your version;
the id is
kubejs:<name>unless you give a namespace). Any registered fluid is an HBM fluid as soon as HBM meets it: it can go in HBM tanks, ducts and recipes, andHBM.fluid('kubejs:<name>')describes it. - Give it HBM properties with a data file
kubejs/data/<fluid namespace>/fluid_property/<fluid name>.json(data/...in a plain datapack). Without one, the fluid has no traits and no hazard, and HBM shows it white at room temperature. See Fluids for the format.
{ "type": "liquid", "color": "#98BDF9", "temperature": -100, "hazard": { "poison": 3, "flammability": 0, "reactivity": 0, "symbol": "cryogenic" }, "flags": [ "gaseous_art" ]}That example is HBM’s own hbm:oxygen file, with the path changed. New trait types (a trait name HBM does not have)
need Java: an addon mod’s FluidProperties.registerTrait.
Then use the fluid in recipes like any other:
event.recipes.hbm.chemical_plant('kjs.liquid_ozone') .inputFluids([Fluid.of('hbm:oxygen', 1000)]) .outputFluids([Fluid.of('kubejs:liquid_ozone', 500)]) .duration(100).power(1000)