8.1 KiB
25 - Pack Management
Pack management covers download/install into the packs workspace, validation, unused-resource cleanup and restore, packaging for distribution, and unsafe replacement of a live world’s pack snapshot. Authoring packs live under the platform packs root; production worlds copy that tree into <world>/iris/pack (see 05 - Concepts & Pack Layout.md and 06 - Worlds & Lifecycle.md).
See also: 03 - Configuration.md, 04 - Commands & Permissions.md, 10 - Studio & VSCode Schemas.md, 24 - Pack Mods & Snippets.md, 27 - Example - Configuring Overworld.md.
Pack workspace
| Item | Path / rule |
|---|---|
| Packs root | Bukkit: plugin data packs/; modded: config/irisworldgen/packs/ (platform data folder) |
| Visible packs | Non-hidden directories listed by PackDirectoryResolver |
| Presence | Pack exists if it has safe tree + at least one dimensions/*.json (parse failures do not trigger redownload) |
| Safe key | Download destination keys: [a-z0-9_-]+ |
Download
Commands
| Command | Behavior |
|---|---|
Bukkit: /iris download <pack> [branch=stable] [overwrite=false]; modded: /iris download <pack> [branch] [force] |
Download into packs root |
| Default overworld special case | Pack name overworld uses IrisDimensions overworld beta release zip (…/releases/download/beta/overworld.zip), not an arbitrary branch zip |
| Other packs | IrisDimensions/<pack>/<branch> GitHub archive search via StudioSVC.downloadSearch |
| Param | Default | Notes |
|---|---|---|
pack |
required | Folder/key or repo short name |
branch |
stable |
GitHub ref when not default overworld |
overwrite |
false |
Force replace existing present pack |
Install pipeline (PackDownloader)
- Per-key/ref download lock (concurrent startup and commands do not double-fetch).
- If pack present and not force → skip network.
- Download zip (size/entry limits: archive ≤512MiB, ≤100k entries, total uncompressed budget, per-file cap).
- Unpack to temp; require single pack home directory.
- Open as datapack-compiler
IrisData; require exactly one dimension; key = that dimension load key. - Run
PackValidator.validate; blocking errors abort install. - Publish into
packs/<key>/with conflict checks (refuses symlink targets; detects dimension-key conflicts with other folders).
Default overworld repository constant: IrisDimensions/overworld.
Validate
| Command | Behavior |
|---|---|
Bukkit: /iris pack validate [pack=<key>]; modded: /iris pack validate [pack] |
Validate one pack or all visible packs; publish into PackValidationRegistry |
Bukkit: /iris pack status [pack=<key>]; modded: /iris pack status [pack] |
Show cached registry results (run validate first) |
Checks performed (PackValidator)
| Check | Blocking vs warning |
|---|---|
Missing pack / missing dimensions/ / no dimension JSON |
Blocking |
Dimension JSON integrity (PackDimensionValidator) |
Blocking / warnings as emitted |
Loot graph (PackLootValidator) |
Blocking |
Removed worldgen fields (e.g. fluidBodies) |
Blocking |
| Object surface support | Blocking |
Unsupported structure transforms (rotation / translate / scale on forbidden surfaces) |
Blocking |
| Structure graph + compiled graph validator | Errors blocking; warnings advisory |
| Native structure replacement envelopes | Blocking |
| Spawner → entity references | Blocking |
| Custom biome spawns category resolution | Blocking |
Content keys / bad block properties (ContentKeyValidator) |
Blocking when general.strictContentKeys or -Diris.strictContent; else warnings (palette-sourced stay advisory) |
isLoadable() is false when any blocking error exists. Status reports blocking count and up to 10 warnings (plus “more” count).
Cleanup (unused resources)
| Command | Mode | Behavior |
|---|---|---|
Bukkit: /iris pack cleanup <pack> [mode=preview]; modded: /iris pack cleanup <pack> [apply] |
preview (default) |
List unused candidates; no writes |
apply |
Quarantine candidates under pack .iris-trash/<timestamp>/ |
Managed folders scanned for unreferenced JSON resources: biomes, regions, entities, spawners, loot, generators, expressions, markers, blocks, mods.
Excluded from cleanup corpus: .iris-trash, datapack-imports, externaldatapacks, internaldatapacks, datapacks, cache, objects, .iris.
Cleanup re-scans on apply (not a blind apply of an old preview). Failed apply may leave paths still quarantined and reports them.
Restore
| Command | Mode | Behavior |
|---|---|---|
Bukkit: /iris pack restore <pack> [mode=preview]; modded: /iris pack restore <pack> [apply] |
preview |
List latest quarantine dump files and conflicts |
apply |
Move files back from latest dump if destinations free |
Restore refuses when destination paths already exist (conflict list). Nothing restored when no quarantine dump exists.
Package (export)
| Command | Behavior |
|---|---|
Bukkit: /iris studio package [dimension=default] [obfuscate=false] [minify=true]; modded: /iris studio package [pack] |
Compile dimension closure to a zip |
| Param | Default | Notes |
|---|---|---|
dimension |
contextual / default |
Dimension in packs |
obfuscate |
false |
Obfuscate packaged content when true |
minify |
true |
Compact JSON (indent 0) |
Pipeline (IrisPackageCompiler):
- Load dimension and walk regions → biomes → generators, loot, entities, spawners, structures/objects closure.
- Stage under Iris data
exports/<dimensionKey>/. - Write
package.jsonwith hash, time, version. - Zip to
exports/<dimensionKey>.iris(compression level 9); delete staging folder.
Does not modify the source pack or any world snapshot.
Developer update-world (unsafe)
| Command | Behavior |
|---|---|
/iris developer update-world world=<world> pack=<dimension> confirm=true [fresh-download=false] |
Replace the world’s pack snapshot |
| Param | Default | Notes |
|---|---|---|
world |
contextual | Target world folder |
pack / dimension |
contextual | Source dimension (live packs root) |
confirm |
false |
Required true; otherwise prints warning only |
fresh-download |
false |
Re-download pack before install |
Implementation:
- Requires
confirm=true. - Optional
StudioSVC.downloadSearchwhenfresh-download. - Acquires
PACK_MUTATION/PACK_PUBLISHlease. StudioSVC.replaceIntoWorld→ install intoworldFolder/iris/packwithreplaceExisting=true(atomic stage/publish).- If an engine still holds that pack data, Iris restarts the server after commit (
"An active Iris world pack was replaced.").
This is intentionally unsafe for production without backups: existing chunks keep old terrain; only future generation and pack-driven systems see new content. Prefer staging a new world when pack contracts change.
Related operations
| Task | Where |
|---|---|
| Create studio project from template | /iris studio create (10 - Studio & VSCode Schemas.md) |
| Open VSCode + schemas | /iris studio vscode |
| Import vanilla objects/structures into pack | /iris studio importvanilla |
| Structure import | /iris structure … |
| Strict content keys | settings.general.strictContentKeys (03 - Configuration.md) |
| Datapack bootstrap / install | Server configurator + /iris datapack (see platform docs) |
Operator checklist
- Download or place pack under
packs/<key>/withdimensions/*.json. - On Bukkit, run
/iris pack validate pack=<key>until loadable. Modded uses/iris pack validate <key>. - On Bukkit, optionally run
/iris pack cleanup <key> mode=preview, thenmode=applyafter review; restore if needed. Modded uses theapplyliteral. - Create world with
/iris create …(copies pack) or open studio for live edit. - To ship on Bukkit:
/iris studio package dimension=<dimension>. - To refresh an existing world pack only after backup:
/iris dev update-world world=<world> pack=<dimension> confirm=true.