Skip to content

API reference / @jsprismarine/spawning

@jsprismarine/spawning ​

Join the Discord Servernpm

Bedrock natural spawning: the spawn_rules/*.json grammar, the condition evaluator, the population pools and the spawn loop. It builds on @jsprismarine/packs for the filter grammar, on @jsprismarine/entities for the filter evaluator that spawn rules, entity definitions and trade tables all share, and on @jsprismarine/predicates for the injected random source.

typescript
import { Spawner, parseSpawnRule } from '@jsprismarine/spawning';
import { seededRandom } from '@jsprismarine/predicates';

const rules = files.map((file) => parseSpawnRule(file.data, { pack: file.pack, path: file.path }));
const spawner = new Spawner({ rules: rules.filter((rule) => rule !== undefined), world, random: seededRandom(seed) });

for (const request of spawner.tick(tick)) {
    world.create(request.identifier, request.position, request.spawnEvent);
}

The grammar ​

A file is {"format_version": "<semver>", "minecraft:spawn_rules": {description, conditions}}. description carries identifier and population_control; conditions is a list of alternatives, and a rule allows a position when any one of them does.

parseSpawnRule reads all 24 components Spawn Rules.json declares and reports an unknown one rather than refusing the file, so a pack written against a newer game still loads. Vanilla writes 21 of the 24. The three it never writes, minecraft:spawns_above_block_filter, minecraft:is_persistent and minecraft:is_experimental, parse into the condition and keep their meaning for the caller, because Mojang documents none of them.

Three components are written in more than one shape, and all of them read:

  • minecraft:spawns_on_block_filter as one name, as a list of names, or as a list of {name} objects.
  • minecraft:herd as one object or as a list of alternatives, which is how the tropical fish picks a color event.
  • minecraft:biome_filter as one test, as a bare array (an implicit all_of), or as a group map. @jsprismarine/packs parses it, including the integer subject and operator encoding and the AND, OR and NOT aliases.

minecraft:permute_type entries read both spellings of their third field: the schema's min_guaranteed and the documentation page's guaranteed_count.

What a condition decides ​

evaluateSpawnCondition runs the components cheapest first and names the first one that rejected the position, so a server can explain an empty attempt and a test can name the component it covers.

ComponentWhat it compares
minecraft:spawns_on_surface, minecraft:spawns_undergroundThe pass the position is in. Naming both takes either; naming neither takes any.
minecraft:spawns_underwater, minecraft:spawns_lavaThe medium. Naming neither refuses a position inside either liquid.
minecraft:disallow_spawns_in_bubbleA bubble column at the position.
minecraft:height_filterThe position's Y against the inclusive range.
minecraft:spawns_on_block_filter, minecraft:spawns_on_block_prevented_filterThe block one below the position.
minecraft:spawns_above_block_filterThe distance blocks below the position.
minecraft:brightness_filterThe light the world reports, lowered by the weather when adjust_for_weather is set.
minecraft:difficulty_filterThe world difficulty against the inclusive range.
minecraft:world_age_filterThe world age in ticks; a maximum of -1 is no upper bound.
minecraft:mob_event_filterWhether the named mob event is running.
minecraft:distance_filterThe distance to the nearest player.
minecraft:player_in_village_filterA player within distance who is within village_border_tolerance of a village border.
minecraft:biome_filterThe shared filter grammar, through the @jsprismarine/entities evaluator.
minecraft:density_limitHow many entities of this type stand within densityRadius, per pass.
minecraft:delay_filterA cooldown keyed by the filter's identifier, then a spawn_chance roll.

The remaining six components are not gates. minecraft:weight and its rarity pick between the conditions that passed, minecraft:herd and minecraft:permute_type build the group, and minecraft:spawn_event, minecraft:is_persistent and minecraft:is_experimental describe what spawns.

Three readings in that table are this project's, because Mojang states the component and not the rule. A condition that names neither liquid refuses a position inside one, which is what keeps cows out of the ocean. minecraft:spawns_above_block_filter scans downward, because an entity "above a block" stands on it. rarity is read as a one-in-N roll on top of the weight, which is the only reading under which a rarity of 3 makes a spawn rarer.

The spawn loop ​

Mojang's spawn cycle diagram names six steps, "check spawn conditions, find valid spawn locations, check population caps, evaluate spawn weight, spawn entity, and run spawn event". Spawner.tick(tick) runs them for every pool whose cadence falls on that tick, and Spawner.cycle(pool, tick) runs one pool on demand.

One cycle of one pool:

  1. Read the pool's cap. A per_player cap multiplies by the players in the region; a per_region cap does not. A pool with no cap, which is the pillager pool, skips the check.
  2. For each player, sample chunksPerCycle chunks inside spawnRadiusChunks.
  3. In each chunk, try positionsPerChunk positions for the surface pass, where Y is SpawnWorld.surfaceY, and the same number for the underground pass, where Y is drawn between SpawnWorld.minY and the surface.
  4. At each position, collect every condition of every rule in the pool that passes, draw one weighted by minecraft:weight.default, then apply its rarity roll.
  5. Draw a herd size inside the chosen minecraft:herd alternative, place the first member at the position and the rest within herdRadius, following the terrain on the surface pass. Reject each member within minimumSpawnDistance of any player or inside that distance from the current world spawn.
  6. Give each member its entity type and spawn event. minecraft:permute_type swaps the type, taking its min_guaranteed members first and drawing the rest by weight, and the minecraft:pillager<minecraft:spawn_as_patrol_follower> form splits into a type and an event. The event is initial_event for the first initial_event_count members, then event for every member past event_skip_count, then the permutation's own event, then minecraft:spawn_event.
  7. Stop as soon as the pool reaches its cap, mid-herd if that is where the cap falls.

despawnReason carries the two rules that belong to the population rather than to an entity: the published Y floor of -128, and the edge of the simulated region. The per-entity policy is minecraft:despawn in @jsprismarine/entities, which this package does not duplicate.

The injected seams ​

SpawnWorld is the one interface the loop reads the world through, so a test drives the whole algorithm with a typed double and a server implements it once.

  • site(flag, at) answers the six site facts, each named by the component or filter test that reads it: surface, underground, underwater, lava, bubble_column and snow_covered.
  • block(at), light(at), biomeTags(at) and biome(at) answer one position.
  • surfaceY(x, z) and minY() give the two passes their Y.
  • players() and worldSpawn() answer the player and world-spawn distances. poolCount(pool) and typeCount(identifier, at, radius) answer the caps and the density limit.
  • difficulty(), weather(), age(), mobEventActive(event) and villageBorderDistance(at) answer the rest.

RandomSource from @jsprismarine/predicates is the only source of randomness, so one seed reproduces one set of spawns. SpawnDelays holds the minecraft:delay_filter cooldowns and a caller can persist it across a restart. SpawnConstants replaces the numbers below.

Which numbers Mojang publishes ​

Mojang documents the pool names and every component's parameters, but the spawn-rule data has no field for the algorithm's attempt rate, population caps, sampling radius, herd placement, or density radius. It also does not state which light value minecraft:brightness_filter compares or what adjust_for_weather does to it. The research note docs/research/bedrock-entities-spawning-loot-trading.md section 4 lists the gaps one by one.

The one place numbers appear is the "Typical Cap" column of EntitySpawningDeepDive.md, and every entry there is hedged with a tilde: animal "~10 per player", monster "~70 in loaded chunks", water_animal "~5 per water body", water_ambient "~20 per water body", ambient "~15 in caves", pillager "Limited by patrols".

Most numbers this package uses are this project's choices. They live in src/tables/spawnConstants.json rather than in code, each with a source string, so a reader can judge them and a host can replace the whole table through SpawnerOptions.constants.

The minimum spawn distance is the exception. Java 26.3's NaturalSpawner rejects spawn positions at or within 24 blocks of a player and inside 24 blocks of the shared world spawn in its dimension. The spawner reads this radius from the same JSON table and checks every herd member as well as the initial position. Mojang's Bedrock spawn-rule files do not carry this distance.

ConstantValueWhere it came from
pools.animal.cap10 per playerThe tilde-hedged "~10 per player".
pools.water_animal.cap5 per player"~5 per water body". A water body is not a quantity this server tracks, so the cap counts per player.
pools.water_ambient.cap20 per player"~20 per water body". No vanilla rule names this pool.
pools.ambient.cap15 per player"~15 in caves". Only the bat uses this pool.
pools.monster.cap70 per region"~70 in loaded chunks", so it covers the region rather than scaling with players.
pools.cat.cap5 per regionMojang says only that cat limits are "based upon the amount within a village" and gives no number.
pools.pillager.capnone"Limited by patrols", so minecraft:delay_filter and minecraft:mob_event_filter gate it instead.
pools.*.cycleTicks400 for the calm pools, 20 for monsters and pillagers, 1200 for catsMojang publishes no rate. Java's animal pass runs every 400 ticks and its monster pass every tick; 20 is this project's cheaper monster cadence.
spawnRadiusChunks4Bedrock's documented default simulation distance, because the ticking area documentation says spawning happens "in a radius centered on a player".
minimumSpawnDistance24 blocksJava 26.3's NaturalSpawner.isRightDistanceToPlayerAndSpawnPoint; excludes near-player and near-world-spawn positions.
chunksPerCycle, positionsPerChunk8 and 3This project's budget, picked so one player in an empty plains biome reaches the animal cap within a few cycles.
herdRadius5 blocksJava's horizontal pack spread.
densityRadius16 blocksOne chunk's width, as this project's reading of the "certain locations" the density limit talks about.
rainDarkening, thunderDarkening5 and 10Java's Level.getSkyDarken subtracts these under rain and thunder.
despawnRadiusChunks8The 128 blocks of minecraft:despawn.despawn_from_distance.max_distance, the one published spawning distance.
despawnFloorY-128Published, and the same in both editions.

The project chose Bedrock's model over Java's deliberately. docs/plans/data-driven-vanilla.md section 12 decision 3 records why: Java's model is implementable and invisible to a Bedrock client, and it would break every farm a Bedrock player has built.

Measured coverage ​

Against the composed vanilla behavior pack of Bedrock Dedicated Server 1.26.51.1, through the corpus test in src/vanillaSpawnRules.test.ts:

MeasureResult
Spawn rule files composed60
Files that parse with no diagnostic60
Condition components the schema declares24, all parsed
Condition components vanilla writes21, all evaluated
Population pools in vanillaanimal 27, monster 24, water_animal 5, pillager 2, cat 1, ambient 1
Rules with no conditions4: blaze, cat, pillager, wither skeleton
Biome filter tests left unanswered by the spawn filter context0

The corpus test needs the sources that pnpm --filter @jsprismarine/bedrock-data run fetch:sources caches and runs only with JSP_VANILLA_SPAWN_RULES set:

sh
JSP_VANILLA_SPAWN_RULES=1 pnpm --filter @jsprismarine/spawning exec vitest run src/vanillaSpawnRules.test.ts

What a later agent adds ​

  • The four rules with no conditions. Blaze, cat, pillager and wither skeleton register a pool and leave placement to engine code: fortress spawns, village cats and patrol placement. This package spawns them wherever the pool cycle looks, which is wrong for all four.
  • Structure-based spawn selection. When the world supplies Java structure data, the spawner suppresses a rule candidate if Java reserves that entity type exclusively for structure overrides and the candidate is outside every matching structure. This keeps guardians out of ordinary ocean water while leaving entities also listed in Java biome spawn tables eligible outside structures. Structure overrides do not yet create spawn attempts or replace the biome category's weighted selection.
  • Measuring the constants. Every number in the table above is replaceable, and a capture against a running BDS would turn the guesses into measurements.

Classes ​

Interfaces ​

AboveBlockFilter ​

Defined in: rules.ts:129

The minecraft:spawns_above_block_filter body, which no vanilla rule writes.

Properties ​

blocks ​

readonly blocks: readonly string[]

Defined in: rules.ts:130

distance ​

readonly distance: number

Defined in: rules.ts:131


DespawnCandidate ​

Defined in: despawn.ts:21

One entity the population cull looks at.

Properties ​

persistent? ​

readonly optional persistent?: boolean

Defined in: despawn.ts:24

Whether minecraft:persistent or a name tag keeps the entity loaded.

position ​

readonly position: SpawnPosition

Defined in: despawn.ts:22


EngineSpawnContext ​

Defined in: engineRules.ts:24

What an engine rule reads besides the position it is deciding.

Properties ​

random ​

readonly random: RandomSource

Defined in: engineRules.ts:27

The spawner's own source, so one seed still reproduces one set of spawns.

world ​

readonly world: SpawnWorld

Defined in: engineRules.ts:25


HerdRule ​

Defined in: rules.ts:89

One minecraft:herd alternative: how many spawn together and which events they run.

Properties ​

event? ​

readonly optional event?: string

Defined in: rules.ts:96

The event every member past eventSkipCount runs.

eventSkipCount ​

readonly eventSkipCount: number

Defined in: rules.ts:97

initialEvent? ​

readonly optional initialEvent?: string

Defined in: rules.ts:93

The event the first initialEventCount members run instead of their spawn event.

initialEventCount ​

readonly initialEventCount: number

Defined in: rules.ts:94

maxSize ​

readonly maxSize: number

Defined in: rules.ts:91

minSize ​

readonly minSize: number

Defined in: rules.ts:90


PlayerInVillageFilter ​

Defined in: rules.ts:123

The minecraft:player_in_village_filter body.

Properties ​

distance ​

readonly distance: number

Defined in: rules.ts:124

villageBorderTolerance ​

readonly villageBorderTolerance: number

Defined in: rules.ts:125


PoolConstants ​

Defined in: constants.ts:19

One pool's cap, cadence and the provenance of both.

Properties ​

cap ​

readonly cap: number | null

Defined in: constants.ts:21

The cap, or null for a pool the documentation leaves to other machinery.

cycleTicks ​

readonly cycleTicks: number

Defined in: constants.ts:24

How many ticks pass between two spawn cycles of this pool.

scope ​

readonly scope: PoolCapScope

Defined in: constants.ts:22

source ​

readonly source: string

Defined in: constants.ts:26

Where the two numbers came from, quoted so a reader can judge them.


SpawnCondition ​

Defined in: rules.ts:139

One member of conditions: a complete alternative set of requirements with its own weight, herd and permutations. A rule passes at a position when any one of its conditions does.

Properties ​

aboveBlocks? ​

readonly optional aboveBlocks?: AboveBlockFilter

Defined in: rules.ts:161

biomeFilter? ​

readonly optional biomeFilter?: Filter

Defined in: rules.ts:141

blocks? ​

readonly optional blocks?: readonly string[]

Defined in: rules.ts:158

The blocks the position may stand on; an empty list means the component is absent.

brightness? ​

readonly optional brightness?: object

Defined in: rules.ts:142

adjustForWeather ​

readonly adjustForWeather: boolean

max ​

readonly max: number

min ​

readonly min: number

delay? ​

readonly optional delay?: SpawnDelay

Defined in: rules.ts:164

density? ​

readonly optional density?: object

Defined in: rules.ts:148

How many of this entity may already stand nearby, per pass; -1 is no limit.

surface ​

readonly surface: number

underground ​

readonly underground: number

difficulty? ​

readonly optional difficulty?: object

Defined in: rules.ts:143

max ​

readonly max: "normal" | "peaceful" | "easy" | "hard"

min ​

readonly min: "normal" | "peaceful" | "easy" | "hard"

disallowSpawnsInBubble ​

readonly disallowSpawnsInBubble: boolean

Defined in: rules.ts:154

distance? ​

readonly optional distance?: SpawnRange

Defined in: rules.ts:146

How far from the nearest player the position must be.

height? ​

readonly optional height?: SpawnRange

Defined in: rules.ts:144

herd ​

readonly herd: readonly HerdRule[]

Defined in: rules.ts:162

isExperimental ​

readonly isExperimental: boolean

Defined in: rules.ts:156

isPersistent ​

readonly isPersistent: boolean

Defined in: rules.ts:155

mobEvent? ​

readonly optional mobEvent?: string

Defined in: rules.ts:165

permutations? ​

readonly optional permutations?: readonly SpawnPermutation[]

Defined in: rules.ts:163

playerInVillage? ​

readonly optional playerInVillage?: PlayerInVillageFilter

Defined in: rules.ts:168

preventedBlocks? ​

readonly optional preventedBlocks?: readonly string[]

Defined in: rules.ts:160

The blocks the position may not stand on.

spawnEvent? ​

readonly optional spawnEvent?: string

Defined in: rules.ts:167

The event a spawned entity runs instead of minecraft:entity_spawned.

spawnsLava ​

readonly spawnsLava: boolean

Defined in: rules.ts:153

spawnsOnSurface ​

readonly spawnsOnSurface: boolean

Defined in: rules.ts:150

spawnsUnderground ​

readonly spawnsUnderground: boolean

Defined in: rules.ts:151

spawnsUnderwater ​

readonly spawnsUnderwater: boolean

Defined in: rules.ts:152

weight ​

readonly weight: SpawnWeight

Defined in: rules.ts:140

worldAge? ​

readonly optional worldAge?: SpawnRange

Defined in: rules.ts:149


SpawnConditionContext ​

Defined in: conditions.ts:67

Everything one condition evaluation needs beyond the condition and the position.

Properties ​

constants? ​

readonly optional constants?: SpawnConstants

Defined in: conditions.ts:74

delays? ​

readonly optional delays?: SpawnDelayView

Defined in: conditions.ts:75

identifier ​

readonly identifier: string

Defined in: conditions.ts:70

The entity the rule spawns, which minecraft:density_limit counts.

onUnanswered? ​

readonly optional onUnanswered?: (test, reason) => void

Defined in: conditions.ts:77

Receives every biome filter test the evaluator could not answer.

Parameters ​
test ​

FilterTest

reason ​

"unknownTest" | "missingSubject" | "missingFact"

Returns ​

void

random ​

readonly random: RandomSource

Defined in: conditions.ts:71

tick ​

readonly tick: number

Defined in: conditions.ts:73

The current world tick, which minecraft:delay_filter compares.

world ​

readonly world: SpawnWorld

Defined in: conditions.ts:68


SpawnConditionResult ​

Defined in: conditions.ts:26

What one condition evaluation produced.

Properties ​

passed ​

readonly passed: boolean

Defined in: conditions.ts:27

rejectedBy? ​

readonly optional rejectedBy?: "minecraft:biome_filter" | "minecraft:brightness_filter" | "minecraft:delay_filter" | "minecraft:density_limit" | "minecraft:difficulty_filter" | "minecraft:disallow_spawns_in_bubble" | "minecraft:distance_filter" | "minecraft:height_filter" | "minecraft:herd" | "minecraft:is_experimental" | "minecraft:is_persistent" | "minecraft:mob_event_filter" | "minecraft:permute_type" | "minecraft:player_in_village_filter" | "minecraft:spawn_event" | "minecraft:spawns_above_block_filter" | "minecraft:spawns_lava" | "minecraft:spawns_on_block_filter" | "minecraft:spawns_on_block_prevented_filter" | "minecraft:spawns_on_surface" | "minecraft:spawns_underground" | "minecraft:spawns_underwater" | "minecraft:weight" | "minecraft:world_age_filter"

Defined in: conditions.ts:29

The first component that rejected the position, absent when the condition passed.


SpawnConstants ​

Defined in: constants.ts:30

The whole constants table.

Properties ​

attemptSource ​

readonly attemptSource: string

Defined in: constants.ts:45

chunksPerCycle ​

readonly chunksPerCycle: number

Defined in: constants.ts:42

How many chunks one cycle samples per player.

darkeningSource ​

readonly darkeningSource: string

Defined in: constants.ts:56

densityRadius ​

readonly densityRadius: number

Defined in: constants.ts:50

The radius minecraft:density_limit counts entities over.

densityRadiusSource ​

readonly densityRadiusSource: string

Defined in: constants.ts:51

despawnFloorY ​

readonly despawnFloorY: number

Defined in: constants.ts:60

The height at and below which every mob despawns.

despawnRadiusChunks ​

readonly despawnRadiusChunks: number

Defined in: constants.ts:58

How far from every player, in chunks, a mob is culled.

despawnSource ​

readonly despawnSource: string

Defined in: constants.ts:61

herdRadius ​

readonly herdRadius: number

Defined in: constants.ts:47

How far from the anchor, in blocks, a herd member may be placed.

herdRadiusSource ​

readonly herdRadiusSource: string

Defined in: constants.ts:48

minimumSpawnDistance? ​

readonly optional minimumSpawnDistance?: number

Defined in: constants.ts:38

Minimum natural spawn distance in blocks from players and the world spawn.

minimumSpawnDistanceSource? ​

readonly optional minimumSpawnDistanceSource?: string

Defined in: constants.ts:40

Where the minimum spawn distance came from. Optional for older custom tables.

pools ​

readonly pools: Readonly<Record<string, PoolConstants>>

Defined in: constants.ts:33

positionsPerChunk ​

readonly positionsPerChunk: number

Defined in: constants.ts:44

How many positions one cycle tries in each sampled chunk.

provenance ​

readonly provenance: string

Defined in: constants.ts:32

Where the table's values came from.

rainDarkening ​

readonly rainDarkening: number

Defined in: constants.ts:53

How much rain lowers the light an adjust_for_weather brightness filter compares.

spawnRadiusChunks ​

readonly spawnRadiusChunks: number

Defined in: constants.ts:35

How far from a player, in chunks, the spawner looks for a position.

spawnRadiusSource ​

readonly spawnRadiusSource: string

Defined in: constants.ts:36

thunderDarkening ​

readonly thunderDarkening: number

Defined in: constants.ts:55

How much a thunderstorm lowers that light.


SpawnDelay ​

Defined in: rules.ts:113

The minecraft:delay_filter body: a cooldown shared by every rule naming the same identifier.

Properties ​

identifier? ​

readonly optional identifier?: string

Defined in: rules.ts:117

The cooldown's name, which is how the three pillager patrol conditions keep separate timers.

max ​

readonly max: number

Defined in: rules.ts:115

min ​

readonly min: number

Defined in: rules.ts:114

spawnChance ​

readonly spawnChance: number

Defined in: rules.ts:119

The percent chance the attempt takes once the cooldown has elapsed.


SpawnDelayView ​

Defined in: conditions.ts:33

Reads the cooldowns minecraft:delay_filter keeps, keyed by its identifier.

Methods ​

readyAt() ​

readyAt(identifier): number | undefined

Defined in: conditions.ts:35

The tick the named cooldown next allows a spawn, or undefined when it has never run.

Parameters ​
identifier ​

string

Returns ​

number | undefined


SpawnPermutation ​

Defined in: rules.ts:101

One minecraft:permute_type entry: a weighted swap of the entity a herd member spawns as.

Properties ​

entityType? ​

readonly optional entityType?: string

Defined in: rules.ts:107

The entity to spawn instead, optionally in the type<event> form. Absent means the rule's own entity, which is how vanilla writes the common branch.

minGuaranteed ​

readonly minGuaranteed: number

Defined in: rules.ts:109

How many herd members this permutation takes before the weighted draw runs.

weight ​

readonly weight: number

Defined in: rules.ts:102


SpawnPlayer ​

Defined in: world.ts:49

One player the spawner spawns around.

Properties ​

position ​

readonly position: SpawnPosition

Defined in: world.ts:50


SpawnPosition ​

Defined in: world.ts:12

A block position. Spawn positions are integers; distances are measured between centers.

Properties ​

x ​

readonly x: number

Defined in: world.ts:13

y ​

readonly y: number

Defined in: world.ts:14

z ​

readonly z: number

Defined in: world.ts:15


SpawnRange ​

Defined in: rules.ts:75

An inclusive numeric range, as every {min, max} component writes one.

Properties ​

max ​

readonly max: number

Defined in: rules.ts:77

min ​

readonly min: number

Defined in: rules.ts:76


SpawnRequest ​

Defined in: spawner.ts:33

One entity the spawner asks the server to create.

Properties ​

identifier ​

readonly identifier: string

Defined in: spawner.ts:35

The entity type, with any <event> suffix already split off.

pass ​

readonly pass: SpawnPass

Defined in: spawner.ts:44

pool ​

readonly pool: string

Defined in: spawner.ts:41

The pool whose cap this spawn counts against.

position ​

readonly position: SpawnPosition

Defined in: spawner.ts:39

The block position whose center the host uses to place the entity.

rule ​

readonly rule: string

Defined in: spawner.ts:43

The rule that produced the spawn, which is the identifier of its file.

spawnEvent? ​

readonly optional spawnEvent?: string

Defined in: spawner.ts:37

The event to run instead of minecraft:entity_spawned, when the rule names one.


SpawnRule ​

Defined in: rules.ts:172

One parsed spawn_rules/*.json.

Properties ​

conditions ​

readonly conditions: readonly SpawnCondition[]

Defined in: rules.ts:177

formatVersion? ​

readonly optional formatVersion?: string

Defined in: rules.ts:176

identifier ​

readonly identifier: string

Defined in: rules.ts:173

populationControl? ​

readonly optional populationControl?: string

Defined in: rules.ts:175

The pool whose cap gates this entity, absent when the file names none.


SpawnRuleParseOptions ​

Defined in: rules.ts:181

Where a parse reports its findings.

Properties ​

pack ​

readonly pack: string

Defined in: rules.ts:183

The pack the file came from, used in the diagnostics.

path? ​

readonly optional path?: string

Defined in: rules.ts:184

report? ​

readonly optional report?: (diagnostic) => void

Defined in: rules.ts:185

Parameters ​
diagnostic ​

Diagnostic

Returns ​

void


SpawnWeight ​

Defined in: rules.ts:81

How often one condition is drawn against the others that pass at the same position.

Properties ​

default ​

readonly default: number

Defined in: rules.ts:83

The relative weight; a weight of 100 among a total of 1000 is drawn a tenth of the time.

rarity ​

readonly rarity: number

Defined in: rules.ts:85

An extra rarity roll Mojang documents by name only. Zero means no roll.


SpawnWorld ​

Defined in: world.ts:54

Everything one spawn cycle reads about the world.

Methods ​

age() ​

age(): number

Defined in: world.ts:103

The world's age in ticks, which is what minecraft:world_age_filter compares.

Returns ​

number

biome()? ​

optional biome(at): string

Defined in: world.ts:80

The biome name at one position, for is_biome.

Parameters ​
at ​

SpawnPosition

Returns ​

string

biomeTags() ​

biomeTags(at): readonly string[]

Defined in: world.ts:78

The biome tags at one position, which is what has_biome_tag compares.

Parameters ​
at ​

SpawnPosition

Returns ​

readonly string[]

block() ​

block(at): string | undefined

Defined in: world.ts:61

The block identifier at one position, or undefined when the chunk is not loaded, which stops the attempt.

Parameters ​
at ​

SpawnPosition

Returns ​

string | undefined

difficulty() ​

difficulty(): "normal" | "peaceful" | "easy" | "hard"

Defined in: world.ts:100

Returns ​

"normal" | "peaceful" | "easy" | "hard"

light() ​

light(at): number

Defined in: world.ts:76

The light level at one position, 0 to 15, before this package applies the weather darkening that adjust_for_weather asks for.

Parameters ​
at ​

SpawnPosition

Returns ​

number

minY() ​

minY(): number

Defined in: world.ts:88

The lowest y the world generates, which bounds the underground pass.

Returns ​

number

mobEventActive() ​

mobEventActive(event): boolean

Defined in: world.ts:105

Whether a named mob event, such as minecraft:pillager_patrols_event, is running.

Parameters ​
event ​

string

Returns ​

boolean

players() ​

players(): readonly SpawnPlayer[]

Defined in: world.ts:90

The players the spawner spawns around, which is every player in the spawn region.

Returns ​

readonly SpawnPlayer[]

poolCount() ​

poolCount(pool): number

Defined in: world.ts:97

How many entities of one population pool stand in the spawn region now.

Parameters ​
pool ​

string

Returns ​

number

site() ​

site(flag, at): boolean

Defined in: world.ts:56

A boolean fact about one position, named by the component that reads it.

Parameters ​
flag ​

"lava" | "bubble_column" | "surface" | "underground" | "underwater" | "snow_covered"

at ​

SpawnPosition

Returns ​

boolean

solid() ​

solid(at): boolean

Defined in: world.ts:71

Whether the block at one position stops an entity standing in it.

The underground pass draws a y uniformly between the world floor and the surface, so most of what it draws is inside rock. Java rejects such a draw in NaturalSpawner.isSpawnPositionOk; without this the spawner puts a zombie inside a stone block, where it can path nowhere and never despawns.

Parameters ​
at ​

SpawnPosition

Returns ​

boolean

structureSpawnOverrideAt()? ​

optional structureSpawnOverrideAt(identifier, at): boolean | undefined

Defined in: world.ts:121

Whether Java restricts this entity type to a structure spawn override at this position.

false means the Java data declares at least one structure override for the entity, but this position is outside every active override. true means a matching override covers this position. undefined means Java's biome data also permits this entity to spawn outside structures, or that the world has no Java override data for it, so the spawn rule decides as usual.

Parameters ​
identifier ​

string

at ​

SpawnPosition

Returns ​

boolean | undefined

surfaceY() ​

surfaceY(x, z): number | undefined

Defined in: world.ts:86

The lowest y an entity may stand on in one column, which is the position the surface pass tries. Undefined when the column is not loaded, which skips the attempt.

Parameters ​
x ​

number

z ​

number

Returns ​

number | undefined

typeCount() ​

typeCount(identifier, at, radius): number

Defined in: world.ts:99

How many entities of one type stand within radius blocks of a position.

Parameters ​
identifier ​

string

at ​

SpawnPosition

radius ​

number

Returns ​

number

villageBorderDistance()? ​

optional villageBorderDistance(at): number | undefined

Defined in: world.ts:111

How far a position is from the nearest village border, negative inside it and undefined when no village is near. minecraft:player_in_village_filter reads it.

Parameters ​
at ​

SpawnPosition

Returns ​

number | undefined

weather() ​

weather(): "thunder" | "clear" | "rain"

Defined in: world.ts:101

Returns ​

"thunder" | "clear" | "rain"

worldSpawn()? ​

optional worldSpawn(): SpawnPosition | undefined

Defined in: world.ts:95

The shared world spawn in this dimension, when one applies. Java's exclusion only applies in the dimension that owns this spawn point.

Returns ​

SpawnPosition | undefined


SpawnerOptions ​

Defined in: spawner.ts:48

How to build a Spawner.

Properties ​

constants? ​

readonly optional constants?: SpawnConstants

Defined in: spawner.ts:52

delays? ​

readonly optional delays?: SpawnDelays

Defined in: spawner.ts:54

The minecraft:delay_filter cooldowns, so a caller can persist them across a restart.

engineRules? ​

readonly optional engineRules?: ReadonlyMap<string, EngineSpawnRule>

Defined in: spawner.ts:60

The conditions Bedrock keeps in engine code, keyed by the entity each one gates. Defaults to VANILLA_ENGINE_SPAWN_RULES; pass an empty map to run the JSON conditions alone.

onUnanswered? ​

readonly optional onUnanswered?: (test, reason) => void

Defined in: spawner.ts:62

Receives every biome filter test the evaluator could not answer.

Parameters ​
test ​

FilterTest

reason ​

"unknownTest" | "missingSubject" | "missingFact"

Returns ​

void

random ​

readonly random: RandomSource

Defined in: spawner.ts:51

rules ​

readonly rules: Iterable<SpawnRule>

Defined in: spawner.ts:49

world ​

readonly world: SpawnWorld

Defined in: spawner.ts:50

Type Aliases ​

DespawnReason ​

DespawnReason = "below_floor" | "simulation_edge"

Defined in: despawn.ts:18

Why one entity despawned.


Difficulty ​

Difficulty = typeof DIFFICULTIES[number]

Defined in: rules.ts:35

One of DIFFICULTIES.


EngineSpawnRule ​

EngineSpawnRule = (at, context) => boolean

Defined in: engineRules.ts:36

One entity's engine-side spawn condition.

Parameters ​

at ​

SpawnPosition

context ​

EngineSpawnContext

Returns ​

boolean

Whether the entity may spawn at the position, with the entity's spawn_rules/*.json conditions already satisfied.


PoolCapScope ​

PoolCapScope = "per_player" | "per_region"

Defined in: constants.ts:16

Whether a pool's cap covers the whole spawn region or scales with the players in it.


PopulationPool ​

PopulationPool = typeof POPULATION_POOLS[number]

Defined in: rules.ts:29

One of POPULATION_POOLS.


SpawnPass ​

SpawnPass = "surface" | "underground"

Defined in: world.ts:40

Which of the two passes a position belongs to.


SpawnRuleComponent ​

SpawnRuleComponent = typeof SPAWN_RULE_COMPONENTS[number]

Defined in: rules.ts:72

One of SPAWN_RULE_COMPONENTS.


SpawnSiteFlag ​

SpawnSiteFlag = typeof SPAWN_SITE_FLAGS[number]

Defined in: world.ts:37

One of SPAWN_SITE_FLAGS.


SpawnWeather ​

SpawnWeather = typeof SPAWN_WEATHER[number]

Defined in: world.ts:46

One of SPAWN_WEATHER.

Variables ​

DIFFICULTIES ​

const DIFFICULTIES: readonly ["peaceful", "easy", "normal", "hard"]

Defined in: rules.ts:32

The difficulty names minecraft:difficulty_filter compares, in ascending order.


MOON_BRIGHTNESS ​

const MOON_BRIGHTNESS: readonly number[]

Defined in: engineRules.ts:117

How bright the moon is at each of its eight phases, starting at the full moon. The swamp branch of the slime rule draws against this number, so a swamp spawns no slimes at all on a new moon.


POPULATION_POOLS ​

const POPULATION_POOLS: readonly ["animal", "water_animal", "water_ambient", "ambient", "monster", "cat", "pillager", "villager"]

Defined in: rules.ts:17

The pools description.population_control names, each with its own cap.


SLIME_SURFACE_BIOME_TAG ​

const SLIME_SURFACE_BIOME_TAG: "spawns_slimes_on_surface" = 'spawns_slimes_on_surface'

Defined in: engineRules.ts:151

The biome tag the swamp branch reads. Three vanilla biomes carry it: swampland, swampland_mutated and mangrove_swamp.


SPAWN_CONSTANTS ​

const SPAWN_CONSTANTS: Required<SpawnConstants>

Defined in: constants.ts:70

The default spawning values, read from src/tables/spawnConstants.json. A host replaces the table through SpawnerOptions.constants.


SPAWN_RULE_COMPONENTS ​

const SPAWN_RULE_COMPONENTS: readonly ["minecraft:biome_filter", "minecraft:brightness_filter", "minecraft:delay_filter", "minecraft:density_limit", "minecraft:difficulty_filter", "minecraft:disallow_spawns_in_bubble", "minecraft:distance_filter", "minecraft:height_filter", "minecraft:herd", "minecraft:is_experimental", "minecraft:is_persistent", "minecraft:mob_event_filter", "minecraft:permute_type", "minecraft:player_in_village_filter", "minecraft:spawn_event", "minecraft:spawns_above_block_filter", "minecraft:spawns_lava", "minecraft:spawns_on_block_filter", "minecraft:spawns_on_block_prevented_filter", "minecraft:spawns_on_surface", "minecraft:spawns_underground", "minecraft:spawns_underwater", "minecraft:weight", "minecraft:world_age_filter"]

Defined in: rules.ts:44

Every condition component Spawn Rules.json declares, in the schema's order. Vanilla writes 21 of the 24; minecraft:spawns_above_block_filter, minecraft:is_persistent and minecraft:is_experimental appear in the schema alone, so this package parses them and leaves their meaning to the caller.


SPAWN_SITE_FLAGS ​

const SPAWN_SITE_FLAGS: readonly ["surface", "underground", "underwater", "lava", "bubble_column", "snow_covered"]

Defined in: world.ts:27

The boolean facts about one position, each named by the rule component or filter test that reads it.

surface and underground select the pass; underwater and lava are the medium the position sits in; bubble_column answers minecraft:disallow_spawns_in_bubble; snow_covered answers the one is_snow_covered test a vanilla biome filter writes.


SPAWN_WEATHER ​

const SPAWN_WEATHER: readonly ["clear", "rain", "thunder"]

Defined in: world.ts:43

The weather names adjust_for_weather reads.


VANILLA_ENGINE_SPAWN_RULES ​

const VANILLA_ENGINE_SPAWN_RULES: ReadonlyMap<string, EngineSpawnRule>

Defined in: engineRules.ts:188

Every engine rule vanilla needs, keyed by the entity it gates.

import('./spawner').Spawner applies these by default. A host that wants a different set passes its own map, and a host that wants none passes an empty one.


slimeSpawnRule ​

const slimeSpawnRule: EngineSpawnRule

Defined in: engineRules.ts:167

Where a slime may spawn, which spawn_rules/slime.json does not say.

Two branches, as Bedrock writes them. At Y 38 and below the position has to be in a slime chunk and nothing else is asked, which is why a slime farm is dug out rather than lit up. Above that the position has to be in a swamp between Y 50 and Y 68, dark enough, and lucky against the moon phase. Everything in between, and every lit surface, spawns no slimes at all.

The one divergence from the Bedrock function is the position the biome tag is read at. Bedrock reads it one block higher than the spawn position; this reads it at the spawn position, because a biome boundary is the only place the two can differ and neither answer is more correct there.

Functions ​

cycleTicksFor() ​

cycleTicksFor(pool, constants?): number | undefined

Defined in: constants.ts:91

How many ticks pass between two spawn cycles of one pool.

Parameters ​

pool ​

string

constants? ​

SpawnConstants = SPAWN_CONSTANTS

Returns ​

number | undefined


despawnReason() ​

despawnReason(candidate, world, constants?): DespawnReason | undefined

Defined in: despawn.ts:38

Decides whether one entity leaves the world for a population reason.

The Y floor is published and is the same in both editions: every mob despawns at Y=-128 and below. The simulation edge is not published; this project uses despawnRadiusChunks on the X and Z axes, whose default of 8 chunks is the 128 blocks of minecraft:despawn.despawn_from_distance.max_distance.

Parameters ​

candidate ​

DespawnCandidate

world ​

SpawnWorld

constants? ​

SpawnConstants = SPAWN_CONSTANTS

Returns ​

DespawnReason | undefined

The reason, or undefined when the entity stays.


distanceSquared() ​

distanceSquared(from, to): number

Defined in: world.ts:125

The squared distance between two positions, which is what the range checks compare.

Parameters ​

from ​

SpawnPosition

to ​

SpawnPosition

Returns ​

number


evaluateSpawnCondition() ​

evaluateSpawnCondition(condition, at, context, requestedPass?): SpawnConditionResult

Defined in: conditions.ts:168

Decides whether one condition allows a spawn at a position.

The components run cheapest first, and the first one that rejects names itself in the result. A condition that declares neither minecraft:spawns_underwater nor minecraft:spawns_lava refuses a position inside either liquid, which is the reading that keeps land mobs out of the ocean; Mojang states the components and not that rule.

Parameters ​

condition ​

SpawnCondition

at ​

SpawnPosition

context ​

SpawnConditionContext

requestedPass? ​

SpawnPass

The pass the spawn loop is evaluating, or absent to derive it from the world's site facts.

Returns ​

SpawnConditionResult


horizontalDistanceSquared() ​

horizontalDistanceSquared(from, to): number

Defined in: world.ts:136

The squared distance between two positions on the X and Z axes alone, which is what a chunk radius such as the simulation distance measures.

Parameters ​

from ​

SpawnPosition

to ​

SpawnPosition

Returns ​

number


isSlimeChunk() ​

isSlimeChunk(chunkX, chunkZ): boolean

Defined in: engineRules.ts:98

Whether a chunk is a slime chunk.

Bedrock seeds a Mersenne twister with chunkX * 0x1f1f1f1f ^ chunkZ and takes its first draw modulo ten. The world seed is not part of it, which is why a Bedrock slime farm sits at the same chunk coordinates in every world and why Java's seeded formula is the wrong answer here.

Parameters ​

chunkX ​

number

The chunk's X coordinate, which is a block X shifted right by four.

chunkZ ​

number

The chunk's Z coordinate.

Returns ​

boolean


moonPhase() ​

moonPhase(time): number

Defined in: engineRules.ts:125

The moon phase at one world time.

Parameters ​

time ​

number

The world's age in ticks, which is never negative on a running server.

Returns ​

number

A phase from 0, the full moon, to 7.


parseSpawnRule() ​

parseSpawnRule(file, options): SpawnRule | undefined

Defined in: rules.ts:391

Parses one spawn_rules/*.json file.

Parameters ​

file ​

unknown

options ​

SpawnRuleParseOptions

Returns ​

SpawnRule | undefined

The rule, or undefined when the file is not a spawn rule or names no identifier. Everything else loads and reports.


passAt() ​

passAt(world, at): SpawnPass

Defined in: world.ts:143

Which pass a position belongs to, which the world decides and the conditions read.

Parameters ​

world ​

SpawnWorld

at ​

SpawnPosition

Returns ​

SpawnPass


poolCapFor() ​

poolCapFor(pool, players, constants?): number | undefined

Defined in: constants.ts:80

The cap one pool is allowed in the spawn region right now.

Parameters ​

pool ​

string

players ​

number

How many players the spawn region holds, which scales a per_player cap.

constants? ​

SpawnConstants = SPAWN_CONSTANTS

Returns ​

number | undefined

The cap, or undefined when the pool has none and other machinery limits it.


spawnFilterContext() ​

spawnFilterContext(world, at): FilterContext

Defined in: conditions.ts:93

Builds the filter context a minecraft:biome_filter reads.

A spawn rule has no entity yet, so the self subject is the position: its biome tags answer has_biome_tag, its biome answers is_biome, and its site flags answer is_snow_covered, is_underground, is_underwater and in_lava. Every other test the shared grammar allows goes unanswered and is reported, which is what the engine does for a fact it cannot establish.

Parameters ​

world ​

SpawnWorld

at ​

SpawnPosition

Returns ​

FilterContext