# 10 - Studio & VSCode Schemas Studio is the live pack-authoring loop: open a pack as a throwaway world, edit its JSON in an editor that autocompletes against schemas generated from the Java models, save, and watch the running engine rebuild itself. This page walks the loop end to end first, then documents the commands, the hotload rules, and how the schemas are produced. Related: see `04 - Commands & Permissions.md`, `05 - Concepts & Pack Layout.md`, `02 - Getting Started.md`, `11 - Dimensions.md`, `21 - Jigsaw Structures.md`, `25 - Pack Management.md`, `30 - Platform Differences.md`. ## The edit loop Prerequisites: a writable packs directory, operator access on Bukkit or gamemaster access on a mod loader, and VSCode/Cursor (or IntelliJ) on the machine that holds the pack folder. Keep the server console visible — hotload reports success and failure there. ### Bukkit-family 1. **Create a project.** `/iris studio create name=tutorial` Writes `packs/tutorial/` with a dimension, region, biome, generator, and a `tutorial.code-workspace`. The command reports the completed project path; creation runs asynchronously and may report that a restart is needed before the pack can be opened. 2. **Open it as a world.** `/iris studio open tutorial seed=1337` You are teleported into a transient world generated from the live pack folder. A fixed seed matters — you will be comparing the same coordinates across reloads. 3. **Open the editor workspace.** `/iris studio vscode dimension=tutorial` Generates `.iris/schema/*` if missing and opens the `*.code-workspace`. On a headless server nothing launches; copy the pack folder to your machine and open the workspace file yourself. *Success condition:* typing `"` inside any object in `biomes/starter.json` offers field names, and hovering a field shows its description, type, and default value. If it does not, the workspace was not opened or the schemas were never written — run `/iris studio update dimension=tutorial`. 4. **Make one change.** Edit `packs/tutorial/biomes/starter.json` and change only its display `name`. Save once. 5. **Wait for the hotload result** in console before saving anything else. A failed hotload leaves the previous runtime active and reports the error; stacking more edits on top makes the first failure hard to find. 6. **Verify in fresh terrain.** Walk into chunks that have never generated and run `/iris what biome`. The new display name appears there. Hotload never rewrites blocks that already exist, so standing still and expecting the world to change is the usual false negative. 7. **Validate.** `/iris pack validate pack=tutorial` — no blocking errors. 8. **Close.** `/iris studio close` ### Fabric / Forge / NeoForge Same loop, positional arguments, and the modded studio create always copies a template (`example` by default): 1. `/iris studio create tutorial example` 2. `/iris studio open tutorial 1337` 3. `/iris studio vscode tutorial` 4. Trace the active dimension to one referenced biome, change one display or palette value, save once. 5. Wait for the hotload result, then enter newly generated terrain and check it with `/iris what biome`. 6. `/iris pack validate tutorial`, then `/iris studio close`. The loop passes when the editor binds the generated schema, hotload succeeds, validation reports no blocking errors, and newly generated chunks show the change. Create a production world only after that gate. A rejected height or dimension-type change is not evidence that hotload is broken — those are refused by design. See **Hotload rules** below. ### When something goes wrong | Symptom | Meaning | Recovery | |---|---|---| | `open` reports startup validation pending, missing, failed, restart-required, or blocking pack errors | Datapacks or the pack graph cannot safely build an engine | Complete the requested restart or run the platform's `pack validate` form, fix the first blocking error, and retry; do not bypass validation | | Save reports hotload failure | The new data or runtime build failed; the previous runtime may remain active | Fix the first console error and save again before making unrelated edits | | Height, logical height, or dimension type change is rejected | The edit violates `IrisDimensionRuntimeContract` | Close Studio and reopen; on modded, restart when regenerated dimension-type datapacks require a registry reload | | A valid change is invisible | The chunks you are standing in are already materialized, or the edited resource is unreachable from the active dimension | Move to new chunks; trace dimension → region → biome to confirm the resource is actually referenced; use `focus`/`focusRegion` or a buffet studio mode to isolate | | No autocomplete, or resource keys are stale | Schemas were not generated or refreshed, or the editor never opened the workspace | Run `/iris studio update`, then open the pack's `.code-workspace`; on headless servers open it manually | | The Studio world disappears after a restart | Studio worlds are transient and purged on purpose | Reopen the pack; `packs//` is the source of truth, not the world folder | ## What Studio is | Concept | Behavior | |---------|----------| | Pack workspace | Packs live under the platform data directory in the folder named `packs` (`StudioSVC.WORKSPACE_NAME`) | | Studio world | Opened from a pack dimension key; uses a studio chunk generator bound to the live pack folder with file watching | | Hotload | Studio worlds only. A low-priority looper polls pack files; on change, `EngineHotloader` waits for already-admitted top-level Bukkit chunk stages, reloads the pack data, and rebuilds the engine runtime under exclusive generator control. Fair stage admission keeps later chunk stages behind the waiting transition, and Studio close uses the same drain boundary. Biome Buffet resolves its chunk focus and completes any required complex hotload under exclusive admission before that noise stage opens a generation session, then downgrades directly to one ordinary stage permit | | Hotload contract | `IrisDimensionRuntimeContract` refuses hotload if the dimension type key, min height, total height, or logical height change | | Non-studio worlds | No pack file watcher. Production worlds keep the pack snapshot installed at create or update time | Studio settings live in `settings.json` under `studio` (`IrisSettings.IrisSettingsStudio`): | Key | Default | Meaning | |-----|---------|---------| | `openVSCode` | `true` | When true and the JVM is not headless, `open`/`vscode` may launch the desktop opener on the pack's `*.code-workspace`. Set false on servers where a desktop launch would be pointless or unwanted | | `entitySpawning` | `true` | Only affects Studio worlds. False stops Iris ambient entity spawning there; production worlds always spawn regardless of this key | | `disableTimeAndWeather` | `true` | Present in the settings model but not read by any code path today | | `autoStartDefaultStudio` | `false` | Present in the settings model but not read by any code path today | ## Hotload rules - The watcher runs only when `PlatformChunkGenerator.isStudio()` is true, the world is not closing, and no Jigsaw Studio session is active. Jigsaw Studio deliberately suppresses ordinary pack-file hotload. - On change: load a new `IrisData` from the same folder, reload the dimension key, check the hotload contract, build a new engine runtime, retire the previous data, refresh the workspace and schemas, reload datapacks when a platform world is bound, and broadcast a client studio-hotload toast on success or failure. - `hotloadComplex` is a narrower rebuild that reconstructs `IrisComplex` without reopening the pack. - A failed hotload rolls the runtime back where possible and reports the error. Four values are pinned for the life of the world and cannot hotload: the dimension type key (derived from the dimension load key), min height, total height, and logical height. Editing `dimensionHeight`, `logicalHeight`, `environment`, or the dimension file name means closing and reopening Studio. See `11 - Dimensions.md`. ## Commands (Bukkit) Root: `/iris studio`, aliases `std` and `s`. Implemented by `CommandStudio` and `StudioSVC`. Keyed arguments; the first column shows the primary subcommand name. | Subcommand | Aliases | What it does | |------------|---------|--------------| | `open [seed=1337]` | `o` | Closes any open studio and opens the pack as a studio world. Blocked unless startup datapack validation is ready and the selected pack has a loadable validation result | | `close` | `x` | Closes the active studio project and world | | `create [name=studio] [template=]` | `+` | Creates a pack under `packs/` after startup validation is ready. With a template, that template must itself validate as loadable and is downloaded first if missing; without one, writes the starter skeleton below | | `vscode [dimension=default]` | `vsc` | Opens the pack's VSCode workspace, generating it if missing | | `update [dimension=default]` | | Rewrites `/.code-workspace` and queues regeneration of `.iris/schema/*` | | `version [dimension=default]` | | Prints the dimension's `version` field | | `pkg [dimension=default] [obfuscate=false] [minify=true]` | `package` | Compiles the pack into a distributable archive | | `importvanilla [variants=3] [structures=true]` | `importv`, `iv` | Captures vanilla features and structures into the pack through Bukkit NMS | | `scoreboard` | `board`, `sidebar`, `sb` | Toggles the studio debug scoreboard; player must be in the studio world | | `noise [generator=] [seed=12345]` | `nmap` | Opens the external noise explorer GUI | | `map [world=]` | `render` | Opens the external biome/terrain map GUI for an Iris world | | `regions [radius=500]` | | Samples region rarity over a chunk spiral; player must be in an Iris world | | `loot [fast=false] [add=true]` | | Opens a virtual chest showing loot tables for the block under the player | | `profile [dimension=default]` | | Writes a pack performance profile report | | `spawn` | `summon` | Spawns a pack entity definition at the player | | `tpstudio` | `stp` | Teleports to the active studio world spawn in creative | | `objects` | `find-objects` | Captures a nearby-chunk object placement report | Permissions and the full `/iris` tree: see `04 - Commands & Permissions.md`. ## Commands (Modded) `/iris studio` on Fabric, Forge and NeoForge is implemented by `ModdedStudioCommands` with positional arguments. Supported: `create`/`+`, `package`/`pkg`, `version`, `regions`, `open`/`o`, `close`/`x`, `tpstudio`/`stp`, `status`, `vscode`/`vsc`, `update`, `noise`/`nmap`, `map`/`render`. `create` with no arguments creates a project named `studio` from the `example` template; `create ` uses the same template; `create