Feature World Type - bh679/dungeon-train-mc GitHub Wiki

"Dungeon Train" world type (raised y=32 floor)

Since: v0.16.0 β€” PR #20 β€” custom preset with raised y=32 floor v0.18.0 β€” PR #24 β€” 11-option Floor Y dropdown on the World tab (βˆ’64, βˆ’48, βˆ’32, βˆ’16, 0, 16, 32, 48, 64, 80, 96); y=32 remains the default v0.19.0 β€” PR #25 β€” preset is now default-selected when the Create World screen opens (via a client mixin into CreateWorldScreen.<init>) post-v0.74.0 β€” PR #105 β€” adds Dungeon Train (Nether) and Dungeon Train (End) as two new entries in the World Type dropdown; the chosen preset determines which dimension the player and starter train spawn in on first login v0.389.0 β€” PR #639 β€” removes Dungeon Train (Nether) and Dungeon Train (End) from the #minecraft:normal world-preset tag; new worlds can now only be created with an Overworld start. Existing Nether/End-start saves are unaffected β€” see Starting in the Nether or End below

Adds a custom world preset, Dungeon Train, selectable from the Create New World β†’ More β†’ World Type dropdown. It maps the overworld to a custom dimension whose floor sits at y=32 instead of vanilla's y=-64. Build height stays at y=320, so only the unused basement is removed β€” about 6 of 24 sub-chunk sections per chunk are eliminated.

Why

For a train-on-rails game where players spend their time on the surface or aboard a moving Valkyrien Skies ship, the deep underground is wasted simulation. Removing it gives:

  • CPU: ~24% fewer noise samples per chunk-gen β€” the preset ships its own noise_settings with noise.min_y=32, so the noise pipeline stops sampling discarded layers (not just the chunk dropping empty sections after the fact).
  • Disk + RAM: ~15-20% smaller region files; fewer non-empty sections in memory.

Usage

  1. Singleplayer β†’ Create New World β†’ More tab β†’ World Type dropdown
  2. Cycle through to Dungeon Train and create the world
  3. Bedrock floor sits at y=32; everything above behaves like a vanilla overworld

For dedicated servers, set level-type=dungeontrain:dungeon_train in server.properties before first launch.

What you keep, what you lose

Kept Lost
Surface terrain (mountains, rivers, oceans) Deepslate ore zone (y=-64..0) β€” including diamonds and ancient-debris-equivalent ores
Iron, coal, copper, redstone (surface ore zones) Lush + dripstone caves below y=32
All vanilla biomes (multi_noise) Strongholds and mineshafts anchored below y=32
Vanilla nether and end (unchanged) A small amount of cave detail near the new floor β€” hidden by the bedrock layer

Per-world Floor Y dropdown (v0.18.0)

PR #24 adds an 11-option Floor Y picker to the Create New World β†’ World tab, visible only when the Dungeon Train preset is selected. The selection maps the world to one of eleven internal Y-variants at the moment the user clicks Create New World; the committed save then lives at the chosen floor height for its lifetime.

Dropdown options (multiples of 16):

Y World range Use case
βˆ’64 y=βˆ’64..320 Vanilla height β€” keeps all deepslate/diamond, no perf gain
βˆ’48 y=βˆ’48..320 Clip the bottom 16 blocks of the deepslate zone
βˆ’32 y=βˆ’32..320 Keep most deepslate ores, mild perf gain
βˆ’16 y=βˆ’16..320 Keep top half of deepslate
0 y=0..320 Keep surface ores only; sea-level floor
16 y=16..320 Slightly above sea level
32 (default) y=32..320 Shipped v0.16.0 default β€” ~24% chunk-gen savings
48 y=48..320 Raised floor, preserves surface biome detail
64 y=64..320 Sea-level-equivalent floor
80 y=80..320 High floor, best perf
96 y=96..320 Extreme β€” most aggressive perf gain, smallest world

World top stays at y=320 for every option. Lower Y preserves more of the vanilla deepslate/diamond zone at the cost of chunk-gen savings; higher Y is cheaper but sacrifices ore layers.

Usage:

  1. Singleplayer β†’ Create New World β†’ World tab
  2. With World Type: Dungeon Train selected, the Floor Y row appears as a centered 150Γ—20 CycleButton below Bonus Chest
  3. Click through to the desired Y
  4. Click Create New World

Dedicated servers: set level-type=dungeontrain:dungeon_train_y{N} (e.g. dungeontrain:dungeon_train_y0, dungeontrain:dungeon_train_y96) in server.properties before first launch. For the default y=32 use dungeontrain:dungeon_train (unchanged from v0.16.0).

The dropdown selection persists across Create-World screen entries within a single game launch, so re-opening the screen after a preset cycle restores the last chosen Y.

Starting in the Nether or End (PR #105)

⚠️ Removed from new-world creation in PR #639 (v0.389.0). The Dungeon Train (Nether) and Dungeon Train (End) entries no longer appear in the Create World screen's World Type cycle β€” new worlds can only be created with an Overworld start. This section is kept for reference and for anyone maintaining a world that already started in the Nether/End; the underlying mechanism below is otherwise unchanged and those saves keep working exactly as before.

Two additional World Type entries β€” Dungeon Train (Nether) and Dungeon Train (End) β€” started the player and the auto-spawned train in minecraft:the_nether or minecraft:the_end instead of the overworld. Worldgen for those dimensions is vanilla β€” only the starting dimension changes; the overworld is still configured exactly like the plain Dungeon Train preset (raised y=32 floor) and remains accessible via portals.

Usage (legacy β€” no longer reachable from the Create World UI):

  1. Singleplayer β†’ Create New World β†’ World tab
  2. Cycle the World Type button to one of:
    • Dungeon Train β€” start in overworld (default, and now the only UI-selectable option)
    • Dungeon Train (Nether) β€” start in the Nether
    • Dungeon Train (End) β€” start in the End
  3. Click Create New World β€” on first login the player is teleported to a random ground position alongside the train in the chosen dimension.

The Floor Y dropdown is hidden for the Nether/End presets (it only affects the overworld bedrock floor). The Dungeon Train Options… sub-screen still applies β€” Train Y, carriage dimensions, generation mode, and group size all work the same in any starting dimension.

Persistence: the chosen dimension is committed to dungeontrain_world.dat (the existing per-world SavedData) as a startingDimension NBT tag, defaulting to overworld for legacy worlds. This is why existing Nether/End-start saves are unaffected by the removal above β€” the preset files and the StartingDimension enum are all still in place; only the tag entry that made them reachable from a new Create World screen was removed.

Known limitations:

  • Death/respawn is a separate mechanism, partially restricted since. StartingDimension.rollRespawnDimension independently rolled a fresh 94% Overworld / 5% Nether / 1% End dimension on every death. As of PR #643 (v0.390.0), the death screen's "New World"/"Same World" buttons (DeathScreenLayoutHandler, plus the dev-only /new-world command which shares the same code path) always start the fresh save in the Overworld β€” they create a new world, so the same "Overworld by default" intent as this page applies. The vanilla in-place "Respawn" button (RespawnDimensionEvents) is intentionally unchanged and still rolls the 94/5/1 split, since it's a deliberate run-variance mechanic that doesn't create a new world. See Feature-Death-Screen-Buttons for the full mechanism.
  • Default Train Y (78) in the End places the train above the central island; in the Nether it sits well above the lava ocean and below the ceiling. Both can be overridden via the Dungeon Train Options sub-screen if the user wants a different elevation for that biome.

Dedicated servers: level-type=dungeontrain:dungeon_train_nether or dungeontrain:dungeon_train_end in server.properties still works for anyone who sets it explicitly (the preset registry entry still exists) β€” only the graphical World Type cycle button no longer surfaces these two options.

Files (datapack + client mixins)

File Purpose
data/dungeontrain/dimension_type/overworld.json Default DimensionType with min_y=32, height=288 (y=32 preset)
data/dungeontrain/dimension_type/overworld_y{N}.json (10 files) Y-variant DimensionTypes; min_y=N, height=320-N
data/dungeontrain/worldgen/noise_settings/overworld.json Vanilla overworld noise_settings with noise.min_y=32, noise.height=288
data/dungeontrain/worldgen/noise_settings/overworld_y{N}.json (10 files) Y-variant noise_settings (only noise.min_y + noise.height differ)
data/dungeontrain/worldgen/world_preset/dungeon_train.json Default preset (y=32); nether/end reference vanilla
data/dungeontrain/worldgen/world_preset/dungeon_train_y{N}.json (10 files) Y-variant presets referencing the matching DimensionType + noise
data/dungeontrain/worldgen/world_preset/dungeon_train_nether.json Same dimension config as dungeon_train.json; the preset ID is the marker that signals "start the player in the Nether" (PR #105)
data/dungeontrain/worldgen/world_preset/dungeon_train_end.json Same shape as the Nether variant; signals "start in the End" (PR #105)
data/minecraft/tags/worldgen/world_preset/normal.json Lists only dungeon_train as of v0.389.0 (PR #639) β€” dungeon_train_nether/dungeon_train_end were removed so the UI selector shows one entry; both preset files still exist and resolve by key for legacy saves + the death-screen carry-forward flow. Y-variants remain intentionally out of the tag (the registry resolves them by key instead)
src/.../world/StartingDimension.java Enum mapping preset path β†’ dimension ResourceKey<Level> and NBT id (PR #105)
src/.../client/worldgen/PendingStartingDimension.java Client-side static holder (mirrors FloorYState); updated each tick from the current preset path; consumed once on integrated-server start (PR #105)
assets/dungeontrain/lang/en_us.json generator.dungeontrain.dungeon_train* keys all resolve to "Dungeon Train" so the preset button label stays consistent; dungeontrain.floor_y.* keys for the widget label/value/tooltip
src/.../mixin/CreateWorldScreenWorldTabMixin.java @Inject at <init> TAIL of CreateWorldScreen$WorldTab; appends the Floor-Y row at hardcoded row index 5
src/.../mixin/CreateWorldScreenMixin.java init TAIL resolves the 11 preset holders into FloorYState; tick HEAD toggles widget visibility + re-applies the chosen Y on transitions back onto the plain DT preset
src/.../mixin/CreateWorldScreenAccessor.java @Accessor exposing the package-private uiState field
src/.../client/worldgen/FloorYState.java Client-side static holder for selected Y + per-screen widget + preset-holder map

Known limitations / follow-ups

  • Disk footprint: ships 10 near-identical copies of the 2,541-line noise_settings/overworld.json (one per non-default Y), ~900 KB uncompressed. A refactor to dynamic runtime registration (approach b from the Gate 1 plan) is tracked as a follow-up if size becomes an issue.
  • Preset cycling quirk: cycling the World Type button forward while a Y-variant is active falls back to the plain dungeon_train preset (vanilla's values.indexOf(current) returns βˆ’1 when the Y-variant isn't in the selector list, so it resets to index 0). From there, one more forward-cycle reaches Default. The tick handler explicitly does not re-apply Y when the user has just cycled from one DT variant to another β€” only on transitions from a non-DT preset back onto DT.
  • Vanilla density functions still reference absolute Y, so the new floor may produce small swiss-cheese caves just above bedrock β€” visually hidden, no gameplay impact.
  • Existing worlds are unaffected. Only new worlds created with the Dungeon Train preset get the raised floor. Vanilla saves continue to work normally. Worlds created with a non-default Y on v0.18.0+ require the mod at v0.18.0 or later to continue loading (normal mod-version behavior; no migration).
⚠️ **GitHub.com Fallback** ⚠️