Paper still provides Adventure at runtime. Every Adventure method Iris calls has the same signature in 4.17 and 5.2.0, so older servers keep working.
Model used: Claude Opus 5.5
The heap gate and the engine service's keep-alive scaling read heap usage
right after the last collection instead of the moment's usage, which G1
lets climb near the maximum on a healthy heap. The plate budget now comes
from a measured 38 MB per plate on a 1088 block world instead of an
estimate that assumed 136 MB there, and is enforced as is rather than at
twice its value. Pregen evicts only the least recently used plates down to
the budget instead of every idle one, so it no longer reloads the plates
it is still generating around.
Model used: Claude Opus 5.5
Ported from Iris v4's mantle backpressure. Before each chunk the
pregenerator now:
- evicts idle tectonic plates and waits while more plates are loaded
than the heap-scaled budget allows (pregen.maxResidentTectonicPlates)
- pauses between 92% and 82% heap, requesting a GC because a paused
pregen allocates too little for the collector to run on its own; if
the heap stays full, the JVM's diagnostic GC runs at most once a
minute, which also works with -XX:+DisableExplicitGC
Both waits give up after pregen.mantleBackpressureTimeoutMs so a stuck
heap cannot hang the pregen. Unlike v4, a reclaim starts anywhere above
82% instead of only at 92%, since a pregen waiting at 89% otherwise
never triggers one.
Outside pregen, the engine service shortens the mantle keep-alive as
the heap fills and trims studio worlds once the heap is critical.
The mantle itself:
- concurrent requests for a plate that is still loading share one load
instead of each holding an IO thread
- plate retries stop once the mantle is closed or the thread is
interrupted, instead of recursing forever
- trim(0, 0) evicts plates idle for 500 ms instead of 4 s
Model used: Claude Opus 5.5
An exception on the pregen thread ended the thread without shutting the
job down, so it kept reporting 0 chunks per second forever and blocked
starting another pregen. A failure is now logged and the job is closed.
Model used: Claude Opus 5.5
Every mantle chunk allocated a coroutine mutex for all 256 possible flag
ordinals up front, about 66 KB of locks per chunk, although only a few
flags are ever raised under a lock. During a pregen those locks took
well over a gigabyte of heap and ran 3 GB servers out of memory. Each
lock is now created when its flag is first raised.
Model used: Claude Opus 5.5
26.3 changed the chunk generator, biome source and structure placement
APIs, so it gets its own v26_3_R1 binding, compiled against the 26.3
dev bundle. v26_1_R1 keeps covering 26.1.2 and 26.2.
Binding changes against v26_1_R1:
- noise, surface and carvers run through a single buildTerrain stage
- the biome source hands out itself as the BiomeResolver
- structures are generated with a climate sampler, and starts are
looked up per chunk instead of per section
- structure set salt and frequency come from the spreading placement
- biome colors are read from Vector3f attributes
Data pack format 121 with DataFixerV2603:
- biome mob spawns and creature spawn probability move into the
natural_mob_spawns and creature_world_gen_spawn_probability attributes
(26.3 silently ignores the old fields)
- the bed rule's "explodes" becomes "destroy_on_use", and straw beds get
the same rule, matching vanilla
Model used: Claude Opus 5.5
Older servers such as Paper 1.20.1 cannot read the Java 25 classes of
the 26.x binding and logged a conversion error for each of them on
shutdown. Bindings for other versions are never used, so they are not
loaded at all.
Model used: Claude Opus 5.5
Studio worlds live in the "iris" world folder, which on 26.x is inside
the level's dimensions folder rather than in the world container.
Model used: Claude Opus 5.5
Paper 26.1.2 caches block data that names every state without the parsed
states BlockData#merge needs, so replacing blocks inside objects threw
on every placement. Such block data replaces the base completely, so
B.merge returns it directly.
Model used: Claude Opus 5.5
26.1 requires has_ender_dragon_fight in dimension types and reads data
packs before any plugin runs, so a pack written on 1.21 stopped the
server from starting. 1.21 ignores the field, so it is now always
written.
Model used: Claude Opus 5.5
Adds the v26_1_R1 binding, which covers both versions. 26.x servers are
not obfuscated and need Java 25, so the build moves to Gradle 9.5.1 and
paperweight-userdev 2.0.0-beta.21, and the binding compiles against the
26.1.2 dev bundle with a Java 25 toolchain while everything else stays on
Java 21.
On 26.x every world is a dimension inside the main level, so the binding
provides DimensionWorldStorage:
- world folders resolve to <level>/dimensions/<namespace>/<key>
- data packs go to the level's datapacks folder
- Iris data in a pre-26.1 world folder is moved into the dimension
before Paper imports the world and deletes the old folder
- "main=true" swaps the world in as the level's overworld instead of
changing level-name
Also:
- INMS compares 1.x and 26.x versions in release order
- data pack formats 101 (26.1.2) and 107 (26.2), declared with
min_format/max_format from format 82 on
- dimension types get the fields 26.1 added
- the Java safeguard accepts Java 25
Model used: Claude Opus 5.5
Minecraft 26.1 moved every world into its level's dimensions folder, so
Iris can no longer assume <world container>/<world name>. World folders,
data pack folders and moving Iris data out of an old layout now go
through WorldStorage, which the NMS binding provides. Every binding so
far uses LegacyWorldStorage, so behaviour is unchanged.
Code that already holds a loaded World uses World#getWorldFolder, which
is correct for both layouts.
Model used: Claude Opus 5.5
Core now compiles against paper-api instead of spigot-api. PaperLib is
replaced by Paper's native async chunk and teleport API, and the Spigot
fallbacks (Medieval pregen method, sync chunk loading) are removed.
Adventure is no longer bundled and relocated: Paper ships it and every
CommandSender is an Audience, so the BukkitAudiences wrapper and ShadeFix
go away.
Iris now refuses to enable on servers without the Paper API, with a clear
message instead of failing later at runtime.
Model used: Claude Opus 5.5