Isekai API

Create custom worldgen, biomes, and dimensions with datapack JSON or Java, from floating islands to mountains.
Back to Files

isekai-api-3.0.0-neoforge-1.21.1

File nameisekai-api-3.0.0-neoforge-1.21.1.jar
Uploader
KURONAMlKURONAMl
Uploaded
Nov 15, 2026
Downloads
2
Size
857.9 KB
Mod Loaders
NeoForge
File ID
9635305
Type
R
Release
Supported game versions
  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:isekai-api-1557389:9635305"

Learn more about Curse Maven

What's new

Breaking changes

  • Mob spawn changes are dimension-scoped. exclusions.mob_spawns, additions.mob_spawns, mob_spawn_strategy and mob_spawn_strategy_by_category used to rewrite the shared biome's spawn builder; they now apply only in the descriptor's dimension. The same biome in another dimension keeps its original list.
  • Carver exclusions and additions are dimension-scoped on noise-based dimensions. exclusions.carvers and additions.carvers now apply only in the declared dimension when its generator is a NoiseBasedChunkGenerator. Dimensions with another generator keep the old biome-wide edit (see limitations).
  • Other mods' features follow the declared scope. A feature another mod adds to a declared biome is removed from the shared biome and re-injected as a guarded copy for the declaring dimension. Dimensions that do not declare the worldshape no longer receive it (ForeignFeatureReconciler).
  • Internal signatures changed (@ApiStatus.Internal, no compatibility promise): ModifyPhase.mobSpawnStrategy(WorldshapeDescriptor, Holder<Biome>), RemovePhase.excludedCarvers(WorldshapeDescriptor, ResourceKey<Biome>, …) and AddPhase.additionalCarvers(WorldshapeDescriptor, ResourceKey<Biome>, …).
  • 2.x datapacks load unchanged, but the scope changes. The same JSON now affects one dimension instead of every dimension that shares the biome. A pack that relied on the old cross-dimension leak must declare a descriptor for the other dimension.
  • ClientAtmosphereOverride gained a skyColor component. The record is now (skyColor, fogColor, fogNearDistance, fogFarDistance); the three-argument constructor is gone. Source callers pass Optional.empty() for skyColor, and compiled callers must recompile.

Added

  • Per-dimension feature drop at decoration time. ChunkGeneratorDecorationMixin redirects generationSettingsGetter.apply(biome) in ChunkGenerator#applyBiomeDecoration; DimensionFeatureScope removes the recorded takeover set for the dimension generating the chunk. The set is recorded by the ADD phase, so the drop and the injected copy always agree.
  • Final feature veto for custom generators. PlacedFeatureScopeMixin injects at PlacedFeature#placeWithContext HEAD and rejects the same takeover values, so a generator that overrides applyBiomeDecoration wholesale also honours exclusions.features, feature_predicates and ore_strategy.
  • Injected features carry isekai_api:dimension_guard. additions.features, remap copies and feature_predicates copies place only in the descriptor's dimension.
  • Structure exclusions are dimension-scoped. StructureFindValidGenerationPointMixin vetoes during generation-point search. During chunk generation the dimension comes from ChunkDimensionIndex (a weak ProtoChunk → dimension index); /locate and /place use the level directly; only an index miss falls back to matching the BiomeSource.
  • Mob spawn rules are enforced at the runtime read points. MobSpawnScope holds a per-(dimension, biome) rule. NaturalSpawner#mobsAt (RETURN) and spawnMobsForChunkGeneration (getMobs redirect) filter the list; MobSpawnVetoHandler cancels at FinalizeSpawnEvent (LOWEST) for paths that never read a list, so an exclusion also covers patrols, spawners, spawn eggs and /summon.
  • Carver rules are enforced at carve time. NoiseBasedChunkGeneratorCarverMixin redirects ChunkAccess#carverBiome in NoiseBasedChunkGenerator#applyCarvers; CarverScope applies the recorded add/remove rule per (dimension, biome).
  • client_atmosphere reaches clients on a dedicated server. The server sends the active Y-bands over the optional isekai_api:client_atmosphere channel on login, /reload and dimension change; the client applies them before falling back to its own registry, so sky and fog match what the server loaded. Vanilla clients and clients without the channel are unaffected.
  • /isekai validate dimension <id> reports the LevelStem profile (build height, sea level, default block, ceiling) and the silent failures: applies_to matching no biome, a playable_range outside the build height, unresolved biome tags, features skipped in that dimension.
  • Start-point safety in /isekai validate dimension <id>. For a dimension with a declared worldshape the report adds a spawn OK/WARN/ERROR/SKIP line: the first solid block below the start point (max 32 blocks) is the footing, the two blocks above it must be neither solid nor fluid, water is a warning, and lava, a buried start or no footing is an error. The start point is the overworld's shared spawn, or the (0,0) MOTION_BLOCKING_NO_LEAVES heightmap position for other dimensions.
  • Worldshapes can be narrowed to dimension types. dimension also accepts { "dimension": "<key>", "required_dimension_types": ["<type>", …] }; a level whose dimension_type is not listed is left alone. This lets a selectable world type keep its worldshape out of vanilla worlds that share the minecraft:overworld key. The string form and an empty list mean no restriction (the 2.x behaviour). Java: Scope (api/remap) on WorldshapeDescriptor.
  • DimensionProfile (api/query) and IsekaiQuery.getDimensionProfile(ResourceKey<Level>) expose a dimension's vertical bounds, sea level, default block/fluid and DimensionType flags before a ServerLevel exists.
  • Nether preset. isekai_api:hooked_nether (min_y 0, height 128, sea level 32, netherrack/lava defaults, legacy random source) with isekai_api:hook/final_density_nether and isekai_api:vanilla_nether_surface. The separate hook id keeps overworld overrides of hook/final_density out of the nether.
  • Dimension-scoped sky colour. client_atmosphere.sky_color (0xRRGGBB) replaces the biome sky colour while the descriptor is active, resolved per camera Y like the fog overrides. Only the sampled base colour changes: vanilla's day/night, rain/thunder and lightning-flash shading still apply. Carried by ClientLevelSkyColorMixin, so it exists on the client only, and it applies to dimensions whose effects is minecraft:overworld (the vanilla sky path).
  • isekai_api:none foliage placer. A crown of nothing, so a minecraft:tree feature can place a bare trunk without leaves. radius and offset are optional and default to 0, which makes {"type": "isekai_api:none"} valid on its own.
  • Six tree decorators. minecraft:tree's decorators array now accepts isekai_api: parts: attach_to_logs (blocks on trunk sides), ground_patch (a disc of blocks around the base, cover or replace), hang_from_leaves (strands from the crown's underside), snow_cap (snow layers on sky-facing leaves), branch_stubs (bare limbs out of the trunk, each axis following the step, block optional so it can reuse the trunk's own block) and broken_top (snaps the top count trunk blocks off, keeping at least one; optional fill_provider turns the break into basalt or charcoal instead of air). Every block is a block_provider slot, so the parts carry no species; leaf states written by a decorator are pinned on distance so they do not decay. Fields and the charred-tree example are in docs/DATAPACK_REFERENCE.md.
  • TreeGrowers (api/wood) builds the TreeGrower a sapling needs from configured feature keys — plain, mega, secondary and flower forms — with Isekai's own name convention, so a wood set does not have to hand-write the eight-argument constructor; a wood set hands the result to WoodSet.Builder#sapling.
  • Bare-tree fixture and coverage. The GameTests load a leafless, branch-bearing tree from disk through the real configured-feature registry and assert the trunk, stubs, snap and ground ring, alongside codec round-trips for the new placers and decorators. The fixture and its test wrapper classes stay out of the jar (data/isekai_api_test/**, gametest/**).
  • /isekai validate <namespace> reports missing wood-set files. For every species the namespace declares with WoodSet, it checks the loot tables, block and item tags, recipes, language keys, blockstates, models and textures that the species' parts imply, and lists each gap by kind and subject. Members that are not visible from the current side (client-only resource packs on a dedicated server) are counted as "not visible here" instead of missing. This catches a missing texture before it shows up as the purple-black checker in game.
  • A one-species example under examples/4_wood/. ExampleWoodMod declares a full wood set (log, wood, stripped variants, planks, stairs, slab, fence, gate, door, trapdoor, pressure plate, button, signs, leaves, sapling, potted sapling, boats) and its datagen; the pack beside it holds the configured feature with an isekai_api decorator. The class is compiled and the pack is loaded only on the GameTest server, and neither ships in the jar.
  • WoodSet.Builder#flammable(boolean). A set declared flammable(false) is left out of the fire odds map and its logs are data-generated into #logs instead of #logs_that_burn, so neither the logs nor the planks spread fire or burn away; WoodSet#isFlammable() reports the setting. One part cannot be turned off: every block keeps vanilla's ignited_by_lava flag from the oak properties it copies, so lava still sets it alight.
  • The wood-set audit covers sign textures. A set with sign or hanging_sign also needs textures/entity/signs/<path>.png, textures/entity/signs/hanging/<path>.png and textures/gui/hanging_signs/<path>.png, which WoodSets.signTexture and WoodSets.hangingSignGuiTexture name. The example pack ships the three files.
  • isekai_api:pool takes a shore_width. shore_width (int 0–6, default 0) grows the pool's rim block outward that many more rings, so a pond can have a beach instead of a one-block lip. The rings are grown from the shell by adjacency, so the bank follows the basin's real outline, and only solid cells are replaced (below the waterline always, above it half the time — the same rule the shell uses). It does not change containment: a pool still refuses terrain that cannot hold it. 0 is the old single ring, and the default, so existing datapacks place the same blocks.
  • isekai_api:leaning trunk placer takes slant_curve, space_check and min_height. slant_curve (double 1.0–2.0, default 1.0) lengthens each successive sideways step, so the same lean_length covers more ground and the bend accelerates instead of forming an L; 1.0 is one block per step and byte-identical to the old tree. space_check (bool, default true) ends the lean at an occupied cell and keeps the crown on the trunk — see Fixed. min_height (int 1–16, default 4) makes the tree place nothing when its trunk would be shorter, which is what a deliberately short palm needs. A datapack that omits all three gets the old shape.
  • isekai_api:leaf_distances structure processor. Recomputes a pasted template's leaf decay data from the template's own #minecraft:logs blocks: distance 1 for a leaf touching a log, +1 per leaf step, 7 when no log is reachable. orphan_leaves (decay|persist, default decay) decides whether unreachable leaves are left to decay or marked persistent, and keep_persistent (default false) decides whether a template leaf's existing persistent flag survives. It runs in finalizeProcessing, so it sees the states earlier processors produced. A template saved with every leaf at distance 7 no longer sheds its whole crown on the first shape update.
  • isekai_api:grounded_template takes a processors list. The same field a jigsaw single_pool_element has: a processor-list id or the list written inline, applied when the piece pastes the template. Omitting it places the NBT exactly as saved, which is what every existing datapack already got. Attaching isekai_api:leaf_distances here fixes a hand-authored tree without routing it through a jigsaw pool.
  • isekai_api:grounded_template varies the shape. rotation (none by default, plus clockwise_90, clockwise_180, counterclockwise_90, random) and mirror (none by default, plus left_right, front_back, random) turn or flip the pasted template, and template now also takes a weighted list, so one structure entry can share several NBT variants. random draws once per placement attempt from the chunk's structure seed. The gates sample the rotated extents, so a quarter-turned template is judged on the ground it actually covers, and the template stays centred on the chunk middle in every orientation. A datapack that omits the new fields places the same blocks as before.
  • /isekai survey <structure> [radius] replays structure placement over a square of chunks and reports how many chunks the structure set offered, how many were placed, and, for the rest, which gate rejected them (clearance_above_fluid, max_slope, biome, or declined for a structure type with its own reason). Nothing is generated to disk and no chunk is loaded, so it answers "why does this never spawn" on a live world; the same numbers are written to <world>/isekai/survey/<ns>_<path>-r<radius>.json. The rejection attribution runs through StructureProbe, which is inert outside a survey.
  • /isekai fit <structure> [pos] shows one chunk at full detail: the WORLD_SURFACE_WG heights the gates read as a 3x3 grid, the minimum/spread against clearance_above_fluid and max_slope, the verdict, and where vertical_offset puts each template variant. It also flags the two authoring mistakes that make a structure vanish without an error: a template id with no NBT (reported as 0x0x0) and a chunk no structure set offers. Written to <world>/isekai/fit/<ns>_<path>-<chunkX>_<chunkZ>.json.
  • /isekai survey blocks <block|#tag> [radius] [center <x y z>] [biome <biome|#tag>] counts what actually made it into each chunk: it generates the square (default radius 8, max 32) to FEATURES, spread over ticks, and reports trees, matching blocks, mean/median/min/max, the share of empty chunks, how much of the total sits in the busiest 10% of chunks, and a histogram. One tree is one six-connected group of matching blocks inside a chunk, so a 2x2 trunk counts once and a leaning trunk counts once. The optional biome filter is answered from the seed, so skipped chunks are never generated. The per-chunk map and the same summary are written to <world>/isekai/survey/blocks-<target>-r<radius>.json. This one does generate terrain to disk.
  • isekai_api:curved trunk and isekai_api:frond crown. A palm that bends while it climbs instead of rising straight and then walking sideways: each level adds one log on the lean side with a chance that grows with height (bend), the bent logs take the lean axis, and a single crown site sits on the top log. frond grows eight arched, drooping fronds (the diagonals as face-connected staircases) sampled per frond, so the top view is eight-pointed rather than a cross. leaning and fan are unchanged.
  • fluid_edge can search a band of heights. The optional vertical_range ({"below": n, "above": n}, both 0–64, default 0) widens the fluid search from the input Y to Y-below … Y+above. One modifier now expresses "no water within 12 blocks anywhere from sea level to 18 above it", which used to take a chain of one modifier plus one Y anchor per level. Omitting the field reads the input Y only, so existing packs behave exactly as before; the widened path also stops each column at its MOTION_BLOCKING height, so open sea costs one lookup per column instead of one per level.
  • isekai_api:biome_falloff places a feature with a probability that falls off with distance from a biome. P(d) = t^exponent with t = (max_distance - d) / (max_distance - full_distance): full density inside full_distance, zero past max_distance, thinning smoothly in between, so a biome border reads as fading density instead of a line. full_distance = max_distance gives a hard radius — what spatial_predicate's near_biome cannot do at placement time, where it always passes. Distance is never measured: one draw becomes a search radius and the rings of biome cells are walked until the first hit, so a position next to the biome costs a few samples (worst case at step 4, no biome in range: 197 / 797 / 3,209 samples for a 32 / 64 / 128-block radius). vertical_range covers dimensions whose biome changes with altitude. Biome cells are remembered per thread for the rest of the chunk's candidates, so the worst case above (76,741 samples, 29 ms per chunk in the nether at a 64-block radius) costs 0.9 ms.
  • isekai_api:override wraps another biome source and replaces the biome inside zone footprints. Everything no zone claims is answered by base, so the base's own rules, seed and climate sampling keep working — a jungle island or a single-biome region inside otherwise vanilla terrain without giving up the vanilla source. Zones are evaluated in declaration order and the first match wins. Two new zones come with it: isekai_api:box (an inclusive block-space X/Z box with optional min_y / max_y) and isekai_api:chunk_box (an inclusive chunk-aligned box, full height). An override changes the surface biome — surface blocks, vegetation, structure and feature eligibility, spawns, sky and fog colour — not the terrain shape, which the base generator's climate noise still decides; a patch over an ocean stays ocean-shaped. Newly generated chunks only.
  • base_biome and climate zones read the world, not just the coordinate. isekai_api:base_biome (biome: an id, a list, or a #tag) matches where the wrapped source's own answer is one of those biomes, so an override patch follows the base's borders instead of a drawn box — every soul sand valley becomes crimson forest in the nether, or forest below Y 80 in the overworld. isekai_api:climate matches the vanilla climate sample on any of the six axes (at least one is required), so one climate_zones rule can now be used anywhere a zone goes, override included, where the replacement biome and the climate that keeps deciding terrain stay independent. The source fills both values once per position and shares them across zones, so a stack of climate conditions costs one sample; base_biome is only meaningful under override and answers false under rule, which has no wrapped source to ask. Java: BiomeZone.test(x, y, z, ZoneContext) is a new overload and ZoneContext (NONE, forClimate) carries the state; the three-argument method, its default and existing third-party zones are unchanged. Measured over 200,000 positions (ns per getNoiseBiome, median of three runs): wrapping the nether costs nothing (122 → 122), and 15 and(base_biome, noise_threshold) children cost 327 — written noise-first the same 15 cost 923, so base_biome goes first.
  • /isekai survey biomes <radius> [center <x y z>] [y <y>] measures a seed's biome map without generating it. It samples every 4-block column of a disc through the biome source, so the biome shares are exact counts, and groups face-connected cells of one biome into patches whose area is reported as the diameter of a circle with that area (2*sqrt(area_blocks/pi), so a radius-64 patch reads as 128); patches that touch the rim are counted and excluded from the median and p90, with the excluded count reported. The same scan reports the six vanilla climate axes unquantized as p1…p99, labelled with both the JSON name and the F3 name (humidity/vegetation, weirdness/ridges). Nothing is generated and no chunk is loaded, so the scan runs on a worker thread while the server ticks; one biomes survey runs per server at a time, and a radius is required (16–4096 blocks, defaulting to the executor's position and Y). Writes <world>/isekai/survey/biomes-<dimension>-r<radius>-<x>_<y>_<z>.json; radius 2048 is 823,592 cells and takes about 0.3 s measured in a GameTest server.

Fixed

  • isekai_api:assembled puts its origin on the ground, not on a tree crown. The origin's Y came straight from WORLD_SURFACE_WG, which counts leaves and logs, so a neighbouring tree whose crown covered the origin column lifted the whole feature list onto the canopy: a pool dug into open air (and its containment check refused it) and a pad spread its sand at tree height. The Y now walks down past air, #minecraft:leaves, #minecraft:logs and replaceable plants to the first block that is terrain, and stops on fluids, so an over-water structure keeps its water-surface origin.
  • isekai_api:assembled places its features once, not once per overlapping chunk. A piece's postProcess runs for every chunk its box overlaps, each with its own random, so a three-chunk-wide assembled landmark could re-place the whole feature list up to nine times and stack nine differently-shaped pools and tree clusters on one spot. The run is now gated on the chunk that contains the origin, which does not depend on chunk visit order. Features may still write past that chunk, exactly as a place feature does during decoration.
  • A leaning trunk no longer attaches its crown to a blocked cell. With space_check on (the new default), a lean that runs into an occupied cell stops there and the crown stays on the trunk; previously the crown could sit in mid-air where no log could be placed. Set space_check: false to reproduce the old shape.
  • Worldshapes for different dimension types of one dimension key coexist. Single-layer declarations were stored one-per-dimension key, so a Sky World shape (sky_world:sky) and a Tundra World shape (frozen_world:frozen) both targeting minecraft:overworld replaced each other in load order and one world type got no shape at all. Declarations are now grouped by Scope; getActiveDescriptor picks the one whose required_dimension_types contains the level's actual dimension_type (restricted over unrestricted, then higher priority). Same- scope declarations keep the old priority rule. If the type is unknown and two restricted declarations exist, the registry returns none rather than guessing.
  • Worldshape bounds resolve per dimension. Ore/feature Y-remapping and the playable_range envelope used the overworld's min_y/height for every dimension. They now come from the dimension's LevelStem/DimensionType, keyed by the descriptor's dimension. Only a level with no LevelStem entry falls back to the overworld envelope.
  • No declarations, no cost. Every hook returns on an empty check before a registry or biome lookup; the reconcile returns immediately when no worldshape is declared.
  • Decorators no longer inherit a 2x2 trunk's ground blocks. TreeDecorator.Context#logs() carries one block per trunk column written by TrunkPlacer.setDirtAt (four for giant_trunk_placer on grass), and only the first was dropped. branch_stubs without a block_provider could therefore take its block from dirt and start one row too low. Every dirt-like entry at the lowest level is now dropped, and only when a trunk block sits above it.
  • The wood-set audit reads references the way the game does. A bare path in a model parent, a textures value or a blockstate model resolves to minecraft:, not to the namespace of the file that names it; a value that is not a valid resource location becomes a reference finding instead of failing the whole audit. /isekai validate <namespace> prints the validation result before the wood-set audit, and an audit failure is logged and reported as one line instead of hiding it.
  • broken_top's fill_provider uses the decorator placement helpers. A leaf used as the fill is pinned like every other decorator-written leaf rather than written at distance: 7.
  • A wood set's builder is claimed only after registration succeeds. A failure part-way through register() no longer leaves the builder marked as registered and unusable.
  • WoodSets survives parallel mod construction. NeoForge constructs mods in parallel; the set list and the boat lookup are now concurrent collections.
  • Docs: a pinned leaf is not a permanent leaf. LeafPlacing, the placer section of docs/DATAPACK_REFERENCE.md and the README now state that the pin carries a leaf through generation, and that the first tick recomputes the real distance, so a leaf more than six steps from a log decays as a vanilla leaf does. The behaviour is unchanged.
  • Docs: ground_patch's radius limit has a stated reason. 16 is the largest disc that stays inside the chunks a feature may write (ChunkStatus.FEATURES writes one chunk out), while a placement modifier that moves the feature's origin into a neighbouring chunk can still reach past it.
  • A leaning trunk's horizontal walk is capped at 12 blocks. slant_curve is exponential, so slant_curve 2.0 with lean_length 16 walked 131,071 blocks sideways — far outside the chunks a feature is placed into, and the crown was attached there. The stalk now stops at 12 blocks of total horizontal travel from the origin (the near-vertical lean counts). slant_curve 1.0 with a lean_length of 13–16 is truncated at the same limit; every configuration that stayed inside 12 blocks (including 1.0 up to 12) generates exactly as before.
  • A leaning trunk with space_check on keeps its crown on the last log it placed. The fix for the blocked cell moved the crown but left the returned attachment pointing at the intended end position, so a decorator or tip_crown_only fan could still hang from a spot with no log under it. The last attachment is now the last placed log itself. space_check: false keeps the old geometry for packs that reproduce it deliberately.
  • /isekai survey blocks no longer claims to stay under 8 ms. Chunk generation runs on the server thread inside the tick, so one chunk per tick means tens of milliseconds per chunk and TPS drops for the length of the run; the tick loop can only decide whether to start another chunk, not slice one. The docs and README now say so, and the per-chunk count is stated as a lower bound because a later chunk's tree can still write into a chunk already counted.
  • Only one /isekai survey blocks runs per server. A second run inside the same window interleaved with the first inside the same ticks and counted the same chunks twice; it is now refused with a message naming the run that is still going.
  • isekai_api:pool's shore_width is taken out of xz_radius. A radius plus a shore larger than the 15 blocks a feature may reach was cut off at the chunk border, leaving a straight edge instead of a bank. The effective radius is now xz_radius shrunk by shore_width (floor 1), so xz_radius 14 with shore_width 6 reaches 15 rather than 19. Pools whose radius plus shore already fit are unchanged.
  • /isekai fit says which variant it measured. The verdict describes one footprint — the first template variant, unrotated — but the report looked like it covered every variant, and rotation: random draws a different turn per chunk. The summary now names the measured template and rotation, and the JSON carries measured_template / measured_rotation.
  • /isekai validate dimension no longer generates the chunk it inspects. A non-overworld dimension whose (0,0) chunk is not loaded reports spawn SKIP (the column is not sampled) instead of reading the heightmap and blocks, both of which would load or generate that chunk. Stand at (0,0) or /forceload add 0 0 to get a verdict.
  • A wall sign is audited under its own language key. The species audit built each block's key from getDescriptionId(), and vanilla's wall sign returns the standing sign's name, so the wall key was never checked while the standing key was checked twice. A missing <ns>:<species>_wall_sign name (and a wall hanging sign's) is now reported.
  • A pool lines around logs and leaves instead of burying them. The rim now uses vanilla LakeFeature's rule and only overwrites cells that are solid and outside minecraft:lava_pool_stone_cannot_replace, so a pool that reaches a tree banks around the trunk; a widened shore_width follows the same rule.
  • leaning with space_check stops at a blocked cell in the vertical trunk. The trunk used to skip the log and keep climbing, leaving the crown on air and the stalk attached above the hole; the crown now goes on the last log that exists.
  • The Japanese name of a potted sapling follows vanilla's word order: 植えられた〈樹種〉の苗木 for block.<ns>.potted_<species>_sapling, as in 植えられたオークの苗木.
  • A frond crown lifted by offset no longer hangs off the trunk. Leaf distance follows face contact, so lifting the crown above the top log left every frond reached only through a diagonal: the whole crown sat past the sixth step and decayed as soon as it was ticked, while untouched leaves kept their generation-time pin and hid it. The lift cells are now filled with leaves and the lift is spent from the same six-step budget as the fronds.

Changed

  • /isekai survey caps radius at 128 instead of 512. The scan is quadratic and runs inside the command call on the server thread: 512 was 1,050,625 chunks of placement tests plus a generation check for every candidate in one tick. 128 is 66,049 chunks; use several smaller runs instead.
  • structure_spawn_overrides is scoped to the structure, not the dimension. It writes the structure's own spawn settings, so a descriptor that sets it also changes that structure in every other dimension. The datapack reference now says so in the scope table; the other override keys keep their dimension scope.
  • A nether or end on an isekai_api: biome source no longer opens behind the experimental-settings prompt. Vanilla accepts only its stock biome source and noise settings there, so a mod that shipped an Isekai nether inside its own jar still asked players to confirm "experimental settings" when the world was created and first opened. Isekai API now reports such a dimension as stable when it keeps the stock dimension type key and a minecraft:noise generator; its own noise settings are allowed. Other causes keep the prompt: a non-Isekai source with its own noise settings, a swapped dimension type key, a dimension count other than three, and any worldgen registry entry (dimension_type, noise_settings, biomes, features) from a user datapack.

Known limitations

  • Biome attributes are shared. Climate (temperature, downfall, precipitation) and effects (colors, particles, sounds, music) cannot differ by dimension when a biome is shared; use applies_to to limit which biomes a descriptor edits.
  • atmosphere.mob_spawn_costs stays global, because NaturalSpawner#createState has no level. creature_generation_probability is written to the same shared biome.
  • Carvers are dimension-scoped only on NoiseBasedChunkGenerator. A dimension with another generator, or a NoiseBasedChunkGenerator subclass that overrides applyCarvers without calling super, keeps the old biome-wide add/remove (CarverScope.hookable).
  • Mob exclusions do not reach a custom mob that calls addFreshEntity without finalizeSpawn. Additions and weight changes only apply where a biome spawn list is read.
  • /reload does not change worldgen rules. NeoForge runs biome modifiers once at server start, so adding or removing a rule needs a restart.
  • A declared biome loses other mods' features in every other dimension. The reconcile removes the original holder, so a dimension that reuses the biome without declaring it no longer gets that feature.
  • Structure dimension resolution during generation depends on the chunk being a ChunkAccess. An implementation that passes only a LevelHeightAccessor is not in the index and falls back to BiomeSource matching, which is ambiguous when two dimensions share one biome source (ChunkDimensionIndex, DimensionResolver).
  • /place structure is not blocked by exclusions.structures because it skips the generation-point search.
  • The final feature veto covers the placeWithContext route only. A generator that places a feature by another path can still place it; the decoration filter is the primary mechanism.

This mod has no additional files