Feature User Content Export - bh679/dungeon-train-mc GitHub Wiki

Feature — User Content Export

Pack and share everything you've built in the editor — custom carriages, parts, contents, container loot, track-side variants, and prefabs — as a single zip archive a friend can drop into their install.

Quick start

  1. Open the Dungeon Train menu in-game and enter the editor (/dt editor).
  2. Stand in any editor plot.
  3. Open the editor menu and click Export Content.
  4. A chat message confirms the export with a clickable path. Click it to reveal the file in your OS file manager.
  5. Share the zip via Discord, Drive, GitHub release, etc.

The receiver extracts the zip into their own <minecraft>/config/dungeontrain/user/ directory and restarts the game. Every saved template appears.

What gets exported

Everything under <minecraft>/config/dungeontrain/user/. That folder only ever contains content the player saved themselves — files bundled with the mod jar live on the classpath and are excluded automatically. The layout inside the zip mirrors the on-disk folder structure exactly:

dungeontrain-export-20260511-094210.zip
├── manifest.json
├── containers/
│   ├── carriage_my_train.contents.json
│   └── ...
├── contents/
│   ├── default.nbt
│   ├── weights.json
│   └── ...
├── parts/
│   ├── floor/<name>.nbt
│   └── walls/<name>.nbt
├── pillars/
│   ├── top/default.nbt
│   └── ...
├── prefabs/
│   ├── block_variants/<id>.json
│   └── loot/<id>.json
├── templates/
│   ├── standard.nbt
│   ├── standard.variants.json
│   ├── standard.parts.json
│   └── standard.contents-allow.json
├── tracks/
│   └── default.nbt
├── tunnels/
│   ├── section/default.nbt
│   └── portal/default.nbt
└── weights.json

The manifest.json at the zip root records the mod version, export timestamp, and the file list — handy for sanity-checking before extracting.

Where the user folder lives

Platform Path
macOS (Vanilla MC) ~/Library/Application Support/minecraft/config/dungeontrain/user/
Windows %APPDATA%\.minecraft\config\dungeontrain\user\
Linux ~/.minecraft/config/dungeontrain/user/
Dev checkout <repo>/run/config/dungeontrain/user/

Same path on a dedicated server: <server>/config/dungeontrain/user/.

Upgrading from older versions

If your install dates from before this change, your saved templates lived directly under config/dungeontrain/<subdir>/ (no user/ segment). The first server start after upgrading migrates each subdir automatically:

[DungeonTrain] Migrated 4 file(s) from .../dungeontrain/contents -> .../dungeontrain/user/contents
[DungeonTrain] Migrated 12 file(s) from .../dungeontrain/templates -> .../dungeontrain/user/templates

Migration runs at server start, before any registry scan. Files move with Files.move per file — a partial failure leaves the original where it was so the next start retries it. Stops touching a kind entirely once the new location already has files; you can't lose work by re-running.

If you'd rather migrate manually, just move each kind folder under dungeontrain/ into dungeontrain/user/ and you're done.

What's NOT exported

  • Mod-shipped templates (the four built-in carriages, default contents, track tiles, tunnels). Those ship with the jar and the receiver already has them.
  • Engine TOML configs (dungeontrain-client.toml, dungeontrain-server.toml). These hold per-machine preferences, not authored content.
  • Per-world ship persistence (dungeontrain/carriage-persist/). Tied to a specific save.

Command surface

  • /dungeontrain editor export — package the user folder, return a clickable chat link. Server-side, OP-level permission. Same effect as the Export Content button.

Implementation notes

  • Zip format only. Resource packs don't fit the shape — the data lives under config/ not resources/. A plain zip is the right shape for "extract this into your config".
  • Exports land in <game>/exports/dungeontrain-export-<yyyyMMdd-HHmmss>.zip. Filename collides at second-precision are resolved with a -2, -3 suffix.
  • Stateless: the exporter walks the folder and streams bytes through ZipOutputStream. No staging directory, no temp files.
  • Single-threaded and synchronous. A typical user library is dozens of KB; even a large one is a couple of MB. The chat-message round-trip is the dominant latency.

Importing a package

Drop any package zip into <game>/imports/ and restart the server (or the dev client). On launch, the mod auto-extracts each zip into <config>/dungeontrain/user/ and moves the processed archive to <game>/imports/installed/ so it doesn't re-run on the next launch.

A README.txt is written into the imports folder on first launch so the workflow is discoverable from outside the game.

Rules:

  • Files that already exist are never overwritten. If the package contains templates/standard.nbt and you already have one, the existing copy stays and the import logs a skip. To accept the imported version, move your local file aside first.
  • Path-escape entries are rejected. Zip entries whose normalised path leaves the user-content root (e.g. ../../something) are dropped with a warning — defence against malicious archives.
  • The manifest.json entry is ignored during extraction — it's metadata about the package, not a template payload.
  • Failed zips stay put. A corrupt or partially-extracted archive is left in <game>/imports/ so you can inspect or retry. Successfully-imported zips move to installed/.

To re-run the import on the same zip, move it back from installed/ into the imports folder and relaunch.

In the editor menu, Package → Open Import Folder jumps to this folder in your file manager.

Follow-ups (not in this release)

  • Per-variant export subset — export only the carriage currently in scope plus its dependencies (parts, contents allow-list, container JSON) instead of the whole library.
  • Overwrite-on-conflict toggle — let the player choose between "skip existing" (default) and "overwrite" during import.
⚠️ **GitHub.com Fallback** ⚠️