36 KiB
11 - Dimensions
A dimension is the root object of a pack: it decides how tall the world is, where sea level sits, which regions supply biomes, and which engine stages run. It lives at dimensions/<loadKey>.json and everything else in the pack hangs off it. Some of its fields are a permanent contract with the world folder and some are free to change every save — this page separates those two groups and explains what each knob actually does to generated terrain.
Related: see 05 - Concepts & Pack Layout.md, 10 - Studio & VSCode Schemas.md, 12 - Regions.md, 14 - Generators & Noise.md, 15 - Caves & Carving.md, 18 - Structures Overview.md, 22 - Native Structures & Datapacks.md, 26 - Example - Minimal Dimension.md.
Decide these before you create a world
Iris pins four values when a world binds to an engine: the dimension type key (derived from the dimension load key), the minimum Y, the total height (max - min), and logicalHeight. That record is IrisDimensionRuntimeContract. Hotload compares the record before and after every pack reload and refuses the reload if any of the four changed, so a height edit in a running Studio world is rejected until you close and reopen. On a production world the values are baked into the generated Minecraft dimension type, so changing them means recreating the world.
| Field | Why it is a contract |
|---|---|
| Dimension file name (load key) | Becomes the dimension type key iris:<sanitized load key>; renaming the file makes the world look for a dimension type that no longer exists |
dimensionHeight |
Min Y and total height are written into the Minecraft dimension type and into every stored mantle/chunk coordinate |
logicalHeight |
Written into the same dimension type |
environment |
Selects which vanilla dimension template the generated type is built from, which changes the type's identity |
Everything else — regions, zooms, noise styles, palettes, ores, deposits, caves, structures, decoration, loot — reloads live in Studio and applies to newly generated chunks. Iterate on those freely; already-generated chunks keep whatever they were built with.
File location and load key
The load key is the path under dimensions/ with .json removed. dimensions/overworld.json is key overworld; dimensions/foo/bar.json is key foo/bar. The world create and studio open commands take that key.
The key is also sanitized into the dimension type key: lowercased, path separators and any character outside a-z0-9_-./ replaced with _. Two dimensions whose keys sanitize to the same string collide on the same generated dimension type, so keep keys distinct in more than punctuation.
/iris studio create name=mypack writes dimensions/mypack.json with a matching name. Keep the file name and the load key stable once a world exists.
Role in the pack graph
Dimension → regions[] → Region → land/sea/shore/cave biomes[] → Biome → generators[]
→ ores, deposits, depositVariants, overlayNoise
→ caveProfile, carving[], structures[], importedStructures, importedFeatures
→ loot, entitySpawners, blockDrops
The dimension never names a biome directly (outside focus and carving entries). Biomes are reached through regions, so an unreferenced region file is dead weight and a biome missing from every region list never generates.
Engine mode
mode.type picks which stages the engine registers. This is the single biggest behavioral switch in the file: three of the four modes register only a terrain pass and a biome pass, so caves, objects, decorations, deposits and post-processing do not run at all in them. Do not reach for ISLANDS or ENCLOSURE expecting a themed world — today they generate exactly what SUPERFLAT does.
{
"mode": { "type": "OVERWORLD" }
}
| Type | Stages actually registered | Use it when |
|---|---|---|
OVERWORLD |
Biome, mantle matter generation, terrain, carve, post-process, floating child biome solids, deposits, matter insert, decoration, floating child biome decoration, perfection, custom modifiers | Any world that needs caves, objects, structures, decorations or entities — this is the only complete mode |
SUPERFLAT |
Terrain and biome only | Fast noise/biome-layout previews, or a genuinely bare world; nothing else generates |
ENCLOSURE |
Terrain and biome only | Nothing yet; the nether-style ceiling/floor treatment is not implemented |
ISLANDS |
Terrain and biome only | Nothing yet; floating-island terrain comes from biome floatingChildBiomes in OVERWORLD mode, not from this |
mode is marked required in the schema, but Gson supplies a default IrisDimensionMode when the field is absent, so an omitted mode runs OVERWORLD. The shipping overworld pack omits it. If the mode factory throws, the engine logs the failure once, warns that it is falling back, and builds OVERWORLD instead.
IrisDimensionMode is a snippet type (dimension-mode), so "mode": "snippet/dimension-mode/overworld" is also valid.
Vertical layout: height, sea level, bedrock
Iris generates internally from 0 to dimensionHeight.max - dimensionHeight.min, then shifts the finished chunk down by dimensionHeight.min on output. Almost every Y number the engine handles internally is in that shifted space, but the numbers you write in the dimension JSON are not all in the same space, which is the most common source of confusion in this file:
dimensionHeight.min/dimensionHeight.maxare world Y.fluidHeightis world Y.IrisDimension.getFluidHeight()returnsfluidHeight - dimensionHeight.min, which is what the engine uses internally, so sea level ends up back at the world Y you wrote. The shipping overworld setsfluidHeight50 withmin-256, and its ocean surface is at world Y 50.caveLavaHeightis internal Y. World Y =caveLavaHeight + dimensionHeight.min. The default 8 with a min of -64 puts the cave lava ceiling at world Y -56.- Bedrock is written at internal Y 0, which is world Y
dimensionHeight.min.
Biome generator heights are relative to sea level: a biome generator entry with min 4 / max 10 produces terrain 4 to 10 blocks above fluidHeight, clamped to the dimension's height range.
{
"dimensionHeight": { "min": -64, "max": 320 },
"logicalHeight": 384,
"fluidHeight": 63,
"bedrock": true,
"caveLavaHeight": 8
}
That fragment is a vanilla-shaped world: build floor at -64, ceiling at 320, sea at 63, bedrock at -64, cave lava below -56.
Minecraft imposes hard rules on the generated dimension type, and Iris fails when they are broken rather than clamping:
dimensionHeight.max - dimensionHeight.minmust be a multiple of 16, and between 16 and 4064.dimensionHeight.minmust be a multiple of 16, and between -2032 and 2031.logicalHeightmust be between 0 and the total height.
/iris pack validate does not check these — it only checks that structure placements fit inside the declared range. A bad height passes validation and then fails when Iris compiles the dimension type, at boot or at studio open. Check the arithmetic yourself before creating the world.
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
dimensionHeight |
IrisRange |
{ "min": -64, "max": 320 } |
The world's build floor and ceiling in world Y. Raise max for tall mountain packs, lower min for deep-cave packs. Contract field: pick it once per world |
logicalHeight |
int | 256 |
The vanilla logical height of the generated dimension type — the ceiling gameplay teleports respect (nether portal search, chorus fruit). Usually set equal to the total height. Contract field |
fluidHeight |
int | 63 |
World Y of the ocean surface, and the baseline every biome generator height is measured from. Lowering it makes the same biome generators produce relatively taller land; raising it drowns low biomes. Not a contract field, but changing it on a live world leaves a visible seam between old and new chunks |
bedrock |
boolean | true |
Writes a bedrock layer at the build floor. Turn it off for void-bottom or stacked-dimension packs |
caveLavaHeight |
int | 8 |
Internal Y at or below which carved cave space fills with lava instead of air. Raise it to flood deep caves, set it to 0 for dry caves. Explicit fluid intent from a carver overrides this |
name |
string | "A Dimension" |
Display name shown by commands and the studio scoreboard. Cosmetic |
version |
int | 1 |
A stamp you control. Iris does not act on it; it exists so pack updates can be recognized and so operators do not silently swap incompatible pack generations under an existing world |
Environment and dimension-type options
environment picks which vanilla dimension template Iris starts from when it generates this dimension's type; dimensionOptions then overrides individual attributes of that template. Together they control sky, fog, ambient light, portal scale, whether beds work, whether raids can start, and the rest of the dimension-type surface. They do not change terrain.
{
"environment": "NETHER",
"dimensionOptions": {
"ultrawarm": "TRUE",
"skylight": "FALSE",
"ceiling": "TRUE",
"coordinateScale": 8,
"ambientLight": 0.1
}
}
environment |
Base template |
|---|---|
NORMAL |
Overworld |
NETHER |
Nether |
THE_END |
End |
CUSTOM |
Overworld — the enum value exists but resolves through the same default branch as NORMAL |
fullbright is a shortcut: when true, Iris copies dimensionOptions and forces ambientLight to 1.0 before generating the type. On both supported Minecraft versions (26.1.2 and 26.2 share the same datapack fixer) a resolved ambient light of 1 also emits minecraft:visual/ambient_light_color #ffffff, so a fullbright world reads as flat white rather than merely bright.
Tri-state options are DEFAULT, TRUE, or FALSE; DEFAULT inherits from the base template. Numeric options use -1 as "unset".
dimensionOptions field |
Default | Effect |
|---|---|---|
ultrawarm |
DEFAULT |
Water evaporates, sponges dry, snow golems melt, lava spreads fast and thin, dripstone drips lava. Set TRUE for nether-like packs |
natural |
DEFAULT |
When false, compasses spin and beds cannot set spawn or be slept in; when true, nether portals spawn zombified piglins and creaking hearts activate |
piglinSafe |
DEFAULT |
When false, piglins and hoglins zombify here |
respawnAnchorWorks |
DEFAULT |
When false, a respawn anchor explodes instead of setting spawn |
bedWorks |
DEFAULT |
When false, beds explode instead of sleeping |
raids |
DEFAULT |
Whether Bad Omen can start a raid here |
skylight |
DEFAULT |
Whether the dimension receives sky light at all. FALSE makes a permanently dark world regardless of the terrain ceiling |
ceiling |
DEFAULT |
Declares a logical bedrock ceiling to the client and to gameplay rules. Independent of whether terrain actually has a roof |
coordinateScale |
-1 (unset) |
Portal coordinate multiplier when travelling out of this dimension. 8 reproduces nether-style compression |
ambientLight |
-1 (unset) |
0 to 1. Raises the light floor so caves are never fully black. A resolved 1 also forces white ambient light color |
fixedTime |
-1 (unset) |
Locks the time of day to this tick value. Leave unset for a normal day cycle |
cloudHeight |
-1 (unset) |
Y of the cloud layer, between -2032 and 2031. null disables clouds |
monsterSpawnBlockLightLimit |
-1 (unset) |
0 to 15. Maximum block light at which hostile mobs may spawn |
Regions and spatial layout
regions is the only mandatory content link in the file. Region selection happens first, per column: regionStyle picks the region, continentalStyle and landChance decide land versus sea inside it, then the land/sea/shore/cave biome styles pick a biome from that region's lists. The zoom fields scale the noise inputs — higher zoom means larger, slower-changing features.
{
"regions": ["temperate", "frozen", "tropical"],
"landChance": 0.69,
"regionZoom": 16.15,
"biomeZoom": 1.0,
"coordFractureDistance": 20,
"coordFractureZoom": 8,
"dimensionAngleDeg": 12
}
Tune this group in Studio with a fixed seed and compare the same coordinates between reloads. Every field here is safe to hotload.
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
regions |
string[] | empty | The region load keys this dimension may place. Required — an empty list produces a world with no biomes to select. Add a region here after creating its file, or the file never generates |
landChance |
double | 0.625 |
Fraction of continental noise that becomes land. Push toward 1.0 for a continental world, toward 0.0 for an archipelago or ocean world |
regionZoom |
double | 1 |
Scales region cells. Small values give many small climate patches; the shipping overworld uses 16.15 for continent-sized climate bands |
landZoom |
double | 1 |
Scales the land-biome selection space independently of regions. Raise it to make each land biome patch bigger without changing where regions sit |
seaZoom |
double | 1 |
Same, for ocean biomes |
continentZoom |
double | 1 |
Scales the land/sea mask. Raise it for fewer, larger continents |
biomeZoom |
double | 1 |
Global multiplier over every biome selection stream. The quickest way to make all biomes uniformly bigger or smaller |
regionStyle |
IrisGeneratorStyle |
CELLULAR_IRIS_DOUBLE |
Noise style that shapes region borders. Change it when region edges look too regular or too noisy |
continentalStyle |
IrisGeneratorStyle |
CELLULAR_IRIS_DOUBLE |
Noise style for the land/sea mask — this is what coastlines look like |
landBiomeStyle / seaBiomeStyle / shoreBiomeStyle / caveBiomeStyle |
IrisGeneratorStyle |
CELLULAR_IRIS_DOUBLE |
Per-category biome border shapes. Cellular styles give patchwork borders; simplex-family styles give organic blobs |
coordFractureDistance |
double | 20 |
How far, in blocks, coordinate warping can displace a sample. This is what produces Iris's characteristic swirls. Set to 0 for straight, unwarped borders |
coordFractureZoom |
double | 8 |
Frequency of that warping. Lower values warp more rapidly and more violently; the shipping overworld uses 0.15 |
dimensionAngleDeg |
double | 0 |
Rotates every input coordinate by this angle. Breaks up axis-aligned artifacts. Pick something off 45 and 90 — the shipping overworld uses 69 |
focus |
string | "" |
Forces the whole world to one biome load key. Testing only; remove before packaging |
focusRegion |
string | "" |
Forces the whole world to one region load key. Testing only; remove before packaging |
Rock, fluid, and overlay noise
rockPalette is the material the terrain column is filled with below the biome's own surface layers, and fluidPalette is what fills ocean columns and any cave aquifer that allows fluid. Both are full weighted palettes, so "stone" can be a blend of stone, andesite and tuff, and "water" can be lava, or a custom mod fluid.
{
"rockPalette": {
"palette": [
{ "block": "minecraft:stone", "weight": 6 },
{ "block": "minecraft:andesite", "weight": 2 },
{ "block": "minecraft:tuff" }
]
},
"fluidPalette": { "palette": [{ "block": "minecraft:water" }] }
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
rockPalette |
IrisMaterialPalette |
stone |
Subsurface fill for every column that a biome layer does not claim. Change it for a themed world (deepslate planet, sandstone desert world). Biomes and regions can override it locally |
fluidPalette |
IrisMaterialPalette |
water |
Blocks used for ocean columns and for cave aquifers that allow fluid. Set it to lava for a magma world |
overlayNoise |
IrisShapedGeneratorStyle[] |
empty | Extra height noise summed on top of the interpolated biome height, everywhere, ignoring biome boundaries. Use it for a global roughness or a world-wide swell that must not follow biome edges |
rockZoom |
double | 5 |
Declared but never read by the engine. Leave it alone; palette scaling comes from the palette's own zoom |
Ores and deposits
Iris has two independent ways to put ore in the ground, and they behave differently.
Ores (ores) are noise-threshold generators evaluated per block while terrain is written. Each generator declares its own Y range and a generateSurface flag; Iris keeps two separate lists and only consults the matching one, so a generator with generateSurface: false never appears in the exposed surface layer. Ores also exist at region and biome scope; all three scopes are consulted, dimension last.
Deposits (deposits) are blob placements written through the mantle, closer to vanilla ore veins, with per-chunk counts and sizes.
Deposit variants (depositVariants) rewrite the block that any of the above would have placed, inside a world-Y band. This is how the shipping pack turns minecraft:iron_ore into minecraft:deepslate_iron_ore below Y 0 without duplicating every generator.
{
"ores": [
{
"palette": { "palette": [{ "block": "minecraft:bedrock" }] },
"chanceStyle": { "style": "FLAT" },
"threshold": 1,
"range": { "min": 0, "max": 0 }
}
],
"depositVariants": [
{
"minHeight": -64,
"maxHeight": 0,
"remap": { "minecraft:iron_ore": "minecraft:deepslate_iron_ore" }
}
]
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
ores |
IrisOreGenerator[] |
empty | Noise-driven ore placement across the whole dimension. Each entry has a palette, a chanceStyle, a threshold, a Y range, and generateSurface. Use dimension scope for ores that must exist everywhere regardless of biome |
deposits |
IrisDepositGenerator[] |
empty | Blob deposits with per-chunk min/max counts and blob sizes. The shipping pack uses these for granite, andesite, diorite, gravel and the classic ores |
depositVariants |
IrisDepositVariant[] |
empty | Source-to-replacement block remaps inside a world-Y band, applied after biome and region rules; the first matching dimension rule wins. Source matching ignores block properties |
hideOresForHiddenOre |
boolean | false |
Replaces every ore the generator would write — terrain ores, deposits, and ores baked into objects — with the surrounding base material. Turn it on only when a drop-control plugin such as HiddenOre is supplying ores at break time instead |
Caves and carving
Three fields at dimension scope decide whether caves exist and what they look like.
caveProfile is the 3D cave configuration. The same object exists on regions and biomes, and the most specific enabled profile wins: dimension, then region, then surface biome, then cave biome. So a dimension-level profile is the default cave system and a region can replace it wholesale for its own climate.
carving maps absolute world-Y bands to cave biomes, which is how the shipping pack puts a deep-dark biome between Y -250 and -175 without touching surface biome selection. Entries can nest through children for patchy sub-regions, bounded by childRecursionDepth.
carvingEnabled: false is implemented by adding the CARVED mantle flag to the disabled set — it is exactly equivalent to listing CARVED in disabledComponents.
{
"carvingEnabled": true,
"caveProfile": { "enabled": true },
"carving": [
{
"id": "global-deepdark-band",
"enabled": true,
"biome": "carving/standard-deepdark",
"worldYRange": { "min": -250, "max": -175 }
}
]
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
carvingEnabled |
boolean | true |
Master switch for carving. Setting it false disables the CARVED mantle component, so no cave, canyon or carver output is written anywhere. Use it to isolate a terrain problem from a cave problem |
caveProfile |
IrisCaveProfile |
disabled default object | The dimension's default 3D cave system: density styles, vertical range, threshold, surface clearance. Regions and biomes override it when they enable their own. Full field reference in 15 - Caves & Carving.md |
carving |
IrisDimensionCarvingEntry[] |
empty | Cave-biome overrides keyed to absolute world-Y bands, each with a stable id, a biome, a worldYRange, optional children, childStyle, childShrinkFactor, and childRecursionDepth. Use it for depth-banded cave themes such as a deep dark layer |
useMantle |
boolean | true |
Disables the entire mantle when false: no objects, jigsaw structures, features, entities or deferred block updates. Terrain and decoration still run. Only useful for isolating mantle cost or debugging |
disabledComponents |
mantle flag strings | empty | Turns off individual mantle components by flag. The registered components are OBJECT, JIGSAW, CARVED, and FLOATING_OBJECT. Cheaper than useMantle: false when you only need to silence one subsystem |
Objects, decoration, and post-processing
These fields gate the passes that run after terrain and carving. All of them hotload.
{
"decorate": true,
"postProcessing": true,
"postProcessingSlabs": true,
"postProcessingWalls": true,
"requireObjectSurfaceSupport": true,
"objectSurfaceSupportBuffer": 2,
"preventLeafDecay": false
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
decorate |
boolean | true |
Runs the decorator pass (grass, flowers, seafloor clutter, ceiling growths). Turn it off to look at bare terrain shape |
postProcessing |
boolean | true |
Master switch for the post pass that smooths block-level artifacts |
postProcessingSlabs |
boolean | true |
Lets the post pass place slabs to soften one-block terrain steps |
postProcessingWalls |
boolean | true |
Lets the post pass paint wall blocks against exposed faces |
requireObjectSurfaceSupport |
boolean | true |
Refuses to place surface objects and trees that would hang over a carved opening. Turning it off produces floating buildings above caves; the per-placement flag can only opt out further, never override this on |
objectSurfaceSupportBuffer |
int | 2 |
Minimum solid blocks required beneath a surface placement, 0 to 16. The effective value is the larger of this and the placement's own buffer, so raising it hardens every placement in the dimension at once |
preventLeafDecay |
boolean | false |
Marks generated leaves persistent so they never decay when the supporting log is removed. Turn it on for packs whose custom trees have unusual leaf-to-log distances |
treeSettings |
IrisTreeSettings |
disabled default | Overrides vanilla sapling growth with pack objects. See 17 - Trees, Fungi, Coral, Crystals, Formations, Ruins.md |
Structures and datapacks
Dimension-level structures entries are Iris placements considered everywhere in the dimension, independent of any biome or region placement. importedStructures and importedFeatures control what vanilla, mod, and ingested-datapack content is allowed to generate on top of Iris terrain.
anchor is what makes a placement's vertical contract explicit. LEGACY preserves the historical underground boolean; the named anchors do not depend on it. Cave anchors read Iris carved-space data, so they apply only to editable structures and never to the nativeStructures backend.
{
"structures": [
{
"placementId": "ancient-city-native",
"nativeStructures": [{ "structure": "minecraft:ancient_city" }],
"nativeSuppression": "REPLACE_SOURCE",
"minHeight": -220,
"maxHeight": -220
}
],
"importedStructures": {
"datapackOverrides": true,
"disabled": [],
"adjustments": [
{ "match": ["minecraft:mineshaft"], "preserveSourceY": true }
]
}
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
structures |
IrisStructurePlacement[] |
empty | Iris structure placements at dimension scope. Use this for content that must exist regardless of biome, such as a global stronghold analogue or a native structure you are re-anchoring |
importedStructures |
IrisImportedStructureControl |
default | Allow/deny and Y-adjustment rules for every registered native structure. Every registered structure generates by default; disabled is the only deny list. adjustments can shift, band, encase, or stilt a structure into Iris terrain |
importedFeatures |
IrisImportedFeatureControl |
disabled | Off by default: leaving it out generates exactly the terrain Iris always has. Setting enabled true runs the vanilla placed-feature decoration pass (ores, trees, plants, springs, geodes) over Iris terrain, filterable by disabled keys, steps, and disabledSteps. Carvers are never imported |
datapackImports |
string[] | empty | External datapack URLs this dimension owns. Their structure sets and definitions generate and locate only in dimensions that declare the same source. Replacing native generation still requires a placement with nativeSuppression: REPLACE_SOURCE; declaring the source alone never disables anything |
Anchor values for editable placements: LEGACY, SURFACE, HEIGHT_BAND, CAVE_FLOOR, CAVE_CEILING, CAVE_CENTER, CAVE_ANY. Details in 18 - Structures Overview.md, 21 - Jigsaw Structures.md, and 22 - Native Structures & Datapacks.md.
Upper dimension (inverted ceiling terrain)
Set upperDimension to another dimension's load key (or this dimension's own key) and Iris generates that dimension's terrain upside-down against the world ceiling, nether-style. "none" or an empty string disables it; the shipping overworld ships with "".
{
"upperDimension": "overworld",
"upperDimensionGap": 32,
"upperDimensionCarving": false,
"upperDimensionObjects": false
}
If the referenced key cannot be loaded, Iris warns and skips upper terrain rather than failing the world.
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
upperDimension |
string | "none" |
Load key of the dimension whose terrain becomes the ceiling. Self-reference is allowed and produces a mirrored world |
upperDimensionGap |
int | 32 |
Minimum air blocks kept between the lower surface and the upper surface, 0 to 256. Raise it if the two halves close up in high terrain |
upperDimensionCarving |
boolean | false |
Lets cave carving cut through the ceiling mass. False leaves it solid |
upperDimensionObjects |
boolean | false |
Lets mantle objects place in the upper zone. False protects the ceiling from trees and structures |
upperObjectsForcePlace |
boolean | false |
Upper objects ignore slope, underwater, clamp, collision, and carving restrictions. Lower-dimension objects always place first, so enabling this lets upper objects clip through them |
Loot, spawners, and block drops
These are dimension-wide fallbacks. Regions and biomes layer on top of them.
{
"loot": { "mode": "FALLBACK", "tables": ["global-clutter"] },
"entitySpawners": ["swamp/passive"],
"blockDrops": []
}
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
loot |
IrisLootReference |
empty, mode ADD, multiplier 1 |
Loot tables applied to containers generated anywhere in the dimension. ADD stacks this scope's tables onto the parent list; CLEAR and REPLACE both drop the parent tables first; FALLBACK supplies tables only when the object itself declared none. multiplier scales item counts 0 to 16. Use dimension scope for global clutter, region scope for climate flavor |
entitySpawners |
string[] | empty | IrisSpawner load keys that continually replenish mobs like vanilla does. Dimension scope means "everywhere in this world" |
blockDrops |
IrisBlockDrops[] |
empty | Custom drop overrides for specific blocks in this dimension |
Studio and debug fields
These exist to help you look at the generator, not to ship. studioMode is applied only by the Bukkit chunk generator; on Fabric, Forge and NeoForge the field is ignored.
| Field | Type | Default | What it does and when to change it |
|---|---|---|---|
studioMode |
StudioMode |
NORMAL |
Swaps in a debug generator. BIOME_BUFFET_1x1, _3x3, _5x5, _9x9, _18x18, _36x36 lay every biome out in a grid of that cell size; OBJECT_BUFFET lays out objects. REGION_BUFFET currently installs no generator and behaves exactly like NORMAL. Remove before packaging |
debugChunkCrossSections |
boolean | false |
Deletes whole chunks on a grid so you can walk up and read the terrain column like a diagram |
debugCrossSectionsMod |
int | 3 |
The X/Z modulus that decides which chunks get cut, 2 to 16. Larger values cut fewer chunks |
explodeBiomePalettes |
boolean | false |
Inserts air gaps between palette layers so you can count and identify them visually |
explodeBiomePaletteSize |
int | 3 |
Size of those gaps, 1 to 16 |
debugSmartBore |
boolean | false |
Fills the air volume objects carve for themselves with cobweb, making object footprints visible |
disableExplorerMaps |
boolean | false |
Declared but never read by the engine today |
forceConvertTo320Height |
boolean | false |
Declared but never read by the engine today |
Annotations are editor hints, not runtime validation
@Required, @MinNumber, and @MaxNumber are consumed only by the schema generator. Nothing enforces them at load time, so a value outside the documented range loads without complaint and produces whatever the engine does with it. The exceptions are the dimension-type constraints listed under vertical layout, which throw during dimension-type compilation. Treat the ranges in the tables above as design guidance backed by editor warnings, and verify unusual values in Studio.
A complete minimal dimension
{
"name": "mypack",
"version": 1,
"mode": { "type": "OVERWORLD" },
"regions": ["starter"],
"environment": "NORMAL",
"dimensionHeight": { "min": -64, "max": 320 },
"logicalHeight": 384,
"fluidHeight": 63
}
This is the studio starter with mode, environment and fluidHeight written out. It needs regions/starter.json, a biome, and a generator to actually produce terrain; the four-file walkthrough is in 26 - Example - Minimal Dimension.md.
What the shipping overworld sets
Path: packs/overworld/dimensions/overworld.json under the platform data directory (the same file ships in the Fabric, Forge and NeoForge run configs).
| Field | Overworld value | Why it is interesting |
|---|---|---|
name / version |
"Overworld" / 4000 |
Large version stamp so pack generations are distinguishable |
environment |
"NORMAL" |
Overworld base template |
dimensionHeight |
{ "min": -256, "max": 512 } |
768 blocks tall, both bounds multiples of 16 |
logicalHeight |
512 |
Below the 768 total, so it is a legal contract |
fluidHeight |
50 |
Sea level at world Y 50, well below the vanilla 63 — biome generator values are measured from here |
landChance |
0.69 |
Land-heavy world |
regionZoom |
16.15 |
Continent-sized climate regions |
coordFractureZoom |
0.15 |
Aggressive coordinate warping — this is where the swirl comes from |
dimensionAngleDeg |
69 |
Off-axis rotation to break up straight borders |
regions |
frozen, hot, terralost, mushroom, forests, tundra, magnetics, temperate, estranged, tropical, swamp, prismatics |
Twelve climate regions |
mode |
omitted | Runs OVERWORLD by default |
preventLeafDecay |
true |
Custom trees keep their canopies |
caveProfile |
enabled: true |
3D caves on by default, overridden per region |
carving |
one deep-dark band, world Y -250 to -175 | Depth-banded cave biome |
ores / deposits / depositVariants |
11 / 20 / 1 | Bedrock and band generators, classic ore blobs, one deepslate remap below Y 0 |
importedStructures |
adjustments for stronghold, trial chambers, mineshaft, village | Native structures re-fitted to Iris terrain |
structures |
ancient city with nativeSuppression: REPLACE_SOURCE |
Vanilla placement replaced by an Iris-anchored one |
Build a dimension, step by step
- Create the pack:
/iris studio create name=mypackon Bukkit writes a four-file starter skeleton;/iris studio create mypackon a mod loader copies theexampletemplate instead. Either way you get a loadable pack to edit. - Open
dimensions/mypack.jsonand set the contract fields deliberately:dimensionHeight,logicalHeight,fluidHeight,environment, andmode.type. Check the multiple-of-16 rules now, not after the world exists. - Make sure every key in
regionshas a file underregions/, and that region has at least one land biome with at least one generator (12 - Regions.md,13 - Biomes.md). - Validate:
/iris pack validate pack=mypackon Bukkit,/iris pack validate mypackon modded. Fix blocking errors before opening Studio — Studio refuses to open a pack whose validation is not loadable. - Open Studio on a fixed seed:
/iris studio open mypack seed=1337on Bukkit,/iris studio open mypack 1337on modded. - Walk into fresh chunks and check the baseline: solid terrain, the build floor where you put it, fluid at the right Y, the expected biome from
/iris what biome, no unresolved-key errors in console. Fix this before touching noise. - Isolate while tuning: set
"focusRegion": "starter"or"focus": "starter", save, and generate a new area. Remove both before packaging. - Tune land/sea and zoom, then add subsystems one at a time — caves, then ores and deposits, then objects, then structures — validating after each new resource edge so a broken key is attributable.
- Close and reopen Studio after editing
dimensionHeight,logicalHeight,environment, or the dimension file name. Hotload rejects those by design. - Create the production world only after Studio is clean:
/iris create mypack-test type=mypack seed=1337. Recreate the world rather than editing its height contract later.
The baseline passes when Studio opens clean, validation reports no blocking errors, and the same seed reproduces the same terrain after a close and reopen.
Common author mistakes
| Mistake | What actually happens |
|---|---|
Empty or unresolvable regions |
No biome can be selected, so the dimension has nothing to place |
Region file exists but is not listed in regions |
It never generates; nothing warns you |
Treating fluidHeight as an offset from the build floor |
It is world Y. The engine converts it to internal Y by subtracting dimensionHeight.min |
dimensionHeight span or min not a multiple of 16 |
Passes pack validate, then fails when Iris compiles the dimension type |
logicalHeight greater than max - min |
Rejected when the dimension type is constructed |
| Editing height, logical height, environment, or the dimension file name mid-Studio | Hotload is refused by the runtime contract; close and reopen |
Expecting decoration or caves from SUPERFLAT, ENCLOSURE, or ISLANDS |
Those modes register only terrain and biome stages |
Leaving focus or focusRegion set when packaging |
The shipped pack generates exactly one biome or region |
| Changing pack files and expecting an existing world to change | Production worlds run from <world>/iris/pack/; see 27 - Example - Configuring Overworld.md |