Repository navigation
Blog 2026 04 26
The editor got a massive overhaul: a world-space part-position panel with weighted variants and side-modes, a world-space block-variant menu with lock groups, and a new Exit button. Auto-promote landed for weights and part assignments, the classpath scanner unified template discovery, and public-release assets (LICENSE, mods.toml, logo) shipped. 24 PRs merged.
Note: The GitHub Release pipeline (CI workflows) shipped the following morning. These changes are available from v0.70.0 onwards — see Downloads for the latest jar.
Tap Z while looking at a block inside any editor plot (carriage / contents / part / track) to open a billboarded panel anchored to the targeted face. The panel lists every candidate block with its name and weight, and a six-cell toolbar: Copy | Add | Lock | Remove | Clear | X.
-
Add captures the player's main hand; empty hand adds the air-sentinel (
"nothing"). -
Copy produces a
dungeontrain:variant_clipboarditem (styled after a command block) that carries the full variant list and lock-id in NBT. -
Lock groups — clicking Lock cycles the cell's lock-id
0 → nextFreeLockId() → 0. Cells with the same non-zero lock-id share their state list (auto-propagated on edit) and share their random pick at spawn. The only way two cells join a group is via Copy/Paste. - Hold-Z + right-click still appends a held block — the legacy flow is preserved; tap vs. hold is detected client-side (≤ 8-tick press without an interaction = tap).
-
Schema bumped v3 → v4. Cells with
lockId > 0serialize as{ "lockId": K, "states": [...] };lockId = 0cells remain bare arrays so v3 sidecars round-trip diff-clean. - Protocol bumped 4 → 5 with three new packets:
BlockVariantSyncPacket(S2C),BlockVariantEditPacket(C2S),BlockVariantMenuTogglePacket(C2S). - First
DeferredRegister<Item>in the project (the clipboard item).
A billboarded panel auto-opens anchored on the inward face of FLOOR / WALLS / ROOF / DOORS regions inside carriage variant plots. Toolbar: Add | Remove | Clear | X. Each entry shows its weight; walls and doors also show a 3-state side-mode toggle: (2) both sides, (1) one side, (1|2) either side, rolled deterministically per (seed, carriageIndex, kind).
- Slash-command parity:
/dungeontrain editor part addnow accepts an optional[weight]arg. -
Schema bump to
.parts.jsonv2: entries become{ name, weight[, sideMode] }. Full back-compat for v1 string entries (loaded as weight=1, sideMode=BOTH); on first save the file is rewritten in v2 form. - Protocol bumped 3 → 4. Three new packets:
PartAssignmentSync(S2C),PartAssignmentEdit(C2S; ops ADD/REMOVE/CLEAR/BUMP_WEIGHT/CYCLE_SIDE_MODE),PartMenuToggle(C2S). -
EditorMenuScreengains a "Part Variant Menu" toggle row;/dungeontrain editor partmenu on|offmirrors it.
PillarAdjunct.STAIRS templates had full world-side infrastructure but were missing from EditorModel's sealed dispatch — so the row never appeared in category iteration, the HUD didn't recognise the plot, and /dt save all skipped them. Adds EditorModel.AdjunctModel and wires every instanceof EditorModel.* cascade across SaveCommand, ResetCommand, EditorCommand, and VariantOverlayRenderer.
Stair plots now appear next to pillars in the Tracks category with their own row of variants. A new bundled sleeperless.nbt track template also ships with this PR.
New bundled templates committed to src/main/resources/data/dungeontrain/:
pillars/adjunct_stairs/ladder.nbttracks/sleepside.nbt- Refreshed
pillars/adjunct_stairs/default.nbtandtracks/sleeperless.nbt
Also fixes a bug in VariantOverlayRenderer.modelNameFor() where the missing AdjunctModel case caused the editor weight row to persist bogus entries like {"adjunct_stairs": 20} to weights.json. Bundled weights are now clean: adjunct_stairs/weights.json = {"default": 20}.
The bottom < Back row in EditorMenuScreen is replaced with an Exit button that runs dungeontrain editor exit. Previous behaviour merely popped the menu stack, leaving the player stranded inside the editor plot. Exit now fully unwinds the session, clears the editor plots, and teleports the player back to where they entered. EnterCategoryMenuScreen retains its < Back for the drilled-in sub-screen.
Every in-game weight edit (/dt editor weight, the [-] Weight (N) [+] HUD row) now writes to both config/dungeontrain/.../weights.json (local override) and src/main/resources/data/dungeontrain/.../weights.json (bundled default). The auto-promote is gated on sourceTreeAvailable() — end-user installs are unaffected.
All four template registries — CarriageVariantRegistry, CarriageContentsRegistry, CarriagePartRegistry, TrackVariantRegistry — now use a shared BundledNbtScanner that walks the classpath at server start. Drop a new .nbt into src/main/resources/data/dungeontrain/... and it auto-registers; no manifest update required. Handles file:, jar:, and Forge's union: URL schemes.
The same source-tree write-through from #73 now applies to per-carriage part assignments edited via the in-world block-variant menu. Every menu mutation writes to both config/dungeontrain/templates/<id>.parts.json and src/main/resources/data/dungeontrain/templates/<id>.parts.json. No devmode on toggle required; the gate is purely whether src/main/resources/ is writable.
Both the block-variant menu and the part-variant menu now reject duplicate entries at insertion time, keeping variant lists clean without needing a manual dedup pass.
New bundled parts: additional roof and wall pieces plus a windowed carriage template. Existing content received polish updates.
Clicking an entry name in the block-variant menu or the parts menu now previews that block or part in-place inside the plot so you can audition options visually without committing the change.
Each block-variant entry now carries its own rotation mode: lock (use the source block's exact rotation), random (randomise on place), or options (cycle through a listed set). The editor shows a live preview of the selected mode while authoring.
LICENSE (MIT), mods.toml metadata fields, and the refreshed mod logo are committed in preparation for the first public release.
CarriagePartEditor was the only editor using Blocks.BARRIER for its outline cage. Barriers are invisible in survival, so the parts grid (FLOOR / WALLS / DOORS / ROOF rows) appeared as floating templates while the carriage row above had clear bedrock bounds. One-line change switches OUTLINE_BLOCK to Blocks.BEDROCK for visual consistency across the entire carriages-editor scene.
The auto-opening part-position panel now early-returns when CommandMenuState.isOpen(), so it hides the moment the worldspace X menu opens. When X closes, the panel pops back on whatever the crosshair is now on.
Breaking a block inside an editor plot now clears its associated variant entry, so stale variant data can no longer accumulate on air blocks.
Paste operations carry the source block's texture through correctly. The lock-id indicator now renders on all six faces of the target block.
Pressing Remove now fully clears both the plot's block content and its surrounding bedrock cage, leaving no ghost geometry.
The block-variant context menu anchor froze at the wrong screen position when the player moved after opening the menu. The anchor is now recaptured on every click.
Lost block-variant data (entries that went missing after certain editor operations) is now recovered correctly. In dev mode, the variant sidecar is auto-promoted to the source tree so edits persist across restarts.
Renaming a part now releases the old name immediately. Previously the old name stayed reserved until a restart, making it impossible to re-use it within the same session.
A test that expected a 3-entry palette in adjunct_stairs/default.nbt was failing after the bundled template was refreshed to 7 entries. The test was deleted rather than updated — it tested the shape of a specific NBT file rather than behaviour, so it provided little ongoing value.