Skip to content

Spawning

github-actions[bot] edited this page Aug 4, 2026 · 1 revision

Spawning

Where NeroCreatures put themselves, why nothing appears on Earth, and every lever a server owner has over it.

The short version: creatures spawn on off-Earth biomes, chosen by Neroland Core's neroland:space/* biome tags. With no planet mod installed those tags are empty, so nothing spawns anywhere. That is by design, not a bug.

Earth stays quiet

NeroCreatures does not touch vanilla biomes at all. Every creature is placed against a Core space biome tag, and those tags start out empty: Core ships them with "required": false entries for planets that may or may not be present (Nerospace's worlds, Ad Astra's), so on a server with no planet mod installed every tag has no members and every spawn rule matches nowhere.

Nothing special-cases the Overworld. It is simply not in the data.

Tag What belongs in it
neroland:space/dark_biomes Dim, sunless or ash-choked worlds
neroland:space/moon_biomes Airless, low-gravity moons
neroland:space/crystalline_biomes Crystal fields and glass plains
neroland:space/asteroid_biomes Rubble fields and asteroid belts
neroland:space/planet_biomes The umbrella: every off-Earth surface

A pack can add its own biomes to any of these with an ordinary datapack tag file — that is the supported way to make NeroCreatures spawn on a planet it has never heard of.

The spawn table

Every line is declared in code, not in a datapack, and the whole table is public:

Creature Biome tag Weight Group
Void Crawler dark_biomes 30 1–2
Lunar Stalker moon_biomes 24 2–4
Plasma Slime crystalline_biomes 20 1–3
Plasma Slime dark_biomes 8 1–2
Xertz Forager crystalline_biomes 14 1–3
Glacite Wisp moon_biomes 12 1–2
Glacite Wisp crystalline_biomes 6 1–2
Space Pirate planet_biomes 10 2–3
Crystal Golem crystalline_biomes 8 1
Asteroid Worm asteroid_biomes 6 1
Rogue Drone dark_biomes 6 1–2
Rogue Android dark_biomes 3 1
Cinder Tyrant dark_biomes 1 1 (gated — see Bosses)
Terraforming Drone never spawns; it is deployed

Weights are local, not global. A candidate position only ever picks between the rules that apply there, so the Asteroid Worm's weight of 6 competes with nothing at all in an asteroid field — it is the only line in that tag. Compare weights within a column, never across the table.

No dimension guard. Every line is biome-tagged only. A dimension guard would silently exclude any planet that reuses a vanilla dimension type — Nerospace's Greenxertz reuses minecraft:overworld, which cannot be tagged without dragging the real Overworld in with it — and no vanilla Earth biome is a member of any neroland:space/* tag, so the guard would cost a planet and buy nothing.

How placement works

NeroCreatures runs its own placement sweep on the server tick rather than adding entries to biome spawn settings. That is a deliberate portability decision: NeoForge does biome modification with JSON modifiers, Forge with an event and Fabric with the Fabric API, and splitting the most gameplay-visible behaviour in the mod across three data systems is the fastest way to make six build targets behave differently.

The sweep is shaped to feel like vanilla's:

  • Player-anchored. Candidates are drawn in a ring 24–48 blocks around a player — far enough not to pop into view, close enough to matter. (Vanilla uses the same 24-block floor.)
  • Budgeted. One sweep every 40 ticks (twice a second), at most 8 players considered per level, at most 3 candidate positions each, and at most 2 groups actually placed per level per sweep. The worst case is a small fixed number of heightmap reads and tag tests, and it does not grow with world size.
  • Vanilla placement rules. Each candidate goes through the same "is this a legal spawn position" and "do this creature's spawn rules pass" checks vanilla uses, plus a collision check — so light levels, block validity and difficulty behave exactly as they do for a vanilla mob. Peaceful stops everything, including the harmless pets.
  • Capped at placement time, not cleaned up afterwards.

Population caps

Two caps, both counted from what is loaded, both checked before anything is placed.

Setting Default What it means
maxCreaturesPerChunk 8 Most NeroCreatures allowed in one chunk column
maxCreaturesPerDimension 200 Most NeroCreatures loaded in one dimension

Set either to 0 and NeroCreatures stops existing in that scope — a legitimate way to disable the mod's spawning without disabling the mod.

The dimension count is deliberately bounded and cached: it stops counting at the cap and says nothing about how far past it a world might be, because the only question anyone asks of it is "is there room?". It is cached for one second per dimension, so a sweep costs roughly one query.

Caps count two class roots — the mod's own creature base and the tameable pets, which derive from vanilla's TamableAnimal instead. A wild pet is inside the caps exactly like a monster.

Everything that is placed on purpose is persistent and never despawns: bosses, structure placements, event waves, tamed pets and deployed drones. Everything that spawned naturally despawns like a vanilla monster, which is what lets the population come back down.

Configuration

All of these live in config/nerocreatures.properties and are server-authoritative — hot-reloadable with /neroland config reload.

Key Default Effect
spawnsEnabled true Master switch for the sweep
globalSpawnWeightMultiplier 1.0 Scales every weight; 0.0 stops all spawning
maxCreaturesPerChunk 8 Per-chunk cap
maxCreaturesPerDimension 200 Per-dimension cap
hostileAggressionMultiplier 1.0 Attack damage and follow range, applied once at spawn
naturalBossSpawnsEnabled true Whether a boss may appear on its own — see Bosses
maxPetsPerPlayer 3 See Pets & Drones
maxDronesPerPlayer 2 See Pets & Drones

Use /nerocreatures caps to see the caps and what is currently using them, and /nerocreatures list for the roster with live counts in your dimension.

For event mods: InvasionBudget

NeroCreatures ships a public helper, spawn/InvasionBudget, for a mod that wants to put a wave of creatures into a world — a NeroEvents raid, for instance. Nothing in NeroCreatures 0.1.0 uses it; it exists so the mod that needs it does not have to reach around the caps to get it.

InvasionBudget.Handle wave = InvasionBudget.reserve(level, 12);
InvasionBudget.spawnWithin(wave, ModEntities.SPACE_PIRATE.get(), pos);   // up to 12 times
// …the event runs…
InvasionBudget.close(wave);                                              // the world is tidy again

The budget is an allowance, not a bypass. A wave may push a dimension temporarily above maxCreaturesPerDimension, by at most the reserved budget, because an event that has to wait for wandering monsters to despawn is not an event. Everything else still applies:

  • maxCreaturesPerChunk is never exceeded — the dimension cap protects the server, the chunk cap protects the player standing in that chunk.
  • A cap of 0 means zero. A server that has turned NeroCreatures spawning off does not get a wave.
  • The budget is spent per successful spawn, whether or not that creature survives.

Cleaning up. Closing a wave removes whatever is left of it — discard, not a kill, so an event ending does not shower the arena in loot nobody earned. Two mechanisms run:

  1. The handle remembers what it spawned and removes each one directly. Exact, works for any mob, but lives in memory.
  2. Every NeroCreatures mob in a wave also carries the wave's id in its own saved data, so InvasionBudget.sweep(level, waveId) can clear up a wave whose handle is long gone — after a crash, or in a later session.

A creature from another mod placed through the API is covered by (1) but not by (2), which is the honest limit of what NeroCreatures can promise about somebody else's entity.

A wave id identifies a batch of mobs. It is not a player id and nothing about a player is derivable from it.

See also

  • Bestiary — per-creature behaviour, drops and spawn eggs
  • Bosses — why the boss line is gated far harder than a weight
  • Pets & Drones — the two creatures that are owned rather than spawned
  • Commandslist and caps

Clone this wiki locally