Skip to content

KubeJS Reference

JohnBraham edited this page Nov 6, 2026 · 2 revisions

KubeJS reference

LeyLines is available in startup and server scripts when KubeJS is installed. The startup binding registers currencies. The server binding works with a live server level and player. Use a normal server event for ledger operations. KubeJS Tutorial

Script scope Call Behavior
Startup registerCurrency(id, unitsPerRaw) Call in StartupEvents.init. Use a unique kubejs: ID and a positive exact rate string. Restart the process after changes.
Server inspectAt(level, x, y, z) Returns a read-only map for that block. account is null outside an eligible nexus.
Server convertAt(level, x, y, z, currency, raw, consumer[, actor]) Exchanges raw for whole units of an active currency.
Server spendAt(level, x, y, z, currency, units, consumer[, actor]) Consumes whole units of an active currency and frees capacity.
Server returnToRawAt(level, x, y, z, currency, units, consumer[, actor]) Exchanges whole units back into raw at the saved rate, including retained inactive currencies.
Server grantVision(player, source, durationTicks[, style]) Grants or renews this source for a positive number of server ticks.
Server revokeVision(player, source) Removes this source’s grant.

Use a ServerLevel, integer block coordinates, and namespaced IDs for the currency, consumer, and vision source. An optional actor must be a ServerPlayer in the same level. Syntax errors, the wrong actor level, or calls from the wrong thread can raise an exception instead of returning a transaction status.

Rates and transaction amounts must be strings. Use '1000' for whole units, or '3/2' for an exact raw amount or rate. An amount must be positive for a transaction, and spending and returning use whole units. Conversion must result in whole currency units. For example, a rate of '3/2' gives 3 units for '2' raw. Converting '1' raw at that rate yields NON_INTEGRAL_OUTPUT. Keep amounts as strings when displaying or passing them back, since JavaScript numbers can round large integers.

Read a map

Use .get('key') for maps returned by the bridge. Here is an inspection you can use inside a server event with a player.

const player = event.player
const pos = player.blockPosition()
const reading = LeyLines.inspectAt(player.serverLevel(), pos.x, pos.y, pos.z)
const account = reading.get('account')
if (account !== null) {
  const balance = account.get('balance')
  const aether = balance.get('currencies').get('kubejs:survey_aether')
  if (aether !== null) player.tell('Survey aether: ' + aether.get('units'))
}
Map Keys
Inspection dimension (string), x, y, z (integers), active (boolean), naturalStrength, lineStrength, nexusStrength, verticalFactor, dimensionalResistance (numbers), account (map or null).
Account nexus (stable ID string), x and z (nexus centre), strength (intrinsic strength), rechargeTicks (effective full refill interval), balance (snapshot). Named pins also supply pinId (namespaced ID) and authoredY (integer). Those keys are absent for seeded nexuses.
Balance snapshot raw and total (exact strings in raw equivalents), capacity (integer after applying the world multiplier), tick (string), currencies (map keyed by full currency ID).
Currency row units (whole-unit string), unitsPerRaw (exact rate string), active (boolean). Zero-balance and retained inactive currencies can appear.
Transaction result succeeded (boolean) and status (string). Success also adds nexus, revision (string), and before and after snapshots.

Reading an account creates no reservation. Transactions choose the nearest eligible nexus, with a stable tie-break, and apply all changes to that account together. A script can read a quote and then find that a later spend fails because another action used the funds first. Check the actual spend result. Common statuses include NO_NEXUS, INSUFFICIENT_RAW, INSUFFICIENT_CURRENCY, INACTIVE_CURRENCY, and CANCELLED from a protection hook. Full status table

Player pools and timed jobs

Call these methods from a server script. A player needs a configured pool for each currency they can hold. Pass whole unit amounts and capacities as strings, such as '1000'. Use a namespaced source ID for each action. Player Energy Pools

Call Behavior
inspectPlayer(player) or inspectPlayer(server, uuid) Returns the player UUID and a pools map keyed by currency ID. Each pool has units, capacity, enabled, active, and optional autoRate.
configurePool(player, currency, enabled, capacity, autoRate, source) Opens a pool or changes its settings. Pass null for no automatic recharge.
setPoolBalance(player, currency, units, source) Sets the pool balance for a trusted gameplay or admin action.
adjustPool(player, currency, signedDelta, source) Changes the balance by a signed whole unit string, such as '-10'.
spendPool(player, currency, units, source) Pays for a player action from their personal balance.
withdrawToPlayer(player, currency, units, schedule, source) Moves converted units from the nexus into the player pool.
depositFromPlayer(player, currency, units, schedule, source) Returns converted units from the player to the nexus if there is room.
transferPlayers(from, to, currency, units, schedule, source) Moves units between two online players.
scheduleConversion(level, x, y, z, currency, raw, schedule, source[, actor]) Converts raw into currency at a nexus using the chosen schedule.
energyJob(server, jobId) Reads id, operation, currency, total, completed, status, and source, or returns null.
cancelEnergyJob(server, jobId) Returns true if it cancelled the job. Transfers that already took place stay in effect.

Schedules are 'instant', 'duration:40' for 40 server ticks, or 'rate:3/2' for an exact throughput. A response with status set to RUNNING includes a jobId. Check that job for completion before granting a reward. Immediate success includes a receipt with the operation, currency, amount, and changes keyed by player UUID.

Use LeyLinesEvents.playerPoolChanged to observe a committed change and LeyLinesEvents.playerPoolEmpty when a positive balance becomes zero. Both expose playerId, currency, before, after, receipt, and server. LeyLinesEvents.energyJobFinished exposes job and server. Read event properties directly and use .get() for their maps, such as event.after.get('units'). Schedule a new mutation for a later tick.

Ley Vision and script lifecycle

Use skysleylines:river, skysleylines:crackle, skysleylines:sparkles, or skysleylines:glow, or omit the style for the server default. Java add-ons can register more styles. Use a different namespaced source for each spell or item whose expiry should be independent. Reusing a source sets a new expiry from the current tick. Other active sources and the operator toggle can keep vision visible. Grants end on logout or respawn.

Use /reload for server script edits. Restart the process to add, change, or remove startup currency definitions. Scripts can call transactions as part of pack gameplay without an operator command. Implement the pack’s access rules in the event handler and pass the player actor so Java protection hooks can evaluate the request. Java protection hooks

Clone this wiki locally