Skip to content

Reading Levels API

DepthDrako edited this page Jun 28, 2026 · 1 revision

Reading Levels (API & Commands)

Added in 1.0.7.

BotzMobLeveling lets datapacks, KubeJS scripts, and other mods read level data — including the area difficulty (the level a mob would spawn at for a given position, even when no mobs are present). This is what you use to build a custom HUD, scale loot, gate quests, etc.

There is no custom Minecraft attribute for level — levels live in entity NBT, and there's a small public Java API plus a query command for everything else.


Where a mob's level lives (NBT)

Every leveled mob stores its data in its Forge persistent data:

NBT key Meaning
botzmobleveling_Level Spawn (base) level
botzmobleveling_KillLevel Levels earned from kills
botzmobleveling_KillCount Number of kills
botzmobleveling_IsBoss 1 if the mob is a boss

Effective level = botzmobleveling_Level + botzmobleveling_KillLevel.

Read it anywhere you have the entity. In KubeJS:

let total = entity.persistentData.getInt('botzmobleveling_Level')
          + entity.persistentData.getInt('botzmobleveling_KillLevel')

In a datapack predicate / selector via nbt:

@e[type=zombie,nbt={ForgeData:{botzmobleveling_Level:50}}]

Commands

Command Returns Notes
/botzmobleveling arealevel [pos] Area difficulty at your position (or pos) Works with no mobs nearby
/botzmobleveling moblevel <entity> That mob's effective level

Both commands are available to all players (read-only) and return the value as their command result — so a datapack can capture it with execute store result.

Silent by default, opt-in printing

The commands print nothing by default, so you can run them every tick without chat spam. Append print to echo the value to chat:

/botzmobleveling arealevel               # silent, returns the value
/botzmobleveling arealevel print         # also prints to chat
/botzmobleveling arealevel ~ ~ ~ print   # at a position, prints
/botzmobleveling moblevel @e[limit=1,sort=nearest,type=!player] print

Public Java API (KubeJS / mods)

Class: com.botzlabz.mobleveling.api.BotzMobLevelingAPI

Method Returns
getAreaLevel(Level level, BlockPos pos) Area difficulty (base distance scaling) at a position; 0 for a non-server level
getMobLevel(Mob mob) Effective level (base + kill); 0 if unleveled
getMobBaseLevel(Mob mob) Base spawn level only
getMobKillLevel(Mob mob) Kill levels earned

In KubeJS, load it once and call it:

const BML = Java.loadClass('com.botzlabz.mobleveling.api.BotzMobLevelingAPI')
let area = BML.getAreaLevel(player.level, player.blockPosition())

Example: a constant "Area Level" HUD

Datapack (server-side, hidden until players join)

data/<your_pack>/functions/load.mcfunction:

scoreboard objectives add bml_area dummy

data/<your_pack>/functions/hud.mcfunction:

execute as @a store result score @s bml_area run botzmobleveling arealevel
execute as @a run title @s actionbar [{"text":"Area Level ","color":"gray"},{"score":{"name":"@s","objective":"bml_area"},"color":"gold"}]

Wire them up with function tags:

  • data/minecraft/tags/functions/load.json{"values":["<your_pack>:load"]}
  • data/minecraft/tags/functions/tick.json{"values":["<your_pack>:hud"]}

Because the command is silent, this produces no chat spam — no sendCommandFeedback change needed.

KubeJS

const BML = Java.loadClass('com.botzlabz.mobleveling.api.BotzMobLevelingAPI')

ServerEvents.tick(e => {
  if (e.server.tickCount % 10 !== 0) return
  e.server.players.forEach(p => {
    let lvl = BML.getAreaLevel(p.level, p.blockPosition())
    p.setStatusMessage(Text.gold('Area Level: ' + lvl)) // actionbar; method name may vary by KubeJS version
  })
})

Accuracy note

getAreaLevel / arealevel reflect the base distance scaling — the configured distance settings (distanceStartRadius, distancePerLevel, distanceLevelMultiplier) and the default level range (defaultMinLevel / defaultMaxLevel).

They do not fold in per-rule overrides (biome / structure / dimension rules) or adaptive-difficulty bonuses, since those are rule- or mob-specific. To make a HUD line up with what actually spawns in your pack, set defaultMinLevel / defaultMaxLevel in the config to match your catch-all base rule's range.

Clone this wiki locally