Skip to main content

KubeJS

KubeJS is well suited to registering concrete items, blocks, recipes and content objects; MiXianTu reads those objects and gives them rules through binding tables. Do not modify server attachments directly in a script, and do not bypass cost validation.

What the Integration Gives You

The KubeJS bridge is optional. It exposes one global object per domain instead of a single Mxt root object:

GlobalResponsibility
MxtActionsRegister mxt:js action callbacks, or run a built-in action.
MxtConditionsRegister mxt:js condition callbacks, or test a built-in condition.
MxtValuesRegister or evaluate number providers and resource value providers.
MxtCostsCheck or pay a single complete cost.
MxtResourcesPay several resource costs atomically.
MxtAbilitiesCast an ability the entity already holds.
MxtCultivationAdd cultivation progress and attempt a realm breakthrough.
MxtCursesApply or explicitly remove a curse.
MxtAuraQuery, add and remove server-side aura areas.
MxtSoulsReclaim the transferable soul of an entity.
MxtEventsEvery MiXianTu server lifecycle event.

Every API that changes game state must be called from kubejs/server_scripts/, and it goes through the mod's existing server transactions and event flow. See the API Reference for the method signatures.

When You Need KubeJS

The mod is a framework, not a content pack:

  • A data pack can define rules, but it cannot create a new item, block or recipe.
  • If everything you need to bind already exists — vanilla items, items from another mod, or items the mod ships with — plain data pack JSON is enough, and KubeJS stays optional.
  • Register content with KubeJS when you want your own items, food, tools or recipes, then bind those real item IDs to the framework.
  • Scripted callbacks are optional too: conditions, actions and number providers can also be written entirely as data pack JSON with the built-in types.

Registering Content Items

The item itself is registered by KubeJS in a startup script:

// kubejs/startup_scripts/mxt_items.js
StartupEvents.registry('item', event => {
event.create('jade_token').displayName('Jade Token')
})

A larger script can register food and tools in the same pass:

// kubejs/startup_scripts/mxt_items.js
StartupEvents.registry('item', event => {
event.create('fire_root_pellet')
.displayName('Fire Root Pellet')
.food(food => food.hunger(2).saturation(0.2))

event.create('returning_pill')
.displayName('Returning Pill')
.food(food => food.hunger(1).saturation(0.1))

event.create('firebound_sword', 'sword')
.displayName('Firebound Sword')
.tier('diamond')
})
warning

Register the item itself and bind it by its real item ID. Do not create mxt:item, mxt:pill or mxt:weapon files for it.

Attaching Items with Binding Tables

MiXianTu is responsible for behaviour, conditions, aura, currency and tooltips; the binding tables in your data pack connect a registered item to those rules. Each of the following files lives under kubejs/data/<namespace>/mxt/<registry>/.

Bind a pill that grants a spirit root:

// kubejs/data/example/mxt/item_binding/fire_root_pellet.json
{
"items": "kubejs:fire_root_pellet",
"quality_group": "#example:group/pellet",
"actions": [
{
"type": "mxt:grant_spirit_root",
"spirit_root": "example:fire_root"
}
]
}

Bind a weapon's damage and attack speed:

// kubejs/data/example/mxt/weapon_binding/firebound_sword.json
{
"items": ["kubejs:firebound_sword", "#example:fire_weapons"],
"attack_damage": 8,
"attack_speed": -2.4,
"quality_group": "#example:group/firebound_weapon"
}

Bind a pill's toxicity:

// kubejs/data/example/mxt/pill_binding/returning_pill.json
{
"items": "kubejs:returning_pill",
"quality_group": "#example:group/pill",
"toxicity_gain": 10,
"toxicity_threshold": 100,
"toxicity_after_overdose": 25
}

Bind a cultivation technique to its carrier item:

// kubejs/data/example/mxt/technique_binding/fire_manual.json
{
"items": "kubejs:fire_manual",
"technique": "example:fire_manual",
"quality_group": "#example:group/manual"
}

All four binding tables only reference items that KubeJS, vanilla or another mod has already registered, and quality_group is an optional vanilla item_quality tag reference. When the bound item ID does not exist, data pack loading fails, so that no unresolvable item rule is created.

Reloading

Reloading the KubeJS item registry requires restarting the game, while MiXianTu binding data can be reloaded with /reload.

// kubejs/server_scripts/mxt_reload_notice.js
ServerEvents.loaded(event => {
console.log('MiXianTu data pack loaded, use /mxt registries validate to check the registries')
})

Rules and Events from Scripts

A script can also provide the rule implementation itself. Register a callback under a namespaced ID, then reference that ID from any matching data pack field:

MxtActions.entity('example:heal', (entity, params) => {
entity.heal(params.amount || 1)
})
{
"type": "mxt:js",
"id": "example:heal",
"params": { "amount": 4 }
}

Actions, conditions, number providers and resource value providers each have a pre-registered mxt:js type for this. The id is unique within the same callback category, and KubeJS clears every callback before reloading server scripts and re-runs the scripts, so keep registrations in server scripts rather than in a client script that only runs once.

All server lifecycle events are subscribed through MxtEvents:

MxtEvents.abilityUse(event => {
if (event.isPre() && event.getAbility() === 'example:forbidden') {
event.cancel()
}
})