Build the Aura Environment
Define Aura and Realms left you with one zone that covers the whole Overworld with the same amount of aura. This page makes the world matter: denser regions, spirit stone veins, items you can burn while meditating, and the client-side presentation that tells a player where they are standing.
The previous tutorial must be finished first — everything here extends the same example:qi resource.
How the Numbers Fit Together
Two different numbers are involved, and confusing them is the usual source of surprise:
| Number | Where it lives | What it means |
|---|---|---|
| Chunk inventory | The mxt:aura chunk attachment | What can actually be consumed at this position. Shared by every player in the chunk, regenerated by regen_per_tick. |
| Environment concentration | Computed from the matching zone | What the template says is here. Fluctuation and noise act on it, and it is what the client shows. |
When a chunk is initialised, each resource starts at max(0, (amount + noise) / 10 - 5), where noise is the Perlin value of the template (or 0 when noise is off). The bare amount is therefore a base value ten times larger than the concentration it produces — a template with amount: 200 starts around 15. Capacity comes from max, which is resolved from that initial value unless you write a fixed number.
Cultivation progress and the aura a player gains are multiplied by the concentration multiplier at their position: concentration / maximum for a finite maximum, and concentration / (concentration + 1) for {"type": "mxt:unlimited"}.
Step 1 — A Denser Biome Zone
Two overlapping templates are resolved level by level: biome < dimension < permanent manual area < formation. A later level replaces the aura values, element values, rules and display template of the earlier one entirely. Inside one level, the highest priority wins, and equal priorities are broken by taking the template with the lower ID, so the result is always reproducible.
That is why the two zones here are both biome-level: the forest template simply outranks the general one where it applies.
// data/example/mxt/aura_zone/misty_valley.json
{
"aura": {
"example:qi": {
"amount": 400,
"max": {"type": "mxt:initial_multiplier", "multiplier": 1.5},
"regen_per_tick": 0.1,
"color": "#7FE3C4"
}
},
"aura_kinds": ["example:common_aura"],
"biomes": ["#minecraft:is_forest"],
"priority": 10,
"distribution": "realm_weighted",
"cultivate_condition": {
"type": "mxt:aura_range",
"aura": {"example:qi": {"min": 5, "max": 100000}}
},
"fluctuation": {
"enable": true,
"cycle_type": "day",
"amplitude": 0.3,
"offset_tick": 0
},
"noise": {
"enable": true,
"seed": 739430,
"scale": 640.0,
"amplitude": 5.0
},
"element_fit_bonus": 0.25,
"element_conflict_penalty": 0.2,
"client_render": {
"fog_color": "#7FE3C4",
"render_distance": 64,
"fog_strength": 0.35
},
"client_hud": {
"stored_aura": {"maximum": 60.0, "bar_index": 1, "anchor": "left", "order": 4},
"sensed_concentration": {"maximum": 60.0, "bar_index": 2, "anchor": "left", "order": 5}
}
}
| Field | Effect |
|---|---|
aura | Per-resource inventory: amount, max, regen_per_tick and the environment color. max accepts a number, mxt:fixed, mxt:initial_multiplier or mxt:unlimited. |
aura_kinds | The aura kinds present here. They are matched as a set against cultivate_action.aura_kinds and alchemy_recipe.aura_kinds; they are markers, not sources of value. |
priority | Used only against other templates of the same level. |
distribution | random, equal or realm_weighted; it decides who gets how much when the chunk inventory cannot satisfy everyone. realm_weighted uses aura_share_weight from each player's realm stage. |
cultivate_condition | An entity condition the environment must satisfy for cultivation. Note that mxt:aura_range requires max on every resource entry. |
fluctuation | Multiplies the concentration by 1 + amplitude * sin(2π * (time + offset_tick) / cycle), with a 24000-tick day cycle or a 192000-tick moon cycle. It only affects the queried concentration, never the stored inventory. |
noise | A seeded, reproducible Perlin offset so the map has gradients instead of hard borders. scale around 640–960 is recommended; amplitude: 5 gives roughly a -5..5 disturbance before the / 10 - 5 transform. |
element_fit_bonus / element_conflict_penalty | Multipliers applied when a player's spirit root element matches or clashes with the environment. |
client_render | Fog colour, the distance it is applied over (8..256) and how strongly it replaces the vanilla fog (0..1). The strength is also scaled by the concentration, so thin aura looks fainter. |
client_hud | Two optional bars: stored_aura reads the chunk inventory, sensed_concentration reads the environment template. They are drawn above the resource bars of the same side. |
Rules
The rules object adds environment policy:
"rules": {
"cultivate_suppress": false,
"tribulation_modify": 0.15
}
cultivate_suppress aborts cultivation that is already running, and tribulation_modify injects the formula variable aura_tribulation_modifier into tribulation formulas. The other three fields — spirit_plant_bonus, alchemy_env_bonus and natural_spawn_herb — are parsed but not yet connected to a consumer, so treat them as not implemented.
Step 2 — Aura From Blocks
A spirit stone vein should be worth more than the ground it sits in.
// data/example/mxt/block_aura/spirit_stone_ore.json
{
"blocks": ["mxt:spirit_stone_ore", "mxt:spirit_stone_block"],
"aura": {
"example:qi": {"amount": 5.0, "max": 5.0, "regen_per_tick": 0.01}
},
"aura_kinds": ["example:common_aura"]
}
blockstakes block IDs and block tags; every matching block in a chunk contributes once.- The contribution does not consume the environment maximum: it raises the chunk's effective capacity by the same amount. An environment maximum of
30with30points of ore becomes60. - Queries look at a 7x7x7 range of sub-chunks: the inner 3x3x3 uses real block positions, the outer ring approximates with sub-chunk centres, and all of it decays by
1 / max(1, distance²). - The cache is rebuilt when a chunk loads, when a block changes and when the data tables are loaded, and the interval is
aura.block_aura_tick_intervalinconfig/mxt-server.json(default10ticks,1..1200).
A common pattern is to make the natural template almost empty and let blocks provide the aura:
"aura": {
"example:qi": {"amount": 0, "max": {"type": "mxt:unlimited"}, "regen_per_tick": 0}
},
"noise": {"enable": true, "seed": 739430, "scale": 640.0, "amplitude": 5.0}
With amount: 0, most chunks sit at 0 after the / 10 - 5 transform, and only places with actual aura-emitting blocks stand out.
Step 3 — Aura From Items
item_aura turns an item into cultivation fuel: while the player cultivates, the stack is drained tick by tick and its aura is released into the resource bar of the current realm.
// data/example/mxt/item_aura/spirit_stone.json
{
"items": ["mxt:spirit_stone", "#example:spirit_fuel"],
"type": "example:qi",
"aura": 100,
"consume_speed": "0.5 + caster_level * 0.05",
"release_speed": 2,
"exhausted_action": {"type": "mxt:no_op"}
}
itemsis the usual item matcher, so one file can cover a whole tag of fuel items.typeis the resource that receives the released aura — not an element.aurais the total per item, written into a server-sidemxt:item_auracomponent on the stack when processing starts; the whole stack moves into themxt:float_holding_itemattachment for the duration.- Each tick the definition matched at that moment subtracts
consume_speed × stack sizefrom the remaining aura and chargesrelease_speed × stack sizeinto the realm's resource bar. Holding more items drains faster but lasts the same number of ticks. - A half-used stack is resumed before a fresh one is taken, and fresh stacks are taken in main hand, off hand, inventory order. When cultivation stops, the player logs out or dies, the stack is returned unchanged.
- On exhaustion the item is removed and
result_stack(if configured) is given back. Items implementingSpiritItemAccessbehave differently: they are charged and drained in place instead of being consumed.
The client does not draw a fuel bar, and never consumes items on its own.
Step 4 — Where It Shows Up
| Place | What it shows |
|---|---|
client_hud.stored_aura | The chunk inventory, as a real value that goes up and down with cultivation. |
client_hud.sensed_concentration | The environment template at the current position, including fluctuation and noise. |
Resource bars with "context": "mxt:environment_concentration" / "mxt:actual_concentration" | The same two numbers, but labelled after the resource, so resource.example.qi becomes environmental or actual aura concentration. |
| Fog | client_render, scaled by concentration. |
| Particles | The optional particle object on the template, refreshed every 5 ticks. |
actual includes every source — template, chunk inventory, block aura and formations — while environment is only the template. The server syncs the position aura every aura.sync_interval ticks (config/mxt-server.json, 5 by default) and the client only draws the snapshot.
On the command line:
/mxt aura query → every resource at your feet, with its element marker
/mxt aura query example:qi → one resource
/mxt aura vein → the size and tier of the connected spirit stone vein you stand on
/mxt aura cache clear 8 → rebuild the cached aura of nearby chunks (radius in chunks, 0..32)
Step 5 — Areas From a Script
Biomes and dimensions cover the static world. For anything that has to be created at runtime — a blessing placed by a quest, a sect's territory, a temporary field — use the KubeJS bridge:
// kubejs/server_scripts/mxt_areas.js
const area = MxtAura.addBox(
player.level, 'example:misty_valley',
0, 64, 0, // minimum corner
64, 128, 64, // maximum corner
10 // priority
)
console.info(`Created aura area ${area}`)
// Read the resolved aura at a position, including every source.
const aura = MxtAura.get(player.level, player.blockPosition)
console.info(`Concentration: ${aura.concentration()}, maximum: ${aura.maximum()}`)
// Later, or from another script:
// MxtAura.remove(player.level, area)
addBox needs a server level and a loaded aura_zone ID, and it returns the generated area ID. Manual areas are saved to the world, are the level above dimension bindings, and among themselves are resolved by priority. MxtAura.get is read-only and works on the client too, where it returns whatever state the client has received.
MxtEvents.auraZone fires with enter, leave, tick and override; override is the formation hand-off and can be cancelled to refuse it:
MxtEvents.auraZone(event => {
if (event.getKind() === 'override' && event.getConcentration() < 20) event.cancel()
})
Formations can also carry their own zone, which is the top level of the resolution order:
{
"structure_template": "example:gathering_array",
"radius": 8,
"max_bonus": {"example:qi": 50},
"aura_zone": "example:misty_valley"
}
Step 6 — Verify
Load the world again — these are data pack registries, so /reload does not pick them up — then run:
(load the world again)
/mxt registries validate
/mxt aura query example:qi → a forest should read higher than a plains
- Stand in a forest during the day and check
/mxt aura query; sleep to night and check again. The value moved by up to ±30%, because offluctuation. - Walk a few hundred blocks in one direction. The value drifts smoothly, because of
noise. - Stand on spirit stone ore and run
/mxt aura vein, then compare/mxt aura querybefore and after mining it out. The removable part is the block contribution. - Cultivate while holding spirit stones. The bar fills noticeably faster than with empty hands, and the stack shrinks.
- If the fog is invisible, remember that
fog_strengthis multiplied by the concentration — a weak zone produces weak fog.
Common Mistakes
| Symptom | Cause |
|---|---|
| The zone never applies | Its biomes/dimensions are empty, and nothing references it. An empty list means "only through a manual area or a formation". |
| A specific zone is ignored | A dimension-level template outranks every biome-level one. Give the specific zone the same level as the general zone and a higher priority. |
Aura is ten times weaker than amount suggests | amount is a base value: the initial concentration is amount / 10 - 5 before noise. |
| Block aura seems to do nothing | It adds capacity, not a visible concentration, to a chunk whose environment maximum is already high. Lower the template's amount and let blocks carry the difference. |
| Aura keeps resetting to the template value | Fluctuation, noise and regeneration all recompute the template; the stored inventory only changes through cultivation, item fuel and regeneration. |
Next
- Create Items with KubeJS and Bind Them — the spirit stones and pills these tables refer to.
- Aura Zone, Block Aura and Item Aura — every remaining field.