Spawning
Four ways a mob reaches the world. Anchors are configured in config.yml and driven by world generation; the other three live in spawners/ and are told apart by a kind: field.
Structure anchors
A world generator places a marker where a boss belongs. Bestiary adopts it on chunk load, records the position, deletes the entity, and from then on spawns the boss on player proximity with a persisted respawn cooldown.
Nothing spawns in the thousands of structures nobody has visited.
anchors:
types:
MARKER: bestiary:example_boss
tag-prefix: "bestiary:"
respawn-cooldown: 30m
activation-range: 64
scan-period-ticks: 20
Identity
Two ways, tried in that order:
- A scoreboard tag, where the generator can write one. A tag of
bestiary:aether/valkyrie_championnames that mob directly, and needs no config at all. - The entity-type map, where it cannot. One entity type maps to one mob id.
The type map is the fallback rather than the only path because a TerraScript entity() call carrying NBT most likely spawns nothing at all, so the design works whichever way that turns out.
Why position and existence are stored apart
Worldgen decides the position once and immutably; the runtime decides existence cheaply and repeatedly.
That separation is what makes every removal Bestiary did not intend heal itself on the next player visit, whether that was peaceful difficulty, a fall into the void, or another plugin's remove(). The anchor still knows where the boss belongs, so it simply spawns again once the cooldown has passed.
Managing them
/bestiary anchor create <mob> [id]
/bestiary anchor remove <id>
/bestiary anchor list
/bestiary anchor reset <id>
reset clears the respawn cooldown, which is the one you want while testing.
Placed spawners
kind: spawner is an admin-placed point, persisted and editable in game.
frostling_camp:
kind: spawner
mob: aether:frostling
world: world
x: 128
y: 72
z: -340
radius: 6
amount: 2
max_concurrent: 6
cooldown: 45s
activation_range: 32
mobmob idrequiredtypeis accepted as an alias.worldstringrequiredMust be loaded when the file is read, or the entry fails to parse.
xnumberdefault0The point itself.
ynumberdefault64The point itself.
znumberdefault0The point itself.
levelnumberdefault1The level spawned mobs start at.
radiusnumberdefault3Mobs appear within this radius of the point, not exactly on it.
amountnumberdefault1How many per spawn.
max_concurrentnumberdefault4How many of this spawner's mobs may be alive at once.
cooldowndurationdefault30sBetween spawns, once the spawner is active.
activation_rangenumberdefault32Nothing spawns unless a player is within this distance.
enabledbooleandefaulttrueTurn it off without deleting it.
conditionscondition listChecked before each spawn: time of day, weather, nearby player count.
Easier to place in game than to write by hand:
/bestiary spawner create <mob> [id]
/bestiary spawner remove <id>
/bestiary spawner list
Spawn regions
kind: region is a box that keeps a weighted population alive inside it.
frozen_valley:
kind: region
world: world
min_x: 100
min_y: 60
min_z: -400
max_x: 300
max_y: 120
max_z: -200
mobs:
aether:frostling: 8
aether:frost_warden: 1
max_concurrent: 6
cooldown: 30s
activation_range: 48
mobs takes a map of id to weight, or a plain list where every entry weighs the same. Its defaults differ from a spawner's: max_concurrent is 6 and activation_range is 48.
Random spawn rules
kind: random replaces or supplements natural spawns, filtered by world, biome, height, light and time.
frostling_wild:
kind: random
mob: aether:frostling
worlds: [world]
biomes: [snowy_taiga, frozen_peaks]
replaces: [stray]
min_y: 60
max_y: 200
min_light: 0
max_light: 7
time: night
chance: 0.05
budget: 40
worldslistEmpty means every world.
biomeslistEmpty means every biome.
replaceslistVanilla entity types this rule replaces. Empty means it supplements rather than replaces.
min_ynumberdefault-64Height band, inclusive.
max_ynumberdefault320Height band, inclusive.
min_lightnumberdefault0Light band, inclusive.
max_light: 7is roughly "dark enough for hostiles".max_lightnumberdefault15Light band, inclusive.
timestringdefaultanyday,nightorany.chancenumberdefault0.05Per eligible natural spawn.
levelnumberdefault1The level spawned mobs start at.
budgetnumberdefault40Maximum spawns from this rule per world.
Checking what exists
/bestiary list anchors
/bestiary list spawners
Test in stages: prove the mob with /bestiary spawn, inspect the anchor, spawner or rule with its
list command, then wait for activation. Random rules are bounded by
performance.random-spawn-budget-per-world; placed spawners and anchors use their own scan periods
and activation ranges.