mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-08-27 12:41:43 +00:00
d
This commit is contained in:
+209
-169
@@ -1,19 +1,45 @@
|
||||
# 03 - Configuration
|
||||
|
||||
Iris stores shared runtime settings in `settings.json` under the platform data folder. On first boot Iris writes a full defaults file if missing; every successful load rewrites the file so new keys appear with defaults. See `01 - Installation & Platforms.md` for data paths and `33 - Performance Tuning.md` for tuning guidance.
|
||||
Iris keeps its shared runtime settings in `settings.json` under the platform data folder. On first boot Iris writes a full defaults file if one is missing, and every successful load rewrites the file so new keys appear with defaults. Bukkit adds `compat.json`; mod loaders add `modded.json`. See `01 - Installation & Platforms.md` for data paths and `33 - Performance Tuning.md` for how to measure a tuning change.
|
||||
|
||||
## Tutorial: change one setting safely
|
||||
## What you actually need to change
|
||||
|
||||
The shipped defaults are correct for almost every server. Most operators only ever touch a handful of keys:
|
||||
|
||||
| You want to | Change |
|
||||
|---|---|
|
||||
| Run the server in another language | `general.language` |
|
||||
| See why generation is behaving oddly | `general.debug`, or `/iris debug` |
|
||||
| Stop Iris opening desktop windows on the host | `gui.useServerLaunchedGuis`, `studio.openVSCode` |
|
||||
| Survive pregen on a memory-constrained box | `pregen.maxResidentTectonicPlates`, the `performance.*CacheSize` keys |
|
||||
| Turn on the survival tree feller | `treeFeller.enabled` |
|
||||
| Catch broken pack keys instead of silently ignoring them | `general.strictContentKeys` |
|
||||
|
||||
Everything else is either already right, only meaningful while diagnosing a specific problem, or inert on your platform. Each table below marks which is which.
|
||||
|
||||
## File locations
|
||||
|
||||
| Platform | Shared settings | Packs root | Platform-only config |
|
||||
|----------|-----------------|------------|----------------------|
|
||||
| Bukkit / Paper / Folia | `plugins/Iris/settings.json` | `plugins/Iris/packs/` | `plugins/Iris/compat.json` |
|
||||
| Fabric / Forge / NeoForge | `<configDir>/iris/settings.json` | `<configDir>/irisworldgen/packs/` | `<configDir>/irisworldgen/modded.json` |
|
||||
|
||||
`<configDir>` is the loader config directory (game `config/` on Fabric, Forge, and NeoForge). Both surfaces use the same `IrisSettings` schema for `settings.json`.
|
||||
|
||||
The modded split is real and easy to get wrong: the engine data folder is `<configDir>/iris`, but installed packs, the generated datapack, and `modded.json` live under `<configDir>/irisworldgen`. Iris also creates an empty `<configDir>/iris/packs` directory; that is not the pack root and putting a pack there will not load it.
|
||||
|
||||
## Changing a setting safely
|
||||
|
||||
1. Start Iris once so it writes the current schema and defaults.
|
||||
2. Copy `settings.json` outside the server directory as a rollback file.
|
||||
3. Change one key only. Keep its JSON type unchanged; quoted numbers and strings such as `"false"` are not booleans.
|
||||
4. Save the file and use `/iris reload`, or wait for the platform hotload interval described below.
|
||||
5. Confirm the console reports the settings reload without a parse exception.
|
||||
6. Exercise the affected feature. For performance or thread-pool settings, restart before judging the result because some values are read when services are constructed.
|
||||
3. Change one key. Keep its JSON type: quoted values such as `"false"` are strings, not booleans.
|
||||
4. Save the file, then run `/iris reload` or wait for the hotload poll (about 3 seconds on both platforms).
|
||||
5. Confirm the console logs `Hotloaded settings.json` or the reload success message, with no parse error.
|
||||
6. Exercise the affected feature. If nothing changed, check the "Takes effect" column below — several keys are captured when a service, pool, or cache is constructed and need a restart.
|
||||
|
||||
If parsing fails, restore the saved file and restart. Do not delete `settings.json` unless resetting every setting to defaults is intentional.
|
||||
If parsing fails, restore the saved file and restart. Do not delete `settings.json` unless resetting every setting to defaults is what you want.
|
||||
|
||||
For example, to change only the server locale, edit the existing `general` object in place:
|
||||
To change only the server locale, edit the existing `general` object in place:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -23,201 +49,213 @@ For example, to change only the server locale, edit the existing `general` objec
|
||||
}
|
||||
```
|
||||
|
||||
This fragment shows the field location; do not replace a populated settings file with the fragment. After `/iris reload`, run `/iris help` and confirm the selected locale is active. Iris rewrites the complete settings file after a successful load, including defaults for fields that were absent.
|
||||
That fragment shows the field location; do not replace a populated settings file with it. After `/iris reload`, run `/iris help` and confirm the selected locale is active. Iris rewrites the complete settings file after a successful load, including defaults for fields that were absent.
|
||||
|
||||
### Validation and rollback
|
||||
|
||||
| Result | Meaning | Action |
|
||||
|---|---|---|
|
||||
| Reload succeeds and the affected feature changes | File parsed and the setting reached a live reload path | Keep the backup until the next clean restart |
|
||||
| Reload succeeds but behavior is unchanged | Setting is read only when a service or engine is constructed | Restart, then retest the same workload |
|
||||
| Parse exception or requested locale rejected | JSON shape, type, or locale is invalid | Restore the backup, reload, and make one smaller edit |
|
||||
| File is rewritten with defaults | Missing fields were normalized by `IrisSettings` | Reapply only intentional overrides; do not restore an obsolete full file over new defaults |
|
||||
| Modded and Bukkit paths differ | The wrong data root was edited | Use the path table below and confirm the changed file timestamp before reloading |
|
||||
|
||||
## File locations
|
||||
|
||||
| Platform | Shared settings | Packs root | Modded-only config |
|
||||
|----------|-----------------|------------|--------------------|
|
||||
| Bukkit / Paper / Folia | `plugins/Iris/settings.json` | `plugins/Iris/packs/` | — |
|
||||
| Fabric / Forge / NeoForge | `<configDir>/iris/settings.json` | `<configDir>/irisworldgen/packs/` | `<configDir>/irisworldgen/modded.json` |
|
||||
|
||||
`<configDir>` is the loader config directory (game `config/` for Fabric/Forge/NeoForge). Both surfaces use the same `IrisSettings` schema for `settings.json`.
|
||||
| Reload succeeds and the feature changes | The file parsed and the setting is read live | Keep the backup until the next clean restart |
|
||||
| Reload succeeds but behavior is unchanged | The value was captured when a service, pool, or cache was built | Restart, then retest the same workload |
|
||||
| Parse error in console, file unchanged | Gson threw before the rewrite, so your broken file is still on disk and Iris is running built-in defaults | Fix the JSON, reload; restore the backup if you cannot |
|
||||
| File is rewritten with defaults | Missing or unknown fields were normalized by `IrisSettings` | Reapply only intentional overrides; do not restore an obsolete full file over new defaults |
|
||||
| Modded and Bukkit paths differ | The wrong data root was edited | Use the path table above and confirm the file timestamp changed before reloading |
|
||||
|
||||
## Load, save, hotload
|
||||
|
||||
| Action | Behavior |
|
||||
|--------|----------|
|
||||
| First boot | Create `settings.json` with current defaults if the file is absent |
|
||||
| Load | Parse with Gson into `IrisSettings`; on parse failure log and keep empty defaults for that boot |
|
||||
| After load | Rewrite `settings.json` (pretty JSON) so new keys and migrated values persist |
|
||||
| `/iris reload` | Invalidate cached settings, re-read `settings.json`, reload locale |
|
||||
| Hotload (Bukkit) | `SettingsHotloadWatch` via VolmLib `ConfigHotloadEngine`; on content change invalidates, reloads, reloads language, logs `Hotloaded settings.json` |
|
||||
| Hotload (modded) | `ModdedSettingsHotloadService` polls every 3s; on `lastModified` change invalidates, reloads, reloads language, logs `Hotloaded settings.json` |
|
||||
| Locale-only tick | Hotload paths also call `IrisLanguage.update()` when the file is unchanged |
|
||||
| `forceSave()` | Used by `/iris debug` and similar toggles that mutate settings in memory |
|
||||
| Load | Parse with Gson into `IrisSettings`. On failure, log `Configuration Error in settings.json!` and run on built-in defaults for that boot — the bad file is left untouched, because the rewrite never runs |
|
||||
| After a successful load | Rewrite `settings.json` as pretty JSON so new keys and migrated values persist. Comments and hand formatting are lost |
|
||||
| `/iris reload` | Invalidate the cached settings, re-read the file, reload the locale. On modded it also schedules a forced datapack regeneration. It does not restart services, reload packs, or rebuild engines |
|
||||
| Hotload (Bukkit) | `SettingsHotloadWatch` polls every 60 ticks (about 3 s) through the VolmLib `ConfigHotloadEngine`. A `lastModified` or size change triggers a read; the reload only runs if the normalized file content actually differs. Logs `Hotloaded settings.json` |
|
||||
| Hotload (modded) | `ModdedSettingsHotloadService` polls `lastModified` every 3 s. Because a load rewrites the file, a touch with no edit still produces one reload (it does not loop). Logs `Hotloaded settings.json` |
|
||||
| Locale refresh | Bukkit calls `IrisLanguage.update()` on every poll; modded calls it only when the file is unchanged, and calls a full `IrisLanguage.reload()` when it did change |
|
||||
| `forceSave()` | Only `/iris debug` writes settings back from memory |
|
||||
|
||||
Legacy migration: if raw JSON still has `world.anbientEntitySpawningSystem`, it is copied to `world.ambientEntitySpawningSystem` and logged once.
|
||||
Legacy migration: if the raw JSON still contains `world.anbientEntitySpawningSystem`, the value is copied to `world.ambientEntitySpawningSystem` and logged once.
|
||||
|
||||
## Root object
|
||||
|
||||
Top-level Gson fields on `IrisSettings` (all nested objects are created with defaults when missing):
|
||||
Top-level Gson fields on `IrisSettings`. Every nested object is created with defaults when missing.
|
||||
|
||||
| Field | Nested class | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| `general` | `IrisSettingsGeneral` | Language, debug, colors, datapack ingest, strict keys, splash |
|
||||
| `world` | `IrisSettingsWorld` | Entity systems, async tick, WorldEdit CUI, pregen cache |
|
||||
| `gui` | `IrisSettingsGUI` | Server-launched GUIs and pregen GUI options |
|
||||
| `autoConfiguration` | `IrisSettingsAutoconfiguration` | Spigot/Paper timeout autoconfig, custom-biome restart |
|
||||
| `generator` | `IrisSettingsGenerator` | Default world type, leaf decay |
|
||||
| `concurrency` | `IrisSettingsConcurrency` | Runtime thread helpers only (no persisted fields) |
|
||||
| `studio` | `IrisSettingsStudio` | Studio open/VSCode/weather/spawn defaults |
|
||||
| `performance` | `IrisSettingsPerformance` | Mantle, caches, SIMD, nested engine SVC |
|
||||
| `pregen` | `IrisSettingsPregen` | Pregen scheduler, mantle residency, timeouts |
|
||||
| `sentry` | `IrisSettingsSentry` | Error reporter options |
|
||||
| `treeFeller` | `IrisSettingsTreeFeller` | Survival tree feller enable and axe durability |
|
||||
| Field | Nested class | Covers |
|
||||
|-------|--------------|--------|
|
||||
| `general` | `IrisSettingsGeneral` | Locale, debug output, console colors, datapack ingest, strict keys, splash |
|
||||
| `world` | `IrisSettingsWorld` | Entity systems, async world tick, WorldEdit CUI, pregen cache |
|
||||
| `gui` | `IrisSettingsGUI` | Server-launched desktop GUIs |
|
||||
| `autoConfiguration` | `IrisSettingsAutoconfiguration` | Spigot/Paper server-file fixups, custom-biome restart |
|
||||
| `generator` | `IrisSettingsGenerator` | Default pack for world creation, leaf decay |
|
||||
| `concurrency` | `IrisSettingsConcurrency` | Nothing configurable — see below |
|
||||
| `studio` | `IrisSettingsStudio` | Studio world behavior |
|
||||
| `performance` | `IrisSettingsPerformance` | Mantle residency, loader caches, SIMD, engine service pool |
|
||||
| `pregen` | `IrisSettingsPregen` | Pregen scheduling, mantle backpressure, timeouts |
|
||||
| `sentry` | `IrisSettingsSentry` | Error reporter |
|
||||
| `treeFeller` | `IrisSettingsTreeFeller` | Survival tree feller |
|
||||
|
||||
Static helper `IrisSettings.getThreadCount(int c)`: for `c` in `{-1,-2,-4}` returns `max(availableProcessors / -c, 1)`; otherwise `max(c, 2)` floored to at least 1.
|
||||
Static helper `IrisSettings.getThreadCount(int c)`: for `c` in `{-1, -2, -4}` it returns `max(availableProcessors / -c, 1)`; otherwise `max(c, 2)`, floored at 1.
|
||||
|
||||
## `general`
|
||||
## `general` — locale, diagnostics, and console output
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `language` | string | `"en_US"` | Active locale key; reloaded by `/iris reload` and hotload |
|
||||
| `commandSounds` | boolean | `true` | Tab-complete amethyst chime on Bukkit when true |
|
||||
| `debug` | boolean | `false` | Toggled by `/iris debug`; saved immediately |
|
||||
| `dumpMantleOnError` | boolean | `false` | Dump mantle plates when tectonic errors occur |
|
||||
| `disableNMS` | boolean | `false` | Disable NMS bindings when true |
|
||||
| `pluginMetrics` | boolean | `true` | Plugin metrics reporting |
|
||||
| `splashLogoStartup` | boolean | `true` | Console splash on enable |
|
||||
| `useConsoleCustomColors` | boolean | `true` | Custom colors for console senders |
|
||||
| `useCustomColorsIngame` | boolean | `true` | Custom colors for player senders |
|
||||
| `adjustVanillaHeight` | boolean | `false` | Adjust vanilla height handling |
|
||||
| `autoIngestDatapacks` | boolean | `true` | Validate and ingest configured external datapacks during the startup admission gate; unchanged committed content reuses its persisted result without another remote/full validation, and managed structures remain scoped to declaring Iris dimensions |
|
||||
| `autoImportDatapackStructures` | boolean | `false` | Opt-in bulk write of every registered datapack structure as editable Iris resources; prefer `/iris structure import <dimension>` |
|
||||
| `strictContentKeys` | boolean | `false` | Unresolved pack content keys and bad block-state properties become blocking pack errors; system property `-Diris.strictContent` overrides when set |
|
||||
| `spinh` | int | `-20` | Splash / spin color H |
|
||||
| `spins` | int | `7` | Splash / spin color S |
|
||||
| `spinb` | int | `8` | Splash / spin color B |
|
||||
This group decides what Iris says and how loudly. `language`, `debug`, and `strictContentKeys` are the ones worth touching; the colour and spin keys are cosmetic; the datapack keys change startup work on Bukkit only.
|
||||
|
||||
## `world`
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `language` | `"en_US"` | Live | Selects the locale catalog for all Iris messages. Reloaded by `/iris reload` and by both hotload watchers |
|
||||
| `commandSounds` | `true` | Live | **Bukkit only.** Plays the amethyst chime on `/iris` tab completion and success/failure sounds after a command. Turn off if the noise annoys staff |
|
||||
| `debug` | `false` | Live | Enables verbose engine tracing on the console and writes per-chunk crash dumps under `debug/chunk-errors/`. Toggle with `/iris debug` rather than editing by hand; leave off in production because it is loud |
|
||||
| `dumpMantleOnError` | `false` | Live | When a tectonic plate read reports an error, dump the decoded region to `dump/<name>.bin` instead of logging a timing line. Turn on only when investigating mantle corruption |
|
||||
| `disableNMS` | `false` | **Restart** | **Bukkit only.** Forces the no-op NMS binding. Iris logs a warning and world creation stops working entirely, so this is a diagnostic escape hatch, not a compatibility switch. Read in a class initializer, so a reload will not change it |
|
||||
| `pluginMetrics` | `true` | **Restart** | **Bukkit only.** Registers the bStats reporter at enable |
|
||||
| `splashLogoStartup` | `true` | **Restart** | Prints the ASCII logo and version block at startup. Set false for quieter console logs |
|
||||
| `useConsoleCustomColors` | `true` | Live | Gradient/hex colouring for console output. Set false if your log viewer mangles it — you still get legacy colour codes. Iris also forces both colour keys off in memory if Adventure fails to bind |
|
||||
| `useCustomColorsIngame` | `true` | Live | Same, for messages sent to players |
|
||||
| `adjustVanillaHeight` | `false` | **Restart** | **Bukkit only.** Overwrites the vanilla `overworld`/`the_nether`/`the_end` dimension-type JSON with Iris height when compiling the datapack. It is part of the datapack fingerprint, so flipping it forces a datapack rebuild |
|
||||
| `autoIngestDatapacks` | `true` | **Restart** | **Bukkit only.** Downloads and installs configured `datapackImports` during the startup admission gate. Unchanged committed content reuses its persisted result instead of revalidating; managed structures stay scoped to the declaring Iris dimensions |
|
||||
| `autoImportDatapackStructures` | `false` | Live (next ingest) | **Bukkit only.** Converts every registered datapack structure into editable Iris pools, pieces, and objects — thousands of files in your pack folder. Native generation never needs those copies, so leave it off and run `/iris structure import <dimension>` when you actually want them |
|
||||
| `strictContentKeys` | `false` | Live | Promotes unresolved pack content keys and bad block-state properties from warnings to blocking pack errors. Worth turning on while developing a pack. `-Diris.strictContent` overrides it in both directions, and the bare property with no value counts as true |
|
||||
| `spinh` | `-20` | Live | Hue factor of the animated "aura" gradient on Iris text |
|
||||
| `spins` | `7` | Live | Saturation factor of the same gradient |
|
||||
| `spinb` | `8` | Live | Brightness factor of the same gradient |
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `postLoadBlockUpdates` | boolean | `true` | Post-load block updates |
|
||||
| `forcePersistEntities` | boolean | `true` | Force entity persistence |
|
||||
| `ambientEntitySpawningSystem` | boolean | `true` | Ambient entity spawning (legacy key `anbientEntitySpawningSystem` migrated) |
|
||||
| `asyncTickIntervalMS` | long | `700` | World manager async tick interval ms |
|
||||
| `targetSpawnEntitiesPerChunk` | double | `0.95` | Target entity density per chunk |
|
||||
| `markerEntitySpawningSystem` | boolean | `true` | Marker-driven entity spawning |
|
||||
| `effectSystem` | boolean | `true` | Engine effects |
|
||||
| `worldEditWandCUI` | boolean | `true` | WorldEdit wand CUI integration (Bukkit) |
|
||||
| `globalPregenCache` | boolean | `false` | Global pregen cache |
|
||||
## `world` — entity systems and the async world tick
|
||||
|
||||
If both `markerEntitySpawningSystem` and `ambientEntitySpawningSystem` are false, the world manager skips related entity work.
|
||||
Iris runs its own spawning and effects pass on a background loop, separate from vanilla mob spawning. These keys decide whether that loop does anything and how often. Turning the spawn systems off makes Iris worlds feel emptier but removes an entire class of tick cost; the defaults are the intended experience.
|
||||
|
||||
## `gui`
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `postLoadBlockUpdates` | `true` | Live | Runs a block-update pass over freshly generated chunks near players so placed objects settle (physics and waterlogging fixups). Turning it off is faster but leaves floating or unwatered blocks from some objects |
|
||||
| `forcePersistEntities` | `true` | Live | Marks every Iris-spawned entity persistent so vanilla mob-cap and distance rules do not despawn it. Turn off if pack-spawned mobs are accumulating |
|
||||
| `ambientEntitySpawningSystem` | `true` | Live | Enables the biome/region ambient spawn lists on the async tick (legacy key `anbientEntitySpawningSystem` is migrated automatically) |
|
||||
| `asyncTickIntervalMS` | `700` | Live (next tick) | Milliseconds between world-manager passes that handle spawning, effects, and cleanup. Raise it to cut background cost on a busy server; lower it only if pack spawns feel too sparse |
|
||||
| `targetSpawnEntitiesPerChunk` | `0.95` | Live | Entity saturation ceiling. Once entities per loaded chunk exceed this, Iris stops spawning (the Bukkit path also backs off for 5 seconds). Lower it on servers already near their entity budget |
|
||||
| `markerEntitySpawningSystem` | `true` | Live | Enables spawning driven by mantle marker blocks, which is how packs place specific mobs at specific generated features |
|
||||
| `effectSystem` | `true` | Live | Applies per-biome and per-region `IrisEffect`s (potion effects, particles, sounds) to players |
|
||||
| `worldEditWandCUI` | `true` | Live | **Bukkit only.** Lets a WorldEdit selection act as an Iris wand and draws the particle outline for it |
|
||||
| `globalPregenCache` | `false` | Live, one event late | **Bukkit only.** Maintains a persistent per-world bitmap of already-generated chunks so pregen can skip finished work across restarts. The enable/disable flip is observed on the following world-init or chunk-load event, not the current one |
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `useServerLaunchedGuis` | boolean | `true` | Allow server-side GUI hosts (noise map, vision, pregen UI) |
|
||||
| `maximumPregenGuiFPS` | boolean | `false` | Cap pregen GUI at max FPS when true |
|
||||
| `colorMode` | boolean | `true` | Colored GUI mode |
|
||||
With both `markerEntitySpawningSystem` and `ambientEntitySpawningSystem` false, the world manager skips all related entity work.
|
||||
|
||||
## `autoConfiguration`
|
||||
## `gui` — desktop windows launched by the server
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `configureSpigotTimeoutTime` | boolean | `true` | Raise Spigot timeout on Bukkit family when supported |
|
||||
| `configurePaperWatchdogDelay` | boolean | `true` | Adjust Paper watchdog delay when supported |
|
||||
| `autoRestartOnCustomBiomeInstall` | boolean | `true` | Auto-restart path after custom biome datapack install when required |
|
||||
Iris can open AWT windows on the machine running the server: the noise explorer, the vision map, and the pregen viewer. That is useful on a local dev box and wrong on a headless host, which is the only reason to touch this group.
|
||||
|
||||
Bukkit-oriented; no-op or unused on mod loaders.
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `useServerLaunchedGuis` | `true` | Live | Allows server-side GUI hosts to open windows. Set false on any remote or headless server; the commands then report that GUIs are unavailable instead of trying |
|
||||
| `maximumPregenGuiFPS` | `false` | Live | Repaints the pregen map window as fast as possible instead of roughly four times a second. Only affects the local window, never generation throughput |
|
||||
| `colorMode` | `true` | Per window open | Colour rendering in the noise explorer instead of grayscale. It is captured when the window opens, so close and reopen the explorer to apply a change |
|
||||
|
||||
## `generator`
|
||||
## `autoConfiguration` — Bukkit server-file fixups
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `defaultWorldType` | string | `"overworld"` | Default pack/dimension type key for world create when not overridden by command defaults |
|
||||
| `preventLeafDecay` | boolean | `true` | Prevent leaf decay on Iris-managed leaves when true |
|
||||
Iris edits a couple of server config files at boot so long chunk generation does not look like a hang to the server's own watchdogs. Leave these on unless you manage those files yourself. They are all Bukkit-only and all read once during enable.
|
||||
|
||||
## `concurrency`
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `configureSpigotTimeoutTime` | `true` | **Restart** | Raises `timeout-time` in `spigot.yml` so a long generation stall does not kill the server |
|
||||
| `configurePaperWatchdogDelay` | `true` | **Restart** | Raises Paper's watchdog early-warning and timeout for the same reason |
|
||||
| `autoRestartOnCustomBiomeInstall` | `true` | **Restart** | When a datapack install registers new custom biomes and reports that a restart is required, Iris restarts the server itself instead of waiting for an admin |
|
||||
|
||||
This section has **no public fields** serialized to JSON. Gson writes an empty object `{}`. Methods used at runtime:
|
||||
These keys are no-ops on mod loaders.
|
||||
|
||||
| Method | Result |
|
||||
|--------|--------|
|
||||
| `getParallelism()` | `max(2, availableProcessors)` |
|
||||
| `getIoParallelism()` | `max(2, availableProcessors / 2)` |
|
||||
| `getWorldGenThreads()` | `max(2, availableProcessors)` |
|
||||
## `generator` — defaults for world creation
|
||||
|
||||
## `studio`
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `defaultWorldType` | `"overworld"` | Live | **Bukkit only.** The pack key used whenever a world, studio, or command omits one — including a bare `Iris` generator string in `bukkit.yml` and `/iris create name type=default`. Mod loaders use `defaultPack` in `modded.json` instead |
|
||||
| `preventLeafDecay` | `true` | Effectively **restart** | Marks generated leaves persistent so they do not decay. The flag is baked into resolved block data that is then cached, so already-resolved leaf blocks keep the old behavior after a reload. Unrelated to the per-dimension `preventLeafDecay` field in pack JSON |
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `openVSCode` | boolean | `true` | Open VS Code / workspace on studio open paths |
|
||||
| `disableTimeAndWeather` | boolean | `true` | Freeze time/weather in studio worlds |
|
||||
| `entitySpawning` | boolean | `true` | Allow entity spawning in studio |
|
||||
| `autoStartDefaultStudio` | boolean | `false` | Auto-open default studio on enable |
|
||||
## `concurrency` — nothing to configure
|
||||
|
||||
## `performance`
|
||||
This object has no serialized fields. Gson writes `{}`, and anything you type inside it is silently discarded the next time Iris saves the file. The values are derived from CPU count at runtime:
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `engineSVC` | object | see below | Nested engine service thread pool |
|
||||
| `trimMantleInStudio` | boolean | `false` | Trim mantle while in studio |
|
||||
| `mantleKeepAlive` | int | `30` | Mantle keep-alive window |
|
||||
| `noiseCacheSize` | int | `1024` | Noise cache capacity |
|
||||
| `resourceLoaderCacheSize` | int | `1024` | Resource loader cache |
|
||||
| `objectLoaderCacheSize` | int | `4096` | Object loader cache |
|
||||
| `mantleCleanupDelay` | int | `200` | Cleanup delay ticks; world manager uses `max(mantleCleanupDelay * 50, 0)` ms |
|
||||
| `simdKernels` | boolean | `true` | SIMD-accelerated noise kernels when available |
|
||||
| Method | Result | Used by |
|
||||
|--------|--------|---------|
|
||||
| `getParallelism()` | `max(2, availableProcessors)` | Default `MultiBurst` pools, hybrid pregen thread count, locator searches |
|
||||
| `getIoParallelism()` | `max(2, availableProcessors / 2)` | The shared IO burst pool |
|
||||
| `getWorldGenThreads()` | `max(2, availableProcessors)` | Async pregen concurrency cap and the Moonrise worker-pool adjustment |
|
||||
|
||||
## `performance` — caches, mantle residency, and the engine service pool
|
||||
|
||||
This is the memory-versus-rework group. Larger loader caches trade heap for fewer pack reloads; mantle keys decide how long generated region data stays resident before being written out. Most keys here are captured when a pool or cache is built, so plan on a restart. Use `33 - Performance Tuning.md` for the measurement procedure — changing these blind usually makes things worse.
|
||||
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `trimMantleInStudio` | `false` | Live | Lets the maintenance pass trim mantle in studio worlds. With the default `false`, studio engines skip the whole maintenance pass, which keeps edits responsive at the cost of growing memory during long authoring sessions |
|
||||
| `mantleKeepAlive` | `30` | Live | Seconds a mantle plate stays resident before it is eligible for trimming. Scaled down automatically as reclaim pressure rises. Lower it when heap is tight, raise it if the same regions are reloaded repeatedly |
|
||||
| `noiseCacheSize` | `1024` | Mixed | Capacity of the noise sample caches. The terrain query API picks it up live; the engine's own caches need an engine hotload or restart. Pregen temporarily raises it to at least 4096 in memory and does not lower it again or persist the change |
|
||||
| `resourceLoaderCacheSize` | `1024` | **Restart / pack reload** | How many loaded pack resources stay cached per loader. Captured when a pack's `IrisData` is opened |
|
||||
| `objectLoaderCacheSize` | `4096` | **Restart / pack reload** | Same, for `.iob` objects, matter objects, and images. Raise it for object-heavy packs when heap allows; lower it first when profiling shows retained pack data |
|
||||
| `mantleCleanupDelay` | `200` | Live | Delay in **ticks** before a loaded chunk's mantle cleanup runs — the default is 10 seconds. Read from the raw field with no clamping, so a negative value is floored at 0 ms and a huge value really does postpone cleanup |
|
||||
| `simdKernels` | `true` | **Restart** | Uses Vector API noise kernels when `jdk.incubator.vector` is on the module path, otherwise scalar fallbacks. Chosen once during class initialization, so toggling it and reloading does nothing, and it is silently inert without the JVM module flag |
|
||||
|
||||
### `performance.engineSVC`
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `useVirtualThreads` | boolean | `true` | Prefer virtual threads when available |
|
||||
| `forceMulticoreWrite` | boolean | `false` | Force multicore write path |
|
||||
| `priority` | int | `Thread.NORM_PRIORITY` (5) | Clamped to `[MIN_PRIORITY, MAX_PRIORITY]` |
|
||||
| `parallelism` | int | `-1` | `>0`: min of configured and `processors * 2`; `≤0`: `ceil(sqrt(processors))` at least 1 |
|
||||
The engine maintenance service is a small scheduled pool that trims and unloads mantle plates. Its three sizing keys are read once at enable, so a restart is required for any change to matter.
|
||||
|
||||
## `pregen`
|
||||
| Key | Default | Takes effect | What it does |
|
||||
|-----|---------|--------------|--------------|
|
||||
| `useVirtualThreads` | `true` | **Restart** | Builds the maintenance thread factory from virtual threads instead of platform threads |
|
||||
| `forceMulticoreWrite` | `false` | Live | Makes every maintenance pass unload all eligible tectonic plates instead of only unloading under heap pressure. Trades steadier memory for more write work; useful during long pregens on a small heap |
|
||||
| `priority` | `5` (`Thread.NORM_PRIORITY`) | **Restart** | Thread priority, clamped to `[MIN_PRIORITY, MAX_PRIORITY]`. It is applied only when `useVirtualThreads` is false, so with the shipped defaults this key does nothing |
|
||||
| `parallelism` | `-1` | **Restart** | Maintenance pool size. `>0` is capped at `processors * 2`; `<=0` uses `ceil(sqrt(processors))`, at least 1 |
|
||||
|
||||
| Key | Type | Default | Effective clamp / resolve |
|
||||
|-----|------|---------|---------------------------|
|
||||
| `runtimeSchedulerMode` | enum | `AUTO` | `AUTO`, `PAPER_LIKE`, `FOLIA`. Regionized (Folia) always resolves to `FOLIA`. On non-regionized, configured `FOLIA` is forced to `PAPER_LIKE`. `AUTO` probes server name/version/class for Folia vs Paper-like family |
|
||||
| `paperLikeBackendMode` | enum | `AUTO` | `AUTO`, `TICKET`, `SERVICE`. Non-`AUTO` uses the configured value; `AUTO` resolves to `TICKET` |
|
||||
| `chunkLoadTimeoutSeconds` | int | `15` | Clamped `[5, 120]` |
|
||||
| `timeoutWarnIntervalMs` | int | `500` | Minimum 250 |
|
||||
| `saveIntervalMs` | int | `30000` | Clamped `[5000, 900000]` |
|
||||
| `maxResidentTectonicPlates` | int | `96` | Minimum 16 via getter; effective residency also scales by world height and ~60% heap budget (~48 MB reference plate at height 384) with floor 16 |
|
||||
| `mantleBackpressureWaitMs` | int | `25` | Clamped `[5, 1000]` |
|
||||
| `mantleBackpressureTimeoutMs` | int | `60000` | Clamped `[5000, 600000]` |
|
||||
| `moddedPregenInFlight` | int | `0` | `>0`: clamped to max 512; `≤0`: `max(16, min(48, cpu * 2))` for modded pregen concurrency |
|
||||
## `pregen` — scheduling, timeouts, and mantle backpressure
|
||||
|
||||
`runtimeSchedulerMode` and Paper-like backend modes apply to Bukkit-family pregen routing. `moddedPregenInFlight` is the modded in-flight chunk budget.
|
||||
These keys bound how aggressively pregeneration pushes the server. They are read when a pregen job is constructed, so a change applies to the *next* job, not a running one. The two that matter in practice are `maxResidentTectonicPlates` (the memory ceiling) and, on mod loaders, `moddedPregenInFlight` (the concurrency ceiling). The rest exist for diagnosing a specific failure mode.
|
||||
|
||||
## `sentry`
|
||||
| Key | Default | Applies to | What it does and how it resolves |
|
||||
|-----|---------|------------|----------------------------------|
|
||||
| `runtimeSchedulerMode` | `AUTO` | Bukkit | `AUTO`, `PAPER_LIKE`, `FOLIA`. A regionized (Folia) runtime resolves to `FOLIA` before the setting is consulted, and off Folia a configured `FOLIA` is downgraded to `PAPER_LIKE`. Since `AUTO` also lands on `PAPER_LIKE` for every recognized and unrecognized fork, this key changes nothing in practice — the one exception is a non-regionized server that still identifies itself as Folia by name or version, where `AUTO` picks `FOLIA` and an explicit `PAPER_LIKE` does not |
|
||||
| `paperLikeBackendMode` | `AUTO` | Bukkit, non-Folia | `AUTO`, `TICKET`, `SERVICE`. `SERVICE` uses the service executor (`paper-service`); `TICKET` and `AUTO` both use the ticket executor (`paper-ticket`). Ignored entirely on Folia. Try `SERVICE` only if ticket-based chunk loading is producing timeouts |
|
||||
| `chunkLoadTimeoutSeconds` | `15` | Both | Clamped to `[5, 120]`. How long pregen waits for one chunk load before it counts as timed out. **On mod loaders the effective value is floored at 120**, so any value below that is ignored there |
|
||||
| `timeoutWarnIntervalMs` | `500` | Bukkit | Minimum 250. Rate-limits the "timed out async pregen chunk load" and failed-release warnings so a bad run does not flood the log. Not read on mod loaders |
|
||||
| `saveIntervalMs` | `30000` | Both | Clamped to `[5000, 900000]`. How often a running pregen flushes progress. Lower it if you expect to lose the process and want a closer resume point; the cost is more IO |
|
||||
| `maxResidentTectonicPlates` | `96` | Both | Minimum 16. The mantle memory ceiling, and the first knob to lower on an out-of-memory pregen. The effective cap is also scaled by world height and by roughly 60% of the heap budget against a ~48 MB reference plate at height 384, with a floor of 16 — so on a small heap you may already be running below the configured number |
|
||||
| `mantleBackpressureWaitMs` | `25` | Both | Clamped to `[5, 1000]`. Sleep granularity while pregen waits for resident plates to drop below the cap |
|
||||
| `mantleBackpressureTimeoutMs` | `60000` | Both | Clamped to `[5000, 600000]`. How long that wait may last before Iris logs a backpressure warning and lowers its adaptive in-flight limit. Seeing this warning repeatedly means `maxResidentTectonicPlates` is too high for your heap, not too low |
|
||||
| `moddedPregenInFlight` | `0` | Modded | Concurrent chunk budget for modded pregen. `>0` is capped at 512; `<=0` derives `max(16, min(48, cpu * 2))`. Lower it when modded pregen causes chunk-load timeouts or memory growth. Inert on Bukkit |
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `includeServerId` | boolean | `true` | Include server id in reports |
|
||||
| `disableAutoReporting` | boolean | `false` | Disable automatic Sentry reporting when true |
|
||||
| `debug` | boolean | `false` | Sentry debug logging |
|
||||
## `sentry` — error reporting
|
||||
|
||||
## `treeFeller`
|
||||
Read once during boot on both platforms, so every change here needs a restart.
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `enabled` | boolean | `false` | Master switch for survival tree feller |
|
||||
| `durabilityPreservationChance` | int | `0` | Percent chance to preserve axe durability; clamped `[0, 100]` |
|
||||
| Key | Default | What it does |
|
||||
|-----|---------|--------------|
|
||||
| `includeServerId` | `true` | **Bukkit only.** Attaches the server id to reports so recurring reports from one server can be grouped. Not read on mod loaders |
|
||||
| `disableAutoReporting` | `false` | Skips Sentry initialization entirely. Set true if you do not want automatic error reports leaving the machine |
|
||||
| `debug` | `false` | Turns on Sentry's own debug logging. Useful only when reports are not arriving |
|
||||
|
||||
Requires permission `iris.treefeller` on Bukkit (and the platform tree-feller permission node on mod loaders). See `04 - Commands & Permissions.md` and `28 - Integrations.md`.
|
||||
## `treeFeller` — survival tree felling
|
||||
|
||||
Off by default because it changes survival gameplay. Both keys are read live, so `/iris reload` is enough.
|
||||
|
||||
| Key | Default | What it does |
|
||||
|-----|---------|--------------|
|
||||
| `enabled` | `false` | Master switch. With it on, a permitted player breaking one log fells the whole Iris-managed tree. Disabling it mid-run cancels an in-flight fell on mod loaders only; the Bukkit runner does not re-read the setting once a fell has started |
|
||||
| `durabilityPreservationChance` | `0` | Percent chance per block that the axe takes no durability, clamped to `[0, 100]`. An integration may override this per call |
|
||||
|
||||
Requires permission `iris.treefeller` on Bukkit, or the platform tree-feller node on mod loaders. See `04 - Commands & Permissions.md` and `28 - Integrations.md`.
|
||||
|
||||
## `studio` — authoring world behavior
|
||||
|
||||
Only two of the four keys in this section do anything today.
|
||||
|
||||
| Key | Default | What it does |
|
||||
|-----|---------|--------------|
|
||||
| `openVSCode` | `true` | Whether `/iris studio vscode` launches an editor after writing the workspace file. Set false on a headless box |
|
||||
| `entitySpawning` | `true` | Whether mobs spawn inside studio worlds. Has no effect on normal worlds |
|
||||
| `disableTimeAndWeather` | `true` | Nothing. Present in the settings model but not read by any code path today |
|
||||
| `autoStartDefaultStudio` | `false` | Nothing. Present in the settings model but not read by any code path today |
|
||||
|
||||
Studio workflow details: see `10 - Studio & VSCode Schemas.md`.
|
||||
|
||||
## Bukkit-only: `compat.json`
|
||||
|
||||
On Bukkit, Iris loads `plugins/Iris/compat.json` at startup and writes the built-in table to `compat.default.json`. Built-in compatibility mappings remain active; entries from `compat.json` are appended so operators can add fallback blocks and items for content that is unavailable on the running server.
|
||||
On Bukkit, Iris loads `plugins/Iris/compat.json` at startup and writes the complete built-in table to `compat.default.json` next to it for reference. This is how you keep a pack working on a server that lacks some block or item it references: Iris substitutes the replacement instead of failing.
|
||||
|
||||
Built-in mappings always stay active; entries read from `compat.json` are appended to them. Both files are read once at boot — `/iris reload` does not re-read them, and mod loaders do not use them at all.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -232,32 +270,34 @@ On Bukkit, Iris loads `plugins/Iris/compat.json` at startup and writes the built
|
||||
|
||||
| Field | Applies to | Behavior |
|
||||
|-------|------------|----------|
|
||||
| `when` | block and item filters | Unsupported source key to match |
|
||||
| `supplement` | block and item filters | Replacement key; block replacement can continue through further mappings |
|
||||
| `exact` | block filters only | When true, match complete block data instead of material only |
|
||||
| `when` | block and item filters | The unsupported source key to match |
|
||||
| `supplement` | block and item filters | The replacement key. If the replacement is also unsupported, Iris re-runs the lookup on it, up to 16 hops, and falls back to `STONE` with an error |
|
||||
| `exact` | block filters only | When true, match the full key including namespace and block-state properties (`minecraft:some_log[axis=x]`). When false, match the bare material name. Item filters have no `exact` field |
|
||||
|
||||
Invalid JSON logs the failure and leaves the built-in mappings active. These files are runtime compatibility configuration, not pack resources, and are not used by the modded adapters.
|
||||
A block substitution logs `Compat: Using '<supplement>' in place of '<when>' since this server doesnt support '<when>'` as a warning; item substitutions log the same at debug level. Invalid JSON logs the failure and leaves the built-in mappings active.
|
||||
|
||||
One quirk to know: when `compat.json` is absent, Iris seeds it with a copy of the entire built-in table. On the next boot those entries are appended to the built-ins again, so the runtime list holds every default twice. It is harmless because the first match wins, but if you are editing the file, delete the entries you did not add.
|
||||
|
||||
## Modded-only: `modded.json`
|
||||
|
||||
Path: `<configDir>/irisworldgen/modded.json`. Written with defaults on first load if missing. Not used by the Bukkit plugin.
|
||||
Path: `<configDir>/irisworldgen/modded.json`, written with defaults on first load if missing. Not used by the Bukkit plugin. Unlike `settings.json` this file is parsed by hand rather than Gson, is cached once, and has no hotload — a restart is required except for the keys that Iris rewrites itself. Malformed JSON logs `Iris modded config at … is invalid; using defaults` and runs on defaults **without** rewriting your file.
|
||||
|
||||
| Key | Type | Default | Notes |
|
||||
|-----|------|---------|-------|
|
||||
| `defaultPack` | string | `"overworld"` | Default create pack; a distinct non-managed value is also prefetched when enabled |
|
||||
| `autoDownloadDefaultPack` | boolean | `true` | Download missing managed Overworld/Underworld beta packs and any distinct configured default |
|
||||
| `primaryWorld` | string | `""` | Primary Iris dimension id for player routing |
|
||||
| `routePlayersToPrimaryWorld` | boolean | `true` | Route players to primary when set |
|
||||
| `mainWorldPack` | string | `""` | Pack (or `pack:dimensionKey`) for main-world preset |
|
||||
| `mainWorldSeed` | long | `0` | Seed for main-world preset |
|
||||
| `mainWorldAutoRestart` | boolean | `false` | Auto-restart after main-world inject when true |
|
||||
| Key | Default | What it does |
|
||||
|-----|---------|--------------|
|
||||
| `defaultPack` | `"overworld"` | Pack used by `/iris create` when none is given. A distinct non-managed value is also prefetched when auto-download is on |
|
||||
| `autoDownloadDefaultPack` | `true` | Downloads the managed Overworld and Underworld beta packs when missing, plus any distinct configured default. Set false on an air-gapped server and install packs by hand |
|
||||
| `primaryWorld` | `""` | Iris dimension id used for player routing |
|
||||
| `routePlayersToPrimaryWorld` | `true` | Sends players to the primary world when one is set |
|
||||
| `mainWorldPack` | `""` | Pack (or `pack:dimensionKey`) for the main-world preset |
|
||||
| `mainWorldSeed` | `0` | Seed for the main-world preset |
|
||||
| `mainWorldAutoRestart` | `false` | Restarts the server automatically after a main-world inject instead of telling you to |
|
||||
|
||||
Updated by `/iris world mainworld`, `/iris world replace-overworld`, primary-world clear paths, and related world commands. See `06 - Worlds & Lifecycle.md` and `30 - Platform Differences.md`.
|
||||
`/iris world mainworld`, `/iris world replace-overworld`, and the primary-world clear paths write this file directly. See `06 - Worlds & Lifecycle.md` and `30 - Platform Differences.md`.
|
||||
|
||||
## What is not in these files
|
||||
|
||||
- Pack JSON (dimensions, biomes, objects) lives under `packs/<key>/` — see `05 - Concepts & Pack Layout.md`.
|
||||
- Per-world studio/workspace files are generated under pack roots — see `10 - Studio & VSCode Schemas.md`.
|
||||
- Per-world studio and workspace files are generated under pack roots — see `10 - Studio & VSCode Schemas.md`.
|
||||
- Locale files and overrides — see `08 - Localization.md`.
|
||||
|
||||
## Related
|
||||
|
||||
Reference in New Issue
Block a user