Files
rivencraft/docs/MINECRAFT_26_3_PORT.md
2026-11-05 15:19:11 -05:00

1964 lines
123 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Minecraft 26.3 port status (issue #96)
Checked 2026-10-26. Minecraft Java 26.3 is the newest stable Java release with
NeoForge support. This is an engineering audit and the start of the port, **not
a claim that a 26.3 Rivencraft JAR is ready**. The 1.21.1 build remains the
release target until a separate 26.3 client and dedicated-server build passes.
The user wants both Minecraft lines maintained after the port, not a one-time
26.3 release. Gitea milestone "Dual-version support: 1.21.1 and 26.3"
tracks issues #97–#103 under parent #96.
## Version boundary
Local slice `1.0.1.98-beta.1` ports the 1.21.1 Accelerated environment page:
stacking extra random block ticks in already-loaded player-nearby chunks,
eight-chunk/16,384-attempt default budgets, fair rotating section allocation,
and an Age-local saved page count. The 26.3 LOCAL config holds these limits.
Entities, machines and scheduled ticks are unaffected. Existing Ages remain
unaccelerated; random Age inclusion and instability scoring are not added.
The suspected host-seed biome zoom mismatch was checked against NeoForge's
patched ServerLevel constructor: seedOverride already replaces it correctly,
so the backend seed path was left unchanged. Native Cave policy issue #111
remains separate future work for both Minecraft tracks.
Minecraft 26.3/NeoForge uses Java 25, while Rivencraft 1.21.1 uses Java 21.
Build and publish separate artifacts; do not widen the Minecraft dependency
range of the 1.21.1 JAR. The official [26.3 release notes](https://www.minecraft.net/en-us/article/minecraft-java-edition-26-3),
[NeoForge 26.3 Maven metadata](https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml),
[NeoForge Java 25 setting](https://github.com/neoforged/NeoForge/blob/26.3.x/gradle.properties),
and [NeoForge migration primers](https://docs.neoforged.net/primer/docs/)
are the version sources. NeoForge 26.3.0.99 is the newest listed stable build
at the time of this check.
## Dependency availability
The entries below mean that a NeoForge 26.3 version is advertised by the
project, not that its API or runtime behavior has been validated with
Rivencraft. Recheck immediately before choosing versions for a port build.
| Integration | Role in 1.21.1 | 26.3 availability | Port decision |
| --- | --- | --- | --- |
| [Dynamic Dimensions AR Edition](https://modrinth.com/mod/dynamic-dimensions-ar-edition) | Required runtime Age loading | No; 1.21.1 only | Keep it for 1.21.1. Use a Rivencraft-owned runtime-dimension backend for 26.3. |
| [bad packets](https://modrinth.com/mod/badpackets) | Declared runtime dependency; no direct Java imports in Rivencraft | No advertised 26.3 version | Determine whether the new dimension backend needs it; otherwise remove it from the 26.3 artifact. Use NeoForge's own networking for Rivencraft packets. |
| [JEI](https://modrinth.com/mod/jei) | Optional recipe/page guides | Yes | Port and test its plugin against the 26.3 API. |
| [TerraBlender](https://modrinth.com/mod/terrablender) | Optional modded biome support | Yes | Port and verify biome discovery and Age generation. |
| [Serene Seasons](https://modrinth.com/mod/serene-seasons) and [GlitchCore](https://modrinth.com/mod/glitchcore) | Optional seasons | Yes | Port and repeat the per-Age seasonal matrix. |
| [Biomes O' Plenty](https://modrinth.com/mod/biomes-o-plenty) | Optional TerraBlender test addon | Yes | Test modded biome registration and decoration. |
| [Ruins (Structure Spawning System)](https://www.curseforge.com/minecraft/mc-mods/ruins-structure-spawning-system) | Optional authored ruins integration | Yes | Port and verify its generation hooks. |
| [Create](https://modrinth.com/mod/create) / bundled Ponder | Optional scene renderer | No advertised 26.3 version | Use Rivencraft's existing legacy-animation preview fallback for this target until a compatible release exists. |
| [Immersive Portals for (Neo)Forge](https://modrinth.com/mod/immersive-portals-neoforge) | Optional live views and portal teleport integration | No advertised 26.3 version | Use the fallback portal surface and normal Rivencraft linking. Do not claim live destination views on 26.3. |
Ecliptic Seasons publishes 26.3, but Rivencraft's Ecliptic integration was
deferred and is not a replacement for the current Serene integration.
The alternatives checked for runtime Age loading do not meet the 26.3
NeoForge requirement: [upstream Dynamic Dimensions](https://github.com/TeamGalacticraft/DynamicDimensions)
and its [AR fork](https://github.com/dercodeKoenig/DynamicDimensions)
have no published 26.3 branch or artifact;
[DimLib](https://modrinth.com/mod/dimlib) is Fabric-only and stops at 1.21.1;
and [DimensionsCore](https://www.curseforge.com/minecraft/mc-mods/dimensionscore-dynamic-dimension-world-management)
currently publishes only a Forge 1.20.1 file. Mods that add fixed dimensions
or portals do not supply the arbitrary per-book runtime worlds Rivencraft
needs. This is a search result, not proof that no other project exists.
## 26.3 backend design
The 26.3 port is a **fresh-save target**. It does not need to import 1.21.1
Age worlds or migrate Dynamic Dimensions' saved registry data. The 1.21.1
artifact will continue using that library. Within 26.3, however, a created
Age must retain its identity, seed, chunks and access across save/restart.
1. Keep the existing `AgeDimensionService`/`AgeDimensionBackend` boundary.
Implement a target-specific 26.3 backend without importing Dynamic
Dimensions or its seed mixin. The backend contract needs registration at
server start, create/load, unload and delete. Return a failure without
publishing a half-created Age if any step fails.
2. At server startup, reconstruct all non-retired Ages from Rivencraft's
`AgeRegistrySavedData` **before** players can join. For a newly bound book,
register its unique `rivencraft:age/...` dimension and construct a
`ServerLevel` from its authored chunk generator, dimension type and saved
Age seed. The seed must feed chunk random state, not only `getSeed()`.
3. Register the level with the server's level map and the appropriate
dimension registries, then synchronize the new dimension definition to
already-connected clients before sending a travel packet. Handle a
connecting client receiving every existing Age. Determine the minimal
26.3 registry and network hooks from the current NeoForge source; do not
assume `/reload` creates new running levels.
4. Initialize world border, view/simulation distance, forced chunks, spawn
settings, per-Age data storage and tick/save lifecycle as a normal level.
On unload or retirement, refuse while players occupy the Age, move any
remaining entities safely, flush pending chunk writes, detach the level,
and synchronize removal. Retirement must not delete another Age's data.
5. Review the MIT-licensed Dynamic Dimensions code as an implementation
reference. If any code is adapted, retain its copyright/license notice and
identify the derived files. Prefer the smallest backend Rivencraft needs
over a general-purpose library fork.
For gameplay systems, treat the 1.21.1 Rivencraft source and assets as the
porting baseline. Carry across unchanged rules, probabilities, recipes, and
textures directly; adapt only the Minecraft/NeoForge APIs that changed in
26.3. Record deliberate behavior gaps (such as prototype Age generation)
instead of silently replacing established mechanics with new ones.
The release gate is a 26.3 integrated-client **and** dedicated-server matrix:
create two Ages with distinct seeds, explore chunks, travel while another
client remains online, reconnect, restart, revisit saved chunks, reseed for
future chunks, unload/reload, retire one Age without harming the other, and
verify normal travel without optional mods. Then repeat relevant paths with
available integrations. A failed synchronization must be reported and leave
the player in their current level, not crash or strand them.
## Implementation order
1. Keep `AgeDimensionService` independent of a concrete runtime-dimension
implementation. The 1.21.1 Dynamic Dimensions calls now live in
`AgeDimensionBackend`; the `AgeDimensionSeedMixin` is 1.21.1-only.
2. Create a separate 26.3/Java 25 build target. Replace the dimension backend,
then migrate the main sources through the official NeoForge primers. Do not
publish a partial JAR with missing Age generation.
3. Port optional integration classes one at a time. Keep unavailable mods
optional and preserve their existing fallbacks. Upgrade JEI, TerraBlender,
Serene Seasons/GlitchCore, Biomes O' Plenty, and Ruins only in the 26.3
target; do not change the validated 1.21.1 dependency set.
4. Run compile, data/resource validation, new-world Age generation, Age
save/restart/reload, direct and portal/book travel, client rendering, and
dedicated-server tests on both targets. Test without optional mods, then
with each available integration. Require an in-game check before release.
The core blocker is **not** a version number change: 26.3 makes a major API
jump and the required 1.21.1 runtime-dimension library has no 26.3 build.
## Build isolation started in #97
The repository root remains the playable 1.21.1/Java 21 build. A separate
`ports/mc263` Gradle build now resolves NeoForge 26.3.0.99 and compiles with
Java 25. The build workflow has separate Java 21 and Java 25 jobs. Its JAR
task remains disabled; this does not satisfy #97's final artifact criteria.
## First core slice in #98
The 26.3 target now has real Rivencraft metadata and an entrypoint. It
registers the Crystal Shard and Crystal Block with their reused 1.21.1
textures/models plus the 26.3 item-model definitions. `build` passed, and a
dedicated development server loaded the mod and reached `Done` with a new
world and no optional mods. The server was then stopped. This validates only
the entrypoint/registry/resource foundation. A development client also loaded
Rivencraft and reloaded its resources without reported missing models or
textures. The client logged the host's missing `libflite.so` narrator library;
this is unrelated to Rivencraft. Both test processes were stopped after
startup. This does **not** validate in-world client rendering or Age
functionality. Age generators, data, networking, and client code still
need migration; #98 remains open.
## Runtime-level prototype in #99
The 26.3 target has a first-party server-side runtime-level loader and a
SavedData seed index. It constructs each level with a `LevelStem` seed override,
publishes the level only after construction, and restores indexed Ages when
the Overworld loads. A dedicated-server probe created two separate Ages with
seeds `123456789` and `987654321`; after generating chunks, their terrain
fingerprints differed (`2865094` and `3227421`). Both levels, their region
files, seeds, and fingerprints survived a server restart, and the startup log
shows restoration before `Done`. The temporary operator-only
`rivencraft_port age` command exists solely to test this non-distributable
port workspace.
This is **not** issue #99 completion. The loader currently reuses the vanilla
Overworld generator because issue #98 has not ported authored generators or
Age definitions. The synchronized operator travel probe below does not port
normal book travel. The 26.3 JAR task remains disabled.
## Runtime client-catalog prototype in #100
The 26.3 target now sends the current dimension-key catalog to each joining
client and broadcasts a new catalog when a prototype Age is created or
retired. Clients update their known-level set and acknowledge a version; the
server's `rivencraft_port age enter <name>` probe refuses travel until that
acknowledgement arrives and the target is still loaded. A stale acknowledgement
does not satisfy the gate. This follows NeoForge's play-payload registration
and client-handler separation. It is not a general dynamic-registry sync for
authored dimension types, which have not been ported.
The dedicated-server probe used two simultaneous 26.3 clients. Both
acknowledged a newly created Age without reconnecting; a second client entered
an existing runtime Age; a player saved inside an Age reconnected after server
restart and remained there. The operator travel probe searches near origin for
safe footing and creates a small Crystal Block platform if none is found.
This probe is not the final book landing implementation.
`rivencraft_port age retire <name>` refuses to retire an Age containing a
player, then saves and closes it, removes it from the active index, and
broadcasts the reduced catalog. On the dedicated test server, the client
acknowledged creation and retirement even when they happened back-to-back; a
late acknowledgement for the intermediate catalog was ignored. Travel to the
retired Age was refused without moving the player, and retiring an occupied
Age was refused. The #101 lifecycle slice below now archives exact Age data.
This remains a **prototype**, not completion of #100: normal Linking and
Descriptive Book travel, authored dimension-type/generator registration, full
client registry synchronization, and an integrated-client regression pass
must follow the core port. The 26.3 JAR remains disabled. The local test
server was stopped after verification.
## Runtime lifecycle prototype in #101
The operator-only backend probe now supports `age unload`, `reload`, `reseed`,
and `retire` in addition to `create`, `list`, `sample`, and `enter`. Unload and
retirement refuse a level containing players. A full chunk/entity save and
close handles other entities; Minecraft's shutdown-style ticket deactivation
and startup-style activation preserve forced chunks across runtime reloads.
The loaded-dimension catalog is rebroadcast after unload/reload/reseed and
retirement, with stale acknowledgements ignored.
On the dedicated server, a generated Age unloaded and reloaded with the same
terrain fingerprint. Reseeding `lifetest` from `24680` to `13579` kept the
previously generated origin fingerprint `2898472`; previously ungenerated
chunks at offset 100 produced fingerprint `2897795`, identical to a fresh
`13579` control Age and different from a fresh `24680` control (`2863099`).
After restart, `lifetest` still reported seed `13579` and its original origin
fingerprint. Three consecutive unload/reload cycles with a connected client
completed; that client acknowledged the final catalog and intermediate stale
acknowledgements were ignored. Unloading the player's current Age was refused.
A force-loaded chunk and a summoned armor stand with UUID
`[I; -872307724, 883641011, -1239011659, 796091120]` survived repeated
runtime unload/reload and server restart. The entity could be queried again
after its chunk finished loading. The probe retired a different Age,
`seedcontrol`: only its directory moved to the sibling `world-retired-ages`
archive, other Age directories stayed in place, and reloading/recreating the
retired ID was refused after restart. A second archival probe exercised the
tombstone-before-move sequence and again moved only its own directory. The
tombstone is persisted before the archive move so an interrupted archival
cannot silently revive an old Age; an ordinary move failure attempts to
restore the index and level. Ten more consecutive unload/reload cycles
completed on the dedicated server, with its open file-descriptor count steady
at 218 before and after. That is a narrow smoke check, not proof of no leak.
This still does **not** close #101. The prototype has not been integrated with
normal books or the full 26.3 Age definition, nor has a long-running resource
leak test or interrupted-archive recovery drill been completed. Its dev world
and archive are under ignored `ports/mc263/build`, not a release save.
## Optional-integration probe in #102
On 2026-10-27, the published NeoForge 26.3 versions checked were JEI
31.17.0.95, TerraBlender 26.3.0.0.9, Biomes O' Plenty 26.3.0.0.15,
GlitchCore 26.3.0.0.5, and Serene Seasons 26.1.2.0.7 (its file is labelled
for Minecraft 26.3). Ruins advertises 26.3.1NF. Create/Ponder and
Immersive Portals still had no advertised compatible version. These are
availability checks, not API-compatibility claims.
The 26.3 development target now has the operator-only
`/rivencraft_port compat` command. It reports loaded optional mod IDs and
the count of registered biome keys by namespace, so integration smoke tests
can distinguish a missing addon from a missing biome registration. It does
not change Age generation. A clean dedicated server loaded with no optional
mods and reported 67 vanilla biomes. A separate dedicated-server launch with
TerraBlender, Biomes O' Plenty, GlitchCore, and Serene Seasons loaded all four;
the probe reported 68 `biomesoplenty` biome keys, and TerraBlender logged its
Overworld and Nether regions. Both launches stopped cleanly.
Issue #102 remains open. The 26.3 target still lacks authored Ages, JEI
guides, per-Age season policy, Ruins hooks, book previews and crystal portals,
so the relevant integration and fallback acceptance tests cannot yet pass.
The probe must not be mistaken for feature support. The existing 1.21.1
integration code and dependencies remain unchanged.
## First player-facing bridge in #104
The 26.3 port now registers a Descriptive Book with the Legacy item texture
and a persistent, network-synchronized Age-ID data component. The operator-only
`/rivencraft_port age book <name>` probe grants a book for an already indexed
Age; an unbound book does not create a world. Using the bound book calls the
same server-authoritative, catalog-acknowledged landing path as the existing
`age enter` probe. A missing or unloaded Age refuses travel. This avoids
trusting a book-supplied seed or creating a new Age from a forged item.
The dedicated-server smoke test still passed after this bridge, and a 26.3
development client loaded the new item model and texture without a missing
resource warning. The host still reports a missing Linux `libflite.so`
narrator library; this is not a Rivencraft item error. The client was stopped.
The player confirmed right-click travel in game. Book component persistence
across restart still needs a player test; the headless smoke test cannot
exercise it. To test the
bridge in a disposable 26.3 world as an operator:
1. `/rivencraft_port age create booktest 123456789`
2. Wait for the Age catalog acknowledgement, then
`/rivencraft_port age book booktest`.
3. Right-click the granted book and verify arrival in
`rivencraft:age/booktest`. Restart client and server, then use the same
book again and verify it targets the same saved Age.
This is deliberately a **port probe**, not the final book workflow: the Book
Binder, naming UI, GUI preview, automatic return link, dropped-book entity, authored Age
plan, and Legacy landing rules are not yet connected. The bound book currently
remains in hand after travel. Do not distribute this target or mark #104 done.
For a local player test only, the normally disabled port JAR can be built with
`./gradlew -p ports/mc263 build -PallowIncompletePortJar=true`; its filename
retains `26.3-INCOMPLETE` and a `port-dev` version marker. This does not enable the normal
release artifact or imply that the full mod has been ported.
The first Prism test exposed a production-only catalog bug: Minecraft 26.3's
`ClientPacketListener.levels()` returned an immutable set, and the client
handler attempted to clear it. That threw `UnsupportedOperationException`
before the client could acknowledge the Age, so book travel was refused. The
handler now replaces the entire level set through a narrow access transformer
and acknowledges only after replacement. The corrected local test JAR is
`rivencraft-26.3-INCOMPLETE-0.0.0.1-port-dev.jar`. It built successfully;
the player used that JAR to verify actual travel in game on 2026-10-27.
### Linking Book return-path slice
The separate 26.3 target now registers a Linking Book using the Legacy bound
book sprite. `/rivencraft_port link book` grants an operator-only probe book
bound to the player's exact current dimension, coordinates, and facing. Its
destination is a persistent data component resolved by the server on use. A
missing dimension, unacknowledged catalog, same-dimension target without
Intra-Linking, out-of-bounds target, or obstructed arrival is rejected without
moving the player. This path does **not** generate a landing platform.
For a test, stand at an unobstructed spot in the Overworld and run
`/rivencraft_port link book`. Create and bind an Age Descriptive Book using the
steps above, travel into that Age, then right-click the Linking Book. It
should return to the exact bound spot and facing. Same-dimension use should
refuse. Repeat after a server restart to check component persistence. This
slice is `0.0.0.2-port-dev` and remains explicitly incomplete: normal
crafting/binding, modifiers, book GUI, origin-drop entity, and safe fallback
are still unported. The probe book remains in inventory after travel.
### Age-index durability after the first in-game return-link check
The first return-link test exposed a recoverable prototype failure: Seamless
Portals rejected a newly added runtime Age, the integrated server exited
abnormally, and a second Age created just before the exit was not present in
Rivencraft's saved index on restart. Its directory contained no saved chunks.
The `0.0.0.3-port-dev` slice flushes the index synchronously before announcing
newly created Ages to clients. It also flushes reseed changes. The dedicated
server smoke test now checks that both new Age IDs are already in the on-disk
index **before** it issues `stop`, then verifies both seeds/terrain after a
restart. This closes the ordinary interrupted-shutdown gap but is not a
substitute for a power-loss durability test or integration with other mods'
dynamic-dimension catalogs.
### Handheld Linking Book binding slice
The `0.0.0.4-port-dev` target adds a client-only book screen using the Legacy
book artwork. An unbound Linking Book accepts a player-chosen title; a
serverbound packet binds the held book to the player's *current* dimension,
coordinates and facing only after checking the book, title length and empty
target. A bound book opens the same screen and uses a server-validated
destination-panel click for travel. This replaces the earlier direct item-use
probe. The panel is a visible placeholder, **not** a live snapshot. The
rotating preview, completed book behavior (including origin drop), recipe,
modifiers, stand handling and other port systems remain unported.
To test this slice, use `/give @s rivencraft:linking_book` in a 26.3 test
world, stand at the intended return point, right-click the unbound book, enter
a name and bind. Travel to an Age, right-click the book again and click its
right-hand destination panel. Verify the named book persists across restart,
same-dimension travel is refused, and a replaced/removed held book cannot be
bound or used by a delayed screen packet. Do not treat this partial target as
a playable release.
The first `0.0.0.4-port-dev` in-game right-click exposed a 26.3 screen API
mistake: `Screen.extractRenderStateWithTooltipAndSubtitles` already calls
`extractBackground`, so the screen's second call raised `Can only blur once per
frame`. The `0.0.0.5-port-dev` fix removes that duplicate background call.
The next in-game check found that a bound Linking Book's right-hand panel did
not trigger travel: its target component was persistent but lacked a network
codec, so the client screen could not identify the book as bound. The
`0.0.0.6-port-dev` slice adds stream codecs for the Linking Book target and
Descriptive Book Age ID. Server-side held-item and destination checks remain
authoritative. This needs another in-game check before considering the slice
validated.
The `0.0.0.6-port-dev` retest showed the bound-book panel but left-clicking
did not even close the GUI. Minecraft 26.3's primary mouse button is
`InputConstants.MOUSE_BUTTON_LEFT` (value 1), while the port handler still
checked the 1.21.1 value 0. The `0.0.0.7-port-dev` slice uses the 26.3
constant. This still requires in-game verification of the full click/travel
path.
The player confirmed the `0.0.0.7-port-dev` bound Linking Book click/travel
path passes in game on 2026-10-27. The 26.3 target remains incomplete and is
not ready for a public release or closure of the parent port issue.
### Explicit technical alpha exception
At the player's request, `1.0.1.2-alpha.1` packages this limited 26.3 port as
an experimental alpha. It is **not** the full mod and does not pass the stable
release gate above. The alpha label and release notes must state that Ages use
prototype vanilla terrain, normal authoring and most content are absent, and
worlds should be disposable or backed up. The 1.21.1 stable release remains
independent; issues #96–#104 stay open until the full port and validation pass.
The next development slice, `1.0.1.3-alpha.1`, adds a basic Descriptive Book
screen and server-validated binding. Naming an unbound book creates a unique
prototype Age with a random seed; clicking the bound book's placeholder panel
uses the acknowledged-catalog travel gate. This is not authored Page binding
or a live destination preview. The player confirmed the Descriptive Book
binding and travel interaction in game on 2026-10-29.
The following `1.0.1.4-alpha.1` development iteration registers a small
Rivencraft creative tab for the two Books, Crystal Block, and Crystal Shard.
It builds and passes the dedicated-server Age smoke test. The player confirmed
the tab and four entries in game on 2026-10-29. No Page categories or
unported items are advertised in the 26.3 tab.
The next local `1.0.1.5-alpha.1` iteration selects Legacy's unwritten
Linking Book sprite until a target is bound, then the bound sprite. It also
restores the four-Crystal-Shard crafting recipe for a Crystal Block. Both
changes passed the player's in-game visual/crafting check on 2026-10-29.
The local `1.0.1.6-alpha.1` iteration ports Budding Crystal and the four
blue crystal growth stages, reusing the 1.21.1 sprites and vanilla amethyst
growth/harvest rules. Crystal clusters yield Shards, but natural crystal
formation generation remains unported. Test growth with a Creative or
command-placed Budding Crystal; the player passed the in-game check.
The local `1.0.1.7-alpha.1` iteration adds one persistent Page item with
unwritten and Link Panel variants. It reuses the existing Page/Link Panel
artwork and exposes only the Link Panel variant in its own creative tab,
matching the 1.21.1 separation of Link Pages from symbol pages. Blank Pages
remain command-only bases; the Ink Mixer, Book Binder and symbol writing are
not yet ported. The player passed the in-game visual and persistence check.
The local `1.0.1.8-alpha.1` iteration ports the Ink Vial item, its animated
sprite, and the black-dye/glass-bottle/water-bucket crafting recipe. Using
it with paper in the other hand prepares a Link Panel at the current 1.21.1
default cost of 2 ink from a 16-use vial. Ink remaining persists per vial;
an empty vial yields a glass bottle. The Ink Mixer, configurable ink cost,
and Book Binder remain unported. The player passed the in-game craft/use check.
The local `1.0.1.9-alpha.1` iteration ports the special shapeless leather +
Link Panel recipe for an unwritten Linking Book. The 26.3 recipe serializer
rejects blank Pages and extra ingredients and preserves a panel's custom name
without carrying its Page identity onto the Book. No Link Panel modifiers are
ported yet. The player passed the in-game crafting check on 2026-10-29. The
full Book Binder GUI and Age authoring remain the next larger port step.
The local `1.0.1.10-alpha.1` iteration adds the first three Link Panel
modifiers as a prerequisite to Binder authoring. All eight combinations of
Disarm, Maintain Momentum, and Intra-Linking are testable in the Link Pages
creative tab and persist as a synced component through leather crafting and
book binding. The server uses the book's flags when linking: Intra-Linking
allows same-dimension travel, Maintain Momentum rotates horizontal velocity
to the destination yaw, and Disarm drops player inventory at the departure
point only after a successful teleport. The Ink Mixer, additional Link Modifier
flags, and Descriptive Book panel propagation are not yet ported. In-game
testing of each modifier and their combinations passed in game. This local slice
must not be committed, pushed or published without the player's explicit request.
The next local `1.0.1.11-alpha.1` slice introduces the Book Binder block and
its first server-authoritative binding workflow. Leather and a Link Panel
produce a named, bound Descriptive Book for a random prototype Age; the output
is persisted in the Binder until collected. The panel's Disarm and Maintain
Momentum flags carry onto the book and apply after successful Age travel;
Intra-Linking is inert for Descriptive Books. This is not yet symbol-page
authoring or the full Legacy Binder interface. Build and dedicated-server
smoke pass. The player passed basic Binder crafting and travel in game, but
reported that typing E closed the GUI and asked us to reuse the 1.21.1 GUI
more faithfully. No
commit, push, or publication without an explicit request during alpha.
The local `1.0.1.12-alpha.1` follow-up ports the existing Binder layout's
top title field, flank slots, center Page strip, and pulsing red missing-panel
cue. It persists the title on the block entity and consumes focused keyboard
events before the container can treat E as inventory-close. Click the output
once to bind and again to collect the result. The full authored-symbol strip
and 1.21.1 grammar still await later port slices. The same slice adapts the
existing 1.21.1 Ink Mixer block, persistent basin, additive probabilities,
16-ink-per-panel exchange, virtual output, Legacy atlas and animated glyph to
the 26.3 storage, menu and GUI APIs. The build and dedicated-server Age smoke
pass. In-game Binder and Mixer verification is
pending; do not commit, push, or publish without explicit authorization.
The local `1.0.1.13-alpha.1` iteration moves the Binder's freshly assembled
book directly to the cursor so one output click both binds and takes it. Its
central strip now displays five Legacy page thumbnails, while only the Link
Panel is currently writable. The Mixer recomputes its virtual output in the
same server click as an input change to address an intermittent first-attempt
delay. The user's second Mixer attempt succeeded but exposed a cost mismatch:
the Mixer now spends one ink and one paper per Link Panel and resets its
additive chances on output pickup. Build passes; in-game retest is
pending. This alpha remains local until explicitly authorized for release.
The local `1.0.1.14-alpha.1` visual follow-up uses the new Binder dev images
as a reference: the page strip now grows only when a Link Panel is present or
carried, its required-panel cue appears above the strip, and the first page
can be clicked to place/take the panel. The stored page has a tooltip. The
rest of the 1.21.1 strip (symbol pages and scrolling) depends on porting the
symbol-page data and authoring pipeline, not just drawing more placeholders.
The local `1.0.1.15-alpha.1` follow-up changes the missing-panel cue to the
Link Panel's 16×16 item icon while preserving its red pulse and tooltip.
The local `1.0.1.33-beta.1` slice adds Flat and Void terrain to authored Binder
books. Flat uses vanilla superflat layers and can use one authored Biome; Void
generates no terrain but can use one authored Biome for environmental behavior.
Without a Biome page, Void uses `minecraft:the_void`. Books with multiple Biome
pages and Flat/Void terrain remain unassembled until their custom distribution
generator is ported. The dedicated-server smoke creates, samples, and reloads
both terrain families in a disposable world.
The local `1.0.1.34-beta.1` follow-up moves Flat ground to Y=0 and targets its
surface for travel. `1.0.1.35-beta.1` enables the selected biome's decoration
on Flat. `1.0.1.36-beta.1` ports a multi-biome Flat/Void chunk generator and
accepts the existing authored distribution pages for those terrains. New Flat
chunks can vary vegetation by biome; Void keeps biome climate without adding
a floor or decorations. These are beta-port slices, not full 1.21.1 parity.
The local `1.0.1.37-beta.1` slice ports Cave terrain authoring using the
26.3 caves noise preset. Cave and Nether Biome pages can be distributed
through an Age, and travel searches for footing from Y=64 downward rather
than mistaking the cave roof for the surface. Nether-style cave material
replacement from 1.21.1 remains a separate port task. The local
`1.0.1.38-beta.1` follow-up
keeps Cave Ages dry by default: the vanilla 26.3 Cave preset otherwise fills
low openings with water. This changes newly generated chunks only; a future
Flooded page will deliberately set an authored water level in both maintained
versions.
The local `1.0.1.39-beta.1` follow-up makes the 26.3 landing search reject
fluid at feet and head height and prevents a submerged fallback platform.
The local `1.0.1.40-beta.1` slice gives pageless Descriptive Books a
seed-selected terrain and biome plan. It follows the 1.21.1 rank weights for
terrain and biome distribution, selects registered Cave/Nether biomes for Cave
Ages and overworld-source biomes for other non-Void terrains, and persists the
resolved choices. Other random Age traits remain a later port task.
The local `1.0.1.41-beta.1` slice adds the first Age-scoped feature wrapper to
the 26.3 generator. A Block page followed by Rocks now places clusters of the
chosen block in new Standard, Amplified, Island, or Flat terrain chunks. The
Age index persists that selection, and the wrapper delegates all vanilla
terrain, biome, and structure generation. Cave and Void are intentionally
excluded until their feature placement rules are ported. This is not yet the
full 1.21.1 feature grammar or instability system.
The local `1.0.1.42-beta.1` follow-up resolves unmodified Rocks to a
seed-shuffled, full-block material and accepts up to 32 ordered Rocks pages.
Each page adds an independent, deterministic surface placement attempt.
Explicit Block modifiers still bind only to the immediately following Rocks
page. The material sequence persists in the Age index; the codec also reads
the single-material format from the previous beta. The remaining feature
families and instability scoring are not yet ported.
The local `1.0.1.43-beta.1` slice uses 26.3's `minecraft:forest_rock`
placed-feature rules and `BlockBlobFeature` for authored Rocks, supplying the
Age's selected material and removing only the vanilla biome filter. This
replaces the port's temporary 3×3 pile algorithm and follows the 1.21.1
generator's authored-placement approach. It affects new chunks only.
The local `1.0.1.44-beta.1` slice extends this Age-scoped feature wrapper to
Flowers, Trees, and Huge Trees. Ordered authored pages retain independent
attempts and use vanilla 26.3 placed-feature rules after biome decoration.
The vegetation plan is persisted alongside terrain, biome, and Rocks plans;
the dedicated-server smoke compares generated flowers and logs against a
same-seed Flat control and checks persistence after restart.
The local `1.0.1.45-beta.1` slice adds authored Dungeons separately from
surface vegetation. Its 26.3 placed-feature JSON mirrors the 1.21.1 eight
monster-room attempts over the world height; ordered duplicate pages add
attempts. The count persists in the Age index and generator codec. The server
smoke creates and samples a dungeon Age, counts monster spawners across a
4×4-chunk area, and verifies the count after restart. Room appearance and
normal book authoring remain in-game checks.
The local `1.0.1.46-beta.1` slice ports Surface Lakes, Deep Lakes, and Small
Lakes, including ordered Fluid modifiers. The 26.3 LakeFeature retains its
vanilla shape and replacement predicates while using the Age's frozen fluid
provider. Surface placement keeps Rivencraft 1.21.1's one-in-twelve rarity;
underground lakes use vanilla placement. Repeated unmodified pages resolve
their fluids independently from a seeded, shuffled source-fluid pool. Lake
plans participate in restore, unload/reload, reseed, and retirement rollback.
The server smoke compares water generation against a same-seed control and
checks explicit/random plans and fluid blocks across restart.
The local `1.0.1.47-beta.1` slice adapts the 1.21.1 FloatingIslandFeature
algorithm to 26.3 chunk access and the biomes already assigned to each chunk.
It retains source range 3, one-in-128 candidate rarity, Y=168..215 center
selection, radii 24..41, coordinate-noise contours, air-only filling, and the
biome-dependent soil cap. It supports Flat/Void in addition to noise terrains;
Block modifiers and independent seeded random materials are frozen in an
ordered terrain-feature plan. Rocks and islands share material resolution.
26.3's final NoiseBasedChunkGenerator merges noise, surface, and carving and
does not expose a pre-surface hook. This port appends islands to the completed
terrain future before decoration; existing terrain is preserved, but base
carvers do not cut the added islands. The smoke verifies actual high-altitude
material placement on noise, Flat, and Void terrain, distinct random material
choices, authored biome preservation, and block fingerprints across restart.
The local `1.0.1.48-beta.1` slice ports TendrilFeature's Legacy-derived
branching solid volumes using the 26.3 chunk mutation and height APIs. Source
range 8, rate 15, size 18, nested node/height selection, branch splitting, and
bedrock preservation match the 1.21.1 implementation. Chunk-local writes and
neighbor-source seeds preserve continuous paths across chunk borders.
The existing terrain-feature plan now supports Tendrils on all terrain types,
including Cave and Void. Compilation retains mixed feature order and applies
the 32-occurrence limit per feature. Block modifiers and seeded random choices
use the shared solid-material resolver; existing save/lifecycle handling carries
both feature types. World validation is manual at the player's request; no
development server is started for this slice.
The local `1.0.1.49-beta.1` slice ports the Legacy-derived Skylands filter
from Rivencraft 1.21.1 with 26.3 chunk height/mutation APIs. The cutoff uses
the same salt, seven octaves, initial cell width 128, amplitude 12, and base
Y=76. Solid/liquid removal and world-height coverage match the reference.
It runs once after base terrain construction and before authored solid
volumes, retaining the feature ordering used by the 1.21.1 implementation.
Skylands is a material-free feature, accepted alongside every terrain type.
Repeated pages retain the same idempotent effect. The existing terrain-feature
plan stores an optional Skylands flag, defaulting to false for earlier beta
Ages; no separate backend/lifecycle path is introduced. A Skylands-only plan
can contain no material choices. Build and static checks are automated; world
generation and restart validation are left to the player.
The local `1.0.1.50-beta.1` slice adapts the 1.21.1 SpheresFeature and
SpikesFeature to 26.3. Spheres retain their source range 8, five-percent
source chance, nested Y selection starting at 32, node geometry, and bedrock
protection. They run after the base terrain/Skylands filter and work on every
terrain type. Spikes retain their one-in-18 chunk chance, 6..37 height roll,
width 1..4, solid-footprint checks, and chunk-local writes during decoration.
They remain unavailable on Cave and Void terrain, matching 1.21.1.
Both page types use ordered saved solid-feature choices, preceding Block
modifiers, and independent seeded materials/occurrences. No backend lifecycle
branch or generated artwork is added. Compilation and static review are the
automated checks; the player handles generation and restart validation.
The local `1.0.1.51-beta.1` slice ports ObelisksFeature using the 26.3 chunk
coordinates and world-height APIs. The site salt, seed mixing, one-in-128
chance, chunk-local site selection, 4×4 plinth, and 2×12×2 shaft match 1.21.1.
Every footing column must be sturdy, dry, and free of block entities; the
base surface can vary by at most two blocks and the full shaft must be open.
No partial structure is written when a placement check fails.
The page joins the existing material-feature plan and shared material resolver.
It runs during surface decoration, with its own occurrence counter, on all
surface terrain types including Flat; Cave and Void remain unsupported.
Spikes and Obelisks use shared stage/restriction classification. Build/static
checks are automated; generation and restart checks remain with the player.
The local `1.0.1.52-beta.1` slice ports CrystalFormationsFeature directly
from 1.21.1 with only registry, ChunkPos, and height API substitutions. It
retains the site salt, one-in-fifteen rarity, 3×3 ground/clearance checks,
three-block center height, randomized outer heights, budding hearts, and
initial small buds. Existing blue crystal growth, sprites, drops, and sounds
are reused without adding assets.
Crystal Formations is an ordered surface feature with fixed crystal material,
not a consumer of Block/Fluid modifiers. It shares the existing saved feature
plan and surface-terrain restrictions (including Flat, excluding Cave/Void),
with independent occurrence seeds and the current 32-page cap. No backend
lifecycle changes are needed. The Obelisks slice passed the player's in-game
check; Crystal Formations build/static checks pass, with generation, growth,
and restart validation handed to the player. No test server is started.
The local `1.0.1.53-beta.1` slice adapts 1.21.1 AgeDenseOres to modern
`AbstractOreFeature` targets and `FeaturePlacer.placeWithBiomeCheck`. It keeps
the common ore tag/name fallback, explicit `rivencraft:dense_ores` placed-
feature opt-in tag, nearby biome discovery, stable registry-ID ordering,
and independent per-occurrence seeds. Registered modded ore features remain
eligible without depending on an ore-providing mod. Biomes and ore placements
are collected once per chunk rather than once per repeated page.
The optional Dense Ores count is saved in the existing terrain-feature plan;
older plans default to zero. Grammar accepts 1–32 occurrences on noise terrain
(including Cave), rejects Flat/Void and material modifiers, and checks explicit
biome pools for at least one eligible ore feature. No extra lifecycle path or
asset is introduced. Random feature selection and instability remain later
port work. Crystal Formations passed the player's in-game check; this slice
passes build/static checks, with ore generation and restart validation manual.
The local `1.0.1.54-beta.1` slice ports Star Fissures. Its footprint matches
1.21.1 exactly (including Legacy attribution); carving uses the dimension's
minimum Y, clears fluids, and protects Cave terrain's roof. The authored flag
is optional in the existing feature-plan codec. Duplicate pages retain the
1.21.1 single-fissure result; all terrains are accepted, with no material
modifier. Random feature selection is not introduced in this slice.
First arrival generates the fissure and stores its spawn/completion in per-Age
SavedData. Re-entry/restart does not repeat carving; an obstructed saved arrival
is rechecked for safe footing. The return block ports modern entity-inside and
TeleportTransition APIs, has a registered Rivencraft block-entity type, and
uses Minecraft's starfield renderer with 1.21.1 face offsets. Shared Overworld
spawn safety search and fallback match 1.21.1, rather than respawning at a bed.
The existing fissure OGG/model are reused. Client renderer registration stays
client-only; the block has no item/drop and is inert in the Overworld.
Dense Ores passed the player's in-game check. Build, footprint comparison,
resource packaging, and static checks pass for this slice. Generation, visual
rendering, actual return travel, and restart checks are left to the player;
no development server is started.
The local `1.0.1.55-beta.1` slice begins the authored structure-set port with
Villages, Mineshafts, and Strongholds. Saved page occurrences use the existing
feature plan's new optional structure list. Terrain gates, random-spread
frequency/spacing scaling, and bounded concentric-ring count/spread follow
1.21.1. Modern `AbstractSpreadingStructurePlacement` accessors replace the old
placement-class accessors. Scaled holder copies never mutate global registries.
Structure-state planning includes authored eligibility biomes while continuing
to sample the actual terrain source. A scoped Structure mixin carries over
1.21.1's authored biome override. The wrapper handles structure starts itself
when a structure plan exists, allowing the hook to recognize the authored Age;
unrelated/unplanned generators remain delegated. Only these three controlled
families are gated in this slice; remaining structure families, random picks,
and biome-mismatch instability remain unported. Existing plans without the
optional list retain their previous structure path. Mod metadata now correctly
calls this target Beta rather than Alpha.
The player passed Star Fissures. Build/static checks pass for this new slice.
A disposable dedicated-server startup reached `Done` without mixin-loading
errors. Its console `/stop` command hit a null-level CommandSourceStack error;
the exact test JVM was then stopped through SIGTERM and saved/shut down. This
was a startup check, not authored generation or density validation. The
disposable world is removed; client authoring, actual structures, density,
biome overrides, and restart checks are handed to the player.
The local `1.0.1.56-beta.1` follow-up corrects the structure biome override.
Client logs confirmed the build-55 mixin was applied, but 26.3 JigsawPlacement
checks `GenerationContext.couldStructureExistInColumn` inside generation,
before the final check bypassed by the 1.21.1 hook. The replacement ModifyArg
changes only the biome predicate passed to the GenerationContext constructor
in Structure.generate for explicitly authored Age structures. Both early
and final checks now see the override; all other generation constraints and
unrelated generators retain their existing behavior.
Build/static checks pass. An isolated `--initSettings` bootstrap initialized
settings without a mixin application error, then FML exited nonzero because
that settings-only mode creates no server thread. This is not a full server
or generation pass. No world was created, and the temporary settings directory
is removed. In-game validation requires a new Age or ungenerated chunks;
previously rejected chunks are not regenerated. No commit/release is made.
The local `1.0.1.57-beta.1` slice completes the existing 1.21.1 structure-page
mapping (Dungeons remains its separate placed feature) and enables 26.3's
Abandoned Camps page. The shared planner now recognizes 15 structure sets.
Page/terrain restrictions match AgeStructureSelection for the 1.21.1 families;
Abandoned Camps follows surface noise terrain. No material modifiers are added.
The separate Fortress/Bastion set resources are reused directly from 1.21.1.
The controlled-set gate includes the vanilla combined Nether set, preventing
unrequested cross-family placement. All structure pages share the previously
validated saved list, density logic, and corrected context-level biome override.
Unknown non-spreading placements are left unchanged rather than cast unsafely.
Unmodified/no-authored-structure Ages retain their prior native path; previously
saved authored plans now gate all supported families in new chunks. Instability
and random feature selection remain pending.
The player passed the build-56 biome fix. Build, diff checks, all 15 registry
and Creative-page mappings, and target structure resource existence checks pass.
Packaged Fortress/Bastion definitions match 1.21.1 byte-for-byte. No server is
started; actual structure placement, terrain-specific limits, repeated density,
and restart validation are handed to the player. Changes remain local.
The local `1.0.1.58-beta.1` slice ports Caves/Ravines feature pages separately
from Cave terrain. A new optional saved carver-page list participates in the
existing feature-plan lifecycle. Grammar accepts noise terrain including Cave,
rejects Flat/Void and material modifiers, and checks the modern CARVER registry.
26.3 combines carving with terrain construction and exposes carvers that emit
geometry rather than mutate blocks. A scoped NoiseBasedChunkGenerator mixin
adds authored geometry to its native CarvingMask immediately before that mask
is tested/applied. It only acts for the matching runtime Age wrapper, using
its frozen seed and actual biome resolver. Vanilla applies the combined mask
with its own aquifer/surface rules; no closed NoiseChunk is accessed afterward.
The source range, salts, Nether cave selection, and Nether ravine skip match
1.21.1. Duplicate Caves/Ravines repeat identical seeds in the baseline, so the
port avoids redundant identical mask passes while retaining authored pages.
Added terrain volumes still follow the combined terrain operation, as noted
for the earlier Floating Islands port.
The player passed structure slice 57. Build/static checks and packaging checks
for the hook, Creative entries, and three required vanilla carvers pass. A
settings-only bootstrap completed initialization without a mixin application
error; FML then returned nonzero because no server thread exists in that mode.
This is not world-generation validation. No world was created; the temporary
settings directory is removed. Actual carving and restart checks are manual,
and no commit/push/publication is performed.
The local `1.0.1.59-beta.1` slice replaces stale per-page port information
and adds the requested red hue for unsupported pages. A shared
PortAuthoredWriting.isPageImplemented classifier uses the same terrain,
controller, material/biome, and feature recognizers as the grammar, without
misclassifying context-dependent modifiers/controllers by testing them alone.
Page tooltips, the extracted item-render color, and the Binder background use
this single availability check. Tinting does not generate extra textures or
change stored page data. Corrupted-page names/descriptions remain obfuscated.
Port language overrides remove the old Standard/one-Biome claim, distinguish
implemented/unimplemented pages and invalid combinations, and correct all
15 structure-family descriptions, material adjacency, and selected terrain/
feature restrictions. The 1.21.1 language assets are unchanged. This is a UI
and information slice, not new generation functionality.
The player passed Caves/Ravines. Build, diff checks, unique language-key checks,
and packaged-language override checks pass. No server/world is started.
Inventory tint, Binder tint/layering, and tooltip readability await the
player's visual check. Changes remain local and unpublished.
The local `1.0.1.60-beta.1` slice implements the four requested 26.3-only
vegetation pages: Poplar Trees, Fallen Poplar Trees, Red Shrubs, and Shelf
Mushrooms. They extend PortVegetationPlan recognition, so grammar, saved plans,
Creative status, item tint, and tooltip availability agree without another
page list. The existing ordered vegetation cap and surface-terrain/biome
restrictions are retained. The 1.21.1 code/assets are unchanged.
Poplar Trees selects only the three vanilla poplar variants, retaining their
relative native weights and six placement attempts. Fallen poplars reuse the
vanilla feature but add authored in-square/surface placement before its sapling
check; the vanilla placed feature alone has no surface-height placement. Red
Shrubs directly reuses its registered patch. No tree/shrub algorithm or artwork
is duplicated.
Shelf Mushrooms is a tree decorator in 26.3, not a placed feature. The authored
page therefore applies ShelfMushroomDecorator to existing connected log hosts
at its position in the vegetation sequence. Section palettes skip log-free
sections, repeated pages reuse the host scan, and tree placements invalidate
that cache. Host ordering and page seeds are deterministic; callback writes
are chunk-local, fluid-free, supported, and height-bounded. The decorator keeps
its native standing/fallen logic and side/age/adjacency checks. This is an
authored extension using the native decorator, not a new vanilla feature ID.
Build/static and resource-reference checks pass. The four pages' descriptions
explain their actual effects and requirements. No server/world is started;
the player validates vegetation appearance, support/tint, ordering, and restart.
Changes remain local and unpublished.
The local `1.0.1.61-beta.1` follow-up separates log-hosted Shelf Mushrooms
from surface plants. A shared requiresSurface classification now governs
terrain/explicit-biome validation; decoration handles Shelf Mushrooms before
the surface-biome skip. Trees, shrubs, and flowers retain their restrictions.
Void/Cave/End-biome log hosts are no longer excluded by the vegetation path.
The host scan is a stable log-position list rather than connected tree groups.
Native tree decorators assume a meaningful base and only decorate a limited
height band, which is unsuitable for log tendrils. The authored extension
therefore checks exposed log faces at all heights, reusing the native decorator's
replaceability/water predicate and block facing/age/survival rules, with spacing
and chunk bounds. Cached scans still avoid repeated full-volume work. No tree
page or log-producing page is required, but actual log hosts must exist during
chunk generation. This supersedes slice 60's whole-tree height-band behavior.
Build/static checks pass. Manual validation: new Void + Oak Log + Tendrils +
Shelf Mushrooms Age, without any tree page; inspect exposed log faces and
restart/new-chunk generation. No server is started and nothing is published.
The player passed the local `1.0.1.62-beta.1` sound slice: the complete 1.21.1
sound manifest/OGGs are reused, book travel emits modifier-selected audio and
cloud bursts, and Star Fissures play audio after arrival as well as departure.
Portal/meteor events are registered but their gameplay ports remain separate.
The local `1.0.1.63-beta.1` slice adds authored Normal/Fast/Slow/Off/Always/Storm
weather policies. One policy is accepted per book, with availability/tint and
tooltips following the shared classifier. Cave terrain always suppresses it.
An omitted policy defaults to Normal for now; random-trait selection is pending.
Unlike 1.21.1, 26.3 ServerLevel.getWeatherData delegates to the server's shared
weather object. A scoped Runtime Age ServerLevel subclass instead loads native
WeatherData from that Age's data storage, alongside its saved policy. Native
weather ticking and client packets remain in charge; only the data owner and
Legacy-style duration policy change. The constructor replaces inherited global
rain/thunder visual levels before publishing the level. Retirement, reseeding,
reload and restart retain the policy through existing per-Age storage lifecycle.
Vanilla /weather remains a global server command; the Age policy is not a
global command override. Native biome precipitation rules still apply.
Build/diff checks pass. A disposable dedicated server created all six weather
policies: every Age reported independent native data and the expected flags/
duration ranges. Setting global thunder left the Off Age clear. Unload/reload
retained Storm, and a full stop/restart restored all six policies and their
live timers. Both servers shut down cleanly; the temporary test world is
deleted after completion. Client appearance, cross-Age travel, authoring/tint,
and Cave suppression remain manual checks.
No commit/push/publication is authorized by the player's testing pass alone.
The local `1.0.1.64-beta.1` follow-up fixes weather-only authoring. Build 63's
server weather checks bypassed the Binder's biome compiler, whose exclusion
list did not yet include weather. As a result weather/storm was incorrectly
resolved as a biome ID despite grammar acceptance. The biome compiler now
selects actual biome-category entries after full-book grammar validation;
controllers retain their separate handling. This avoids repeating the same
missed-exclusion bug as more non-biome page families are ported. The operator
weather fixture now calls that compiler before backend creation. All six
weather-only symbol lists compiled and created their expected weather states
on a fresh dedicated server. Build/diff checks pass. The server shut down
cleanly and its disposable world was removed; player GUI validation remains.
The local `1.0.1.65-beta.1` spawn correction traces non-Cave arrival columns
from maximum build height, inspecting actual fully generated chunk blocks.
The configured Flat-layer shortcut could select ground below later authored
terrain, and the old heightmap-only path did not explicitly ensure an exposed
surface. The new path stops at the first fluid/leaves/collision, requires dry
footing and headroom, and otherwise tries the next column rather than searching
below an obstruction. Chunk lookup is cached per column and a mutable position
avoids per-air-block allocations. A fallback platform goes above the actual
highest obstruction; empty Void retains floor Y=63. Surface footing accepts
leaves, rejects fluid-bearing floors, and checks build/border bounds.
Stored non-Cave Star Fissure arrivals also use the surface search rather than
accepting old underground pockets. Cave terrain keeps its Y=64-down search.
Exact bound Linking Books and the general fissure Overworld-return anchor
search are not redirected to the sky. A read-only surface probe command helps
validate the chosen column/nearby surface (chunk generation is possible).
Build/diff checks pass. A disposable dedicated-server probe selected Y=4 on
plain Flat ground, Y=141 above leaves placed at Y=140, and a neighboring dry
column instead of descending below water added above those leaves. A larger
roof-fixture fill was rejected by vanilla because some target chunks were not
loaded; that fixture is not claimed as tested. The server shut down cleanly,
and its temporary world was deleted. Actual player arrival in the affected
Age and the unchanged Cave/Linking Book paths remain manual checks.
The local `1.0.1.66-beta.1` slice ports the three 1.21.1 lighting controls.
Normal surface types keep the host Overworld holder; Dark disables skylight,
Bright sets ambient light to 0.25. Cave Bright is explicitly supported with
0.25 ambient and no skylight; Cave Normal/Dark have 0.0 ambient and no skylight.
The native vanilla registry-sync path supplies types to clients before travel.
Generated data derives three variants from the exact 26.3 vanilla Overworld
resource, preserving every key except has_skylight and ambient_light. The
generator has declared inputs/outputs and depends on Minecraft artifacts.
The Age index has an optional lighting map, defaulting old entries to Normal.
Creation supplies the choice before constructing the level and saving the
index. Restore/reload/reseed read it from the index; retirement removes it and
failed retirement restores it before reloading. Pages share grammar/tint and
the positive biome-page filter, avoiding the weather-only compiler regression.
Missing lighting stays Normal until the random-trait port; Bright instability
is pending with the instability system. No sky/celestial renderer is added.
The static variants derive vanilla data, not arbitrary data-pack overrides
to the host's Overworld type; broader custom type inheritance is not claimed.
Build/diff checks and generated-data equality checks pass (only the two
lighting fields differ from vanilla). A disposable server with a normal
Overworld compiled all six surface/Cave lighting-page combinations and
reported the expected type, skylight and ambient values. Cave Bright survived
unload/reload and reseeding, and all six choices survived a full restart.
Overworld skylight/ambient stayed unchanged. An earlier Superflat-host fixture
could test surface variants but could not create Cave terrain because the
existing backend requires a noise-based host generator; it was discarded and
the Cave checks ran on a fresh normal-host fixture. Test servers stopped
cleanly and both temporary worlds were deleted. Client-side appearance,
authoring, travel, placed lights and multiplayer registry behavior are manual
checks, not inferred from the server probes. No commit/push/publication.
The local `1.0.1.67-beta.1` corrects the visual failure found in slice 66:
LightmapRenderStateExtractor and lightmap.fsh use AMBIENT_LIGHT_COLOR, while
dimension ambient_light only affects other brightness queries. Merely porting
1.21.1's 0.25 field was insufficient. Bright types now provide white native
ambient color and ambient_light 1.0; Cave Bright retains no skylight. A scoped
NeoForge spawn-placement handler denies natural/chunk-generation MONSTER
spawns in Bright runtime Ages, leaving passive/existing mobs, spawners,
commands/eggs and event spawns untouched. It does not manufacture propagated
block light or alter crop light checks. This supersedes slice 66's Bright
appearance and natural-spawn limitation; existing Bright types update on boot.
Requested follow-up for the color-page port: add ambient-light color as a
separate authorable target using minecraft:visual/ambient_light_color. Keep
the existing number/color mixing semantics and white Bright default; do not
confuse ambient tint with sky/celestial color or its server spawn policy.
Color pages themselves remain unported in this slice.
Build/diff and generated attribute checks pass. A disposable dedicated server
verified the registered event handler denies a successful-default natural
zombie placement in surface/Cave Bright, leaves spawner zombies and natural
cows unchanged, and leaves Normal unaffected. Those are isolated event-policy
probes, not a long-running natural-spawn census. The server shut down and its
temporary world was deleted. Actual client appearance awaits player validation.
The local `1.0.1.68-beta.1` removes the requested-against MobSpawnEvent veto.
An Age-scoped LevelLightEngine.getRawBrightness return modifier contributes
Bright's full ambient minimum of 15 to combined brightness on both sides.
Vanilla Monster.isDarkEnoughToSpawn now sees that light, rather than being
overridden or filtered by mob category/spawn reason. Light-ignoring mobs and
special spawns retain vanilla rules; no spawner exemptions are introduced.
Block/sky storage and propagation remain physical, while combined-light
consumers (including plant checks) see ambient light. Cave Bright retains
no skylight, and the native white render attribute remains. This supersedes
slice 67's separate spawn policy and unchanged-crop-light behavior.
The lighting probe now calls vanilla's darkness predicate and combined
brightness instead of constructing synthetic spawn events. Ambient-color
authoring remains a planned part of the color-page port.
Build/diff checks pass. A disposable dedicated server loaded the required
mixin and reported effective brightness 15 / vanilla darkness false for
surface/Cave Bright, versus 0 / true for Dark. These are direct brightness/
vanilla-predicate probes, not a natural-spawn census or a fully generated
underground-room test; an unloaded Normal column returned native sky light 15.
The server stopped cleanly and its temporary world was deleted. Client visual
validation remains with the player; no publication is performed.
The local `1.0.1.69-beta.1` slice completes missing weather/lighting choices
at book binding. PortEnvironmentSelection resolves explicit supported pages
first and uses independent seed-salted Legacy-rank rolls for omissions.
Normal is rank 1, remaining supported modes rank 2: 3:1:1 lighting and
6:1:1:1:1:1 weather. These weights derive from the active enum pool and reuse
the existing weighted ticket routine, rather than duplicating random-choice
logic or enabling unported Cloudy/Rain/Snow modes. It is rank-policy parity,
not exact seed-stream parity with 1.21.1's broader trait pool.
The selected weather/lighting are passed through the existing save-before-
catalog creation path. Restoring Ages never calls the resolver, so old Ages
retain their saved values. Cave weather is always Off; Cave lighting remains
independent and supports Bright. Explicit developer fixtures remain controlled,
but create_random now uses the same resolver as pageless books. A read-only
environment probe checks seed repeatability and explicit overrides. Superseded
Normal-only fromPages helpers are removed. Random feature, sky/celestial,
blocklist policy and instability work remain pending.
Build/diff checks pass. Disposable dedicated-server probes repeated seeds
0/4/7, verified explicit overrides and independent one-field completion, and
confirmed Cave weather Off with Bright lighting. Three random Ages saved
Always/Normal, Normal/Dark and Fast/Bright respectively; weather/lighting
choices and live weather timers persisted through a full server restart.
Overworld weather/type stayed unchanged. The server stopped cleanly and its
temporary world was deleted. Player book-authoring/visual checks remain
manual. No commit, push or publication is performed.
The local `1.0.1.70-beta.1` slice ports native Overworld/Nether/End sky styles.
The shared grammar accepts one style and the biome compiler ignores it by
category. Sky is saved in an optional Age-index map with Overworld fallback;
restore/reseed/retirement rollback use the saved choice. It does not alter
the missing-weather/lighting seed-completion rules, add random sky selection,
or enable Static Sky/color/individual-celestial pages prematurely.
The dimension-data generator now produces 11 sky/lighting variants from the
vanilla Overworld baseline. It changes visual skybox/fog/cloud settings only
in addition to lighting. Geometry, scale, ceiling, monster settings, default
clock and gameplay attributes are retained; no Nether gameplay or End dragon
fight is inherited. A derived native day timeline omits only sky/fog/cloud
color tracks for non-Overworld styles, preserving schedules and illumination.
Native End/no-sky rendering needs no optional renderer or new artwork. The
Legacy animated Static Sky renderer cannot be replaced by native flat gray
without losing its behavior, so its page remains red/unimplemented.
Bright detection includes all registered sky variants, preserving both white
ambient rendering and the effective brightness floor for surface/Cave Bright.
Data equality checks confirm all 11 variants preserve geometry/gameplay and
the day timeline keeps native tracks except the three excluded visual colors.
Its global time markers remain defined only by minecraft:day, not duplicated
in the derived timeline. The grouped timeline list is registered as a tag.
Client appearance and multiplayer travel validation remain manual.
Registry validation initially caught an invalid inline tag reference and
duplicate global clock markers in the derived day timeline; both were fixed
before handoff. The sky diagnostic also now supplies a position when sampling
the spatial fog attribute. A disposable dedicated server then restored all
sampled types after restart, including Nether normal/Bright and End normal/
Cave Bright, with the expected reddish/purple fog at the sample position,
unchanged geometry/gameplay flags, and effective light 15 on Bright variants.
Cave Bright End retained its type after unload/reload; a reseeded Nether Age
retained its style after restart. Servers stopped cleanly and temporary test
directories/worlds were deleted. These are server/data checks, not a rendered
client pass. No commit/push/publication is performed.
## Static Sky renderer slice
`1.0.1.71-beta.1` ports the 1.21.1 Legacy-style animated Static Sky, superseding
the previous unsupported/red status. The six independent 48×48 noise faces
use the existing default gray tint (146 per channel), noise range 65–224,
and a two-world-tick refresh. A cached 24-vertex cube and a single 288×48
dynamic texture use the native textured sky pipeline instead of rebuilding
thousands of colored cells every frame. No new asset or dependency is needed.
Client-only mixins carry the animation frame in extracted sky state, reset
it with the state, and own/close GPU resources with SkyRenderer. Static types
have native skybox NONE; the extracted state alone requests a sky pass and
the custom renderer replaces it. End flashes and End gameplay are not enabled.
Normal/Dark/Bright/Cave Bright variants preserve the existing lighting policy,
geometry and gameplay. Existing persistence handles STATIC as a sky enum value.
Random sky selection, color pages, and individual celestial bodies remain
separate unfinished work; this slice does not claim complete sky parity.
Verification: port build passed (no automated unit tests configured). A
disposable dedicated server created Static Standard Normal and Static Cave
Bright Ages, confirmed their gray fog, NONE native skybox and correct skylight/
ambient values, then restored both choices after restart. It stopped cleanly;
the temporary server/world was deleted. Client animation, travel between sky
styles, and restart appearance still require manual validation. No user world
was modified, and nothing was committed, pushed or published.
## Seeded sky completion slice
`1.0.1.72-beta.1` completes missing sky controllers using the first seeded
selection from 1.21.1 `AgeSkyProfile.random` (`0x534B5950524F464C` salt).
Inherited and Overworld currently map to the same native Overworld style;
the effective Overworld/Nether/End/Static weights are 2:1:1:1. This deliberately
ports only style selection, not random colors or celestial-body lists.
The player book path and `create_random` fixture now share one environment
record containing weather, lighting and sky. Explicit pages win. Separate
seed streams keep controllers independent, including when one is supplied
explicitly, and Cave weather remains Off. Existing Age index values/defaults
remain authoritative; this does not reroll old Ages or reseeded Age skies.
The one-purpose controlled fixtures keep their explicit Overworld defaults.
The environment probe checks repeatability and every explicit sky override
with and without explicit lighting/weather. Manual seeds 0–11 and -1 covered
all four sky choices, Cave and Void, without changing established weather/
lighting results; signed-long boundary seeds also passed. Disposable-server
fixtures created all four random styles plus Bright Static and an explicit
Overworld override. Static survived unload/reload; Nether retained its saved
style after reseeding to an End-selecting seed. All six choices survived a
server restart. The server stopped cleanly and its temporary world was deleted.
The port build passed (no unit-test sources are configured). Player rendering
still needs validation of new book creation and travel. No user save is changed
and nothing is committed or published.
## Shared colors and ambient-light target slice
`1.0.1.73-beta.1` adapts the 1.21.1 `AgeSkyProfile.ColorAccumulator` rules:
Number 0–24 followed by Red/Green/Blue adds ten times that amount to one
channel, White adds to all, Black subtracts from all, and final channels are
clamped. Unnumbered colors use the same seeded index-salt approach. Color
groups preceding Sky pages, or trailing the book, tint the sky. No colors
means native rendering; omitted channels within an authored group are zero.
The new port-only `lighting/ambient_color` target consumes the preceding group
as ambient color instead. It appears in the existing Lighting creative tab
and uses the shared procedural glyph/item compositor, not generated artwork.
Profiles are frozen in the Age index with native defaults, retained on reload/
reseed/retirement rollback, and included in the full catalog. The catalog
protocol is now 2; both peers need the matching beta. The client replaces its
profile map before catalog acknowledgment, invalidates the current attribute
cache and clears the map on disconnect. Age-only default-layer hooks apply
the native sky/fog/ambient RGB attributes dynamically; vanilla dimensions are
not changed. No runtime dimension registry mutation or RGB variant explosion
is involved. Client sky state carries tint separately from the live world:
Static cells use that tint, and the native End texture uses a color modulator.
Native celestial rendering is otherwise unchanged; authorable bodies remain
pending. Explicit ambient tints do not alter the effective Bright floor or
fabricate block/sky light; native lightmap tinting controls their appearance.
Numbers are supported only before shared colors in this slice. Celestial
numeric modifiers and variable Static resolution (#109) remain unsupported.
Random sky color completion and deprecated legacy fixed-color aliases remain
pending; this is not a claim of full celestial/color parity. Rendering needs
manual checks of authored groups, all sky types, ambient color, no leakage on
travel/reconnect, and persistence. Dedicated-server fixtures exercise known
RGB results, zero/upper amounts, clamping, seeded repeatability, rejection of
dangling numbers, and a catalog encode/decode round trip. All four colored
styles and an uncolored native fixture restored correctly after restart with
the expected sampled RGB attributes. The server stopped cleanly and its
temporary world was deleted. Port build/static checks passed; there are no
unit-test sources configured. Client rendering and live multiplayer sync
remain manual checks. No commit, push, or publication was requested.
## Authored native day-cycle slice
`1.0.1.74-beta.1` ports Normal Time with Full/Half/Double/Zero Length modifiers,
using the fixed values from the 1.21.1 symbol definitions. Number pages before
Length apply the existing `CelestialPageValues` rule (`number × 0.08` days).
Zero chooses a seeded time once and saves it. Missing Normal Time retains the
native cycle. The strict interim grammar requires at most one Length preceding
one Normal Time; broader ordered recovery and multiple celestial bodies remain
separate work. Number targets other than colors and lengths are still unported.
The Age index persists a native-default day-cycle profile. Lifecycle load,
reseed, retirement/rollback and catalog sync include it. Catalog protocol 3
carries the new profile map; clients replace it before acknowledgment, clear it
on logout and invalidate current attributes/sky brightness. Both peers need
the same beta build. A small Age-only Builder mixin preserves native dynamic
timeline ordering and weather layers, but supplies a read-only wrapped clock
manager for this Age's timeline samples. Its clock instances are cached per
definition, read profiles lazily (including during level construction), and
delegate non-Overworld clocks untouched. No global clock mutation occurs.
Native day shading, sun/moon tracks, moon phase, and gameplay attributes in
those timelines share the scaled sample. Zero has a constant integer sample,
rate zero, and partial tick zero, preventing the prior stopped-time bounce.
This does not accelerate blocks/entities, change the native `/time query`
result, make a Nether/End/Static sky show bodies, or port custom bodies. Global
time commands still affect moving samples. Authored RGB overrides and existing
Bright/Dark behavior remain independent. Separate Sun/Moon, angle/phase/size/
direction, eclipses, and randomized celestial completion are still pending.
Fixtures validate parser eligibility, known half/double/zero clock values,
Number overrides, deterministic stopped time, and the shared catalog codec.
At shared native time 18022 the sampled Full time was 18022 (sky light 4),
Half 36044 (sky light ~13.92), Double 9011 (sky light 15), and Zero stayed at
11611 with its unchanged sun angle. An unmodified Age matched Full exactly.
Zero survived unload/reload and reseeding without rerolling; the color fixture
retained its RGB values. All authored profiles, numeric endpoints 1/24, zero
override, native fallback, and the color fixture restored after server restart.
The final port build passed (no unit-test sources configured). Test servers
stopped cleanly; their temporary world was deleted. Visual/client reconnect
checks remain manual. No commit/push/publication is performed without an
explicit request.
## Native cycle phase and direction slice
`1.0.1.75-beta.1` extends the existing day-cycle profile with a saved native
clock origin, phase offset and direction. Phase conversion is adapted directly
from 1.21.1 `AgeDimensionService.applyInitialCelestialPhase`: the symbolic
angle is measured from Nadir, then shifted 18000 native ticks. Rising/Zenith/
Setting/Nadir give 0/6000/12000/18000, and preceding Number pages override a
Phase using the `CelestialPageValues` 15-degree rule (24 wraps to 0). Length
and phase remain independent. Explicit phase starts at Age creation, not at
the current Overworld position divided by Length.
Moving samples are `direction * (nativeTicks - origin) / period + phase`;
Counterclockwise reverses the native day timelines, including moon-phase and
gameplay tracks. Stopped samples remain constant and prefer written phase,
otherwise the previous saved seeded stopping time. Existing profiles without
the new optional fields retain their former behavior. Saved/profile lifecycle
and catalog synchronization already carry the extended codec. Catalog protocol
4 requires matching client/server beta versions. No registry types, textures,
or global clock mutations are added. Angle/size/per-body color and multiple
celestial rendering remain pending, as do eclipses and random celestial
completion. #110's Time/Normal Length naming changes remain separate work.
The interim grammar accepts at most one Length, Phase and Direction preceding
one Normal Time; numbers currently target Color/Length/Phase only. Fixtures
check all phase mappings at a shared origin, forward/reverse deltas, stopped
behavior, parsing of the earlier three-field profile, and full catalog codec
round trips. At native tick 1518, profiles sharing origin 496 and noon offset
sampled 7022 forward and 4978 backward, with sun angles ~10.756° and ~349.244°.
Zero Zenith stayed at 6000 / 0° / sky light 15; Zero Nadir stayed at 18000 /
180° / sky light 4. Number 6 yielded sunrise; Number 24 yielded midnight.
The reverse profile survived unload/reload; reseeding retained frozen midnight.
All sampled profiles restored after a server restart, retaining their origins,
direction and fixed phases; the old-style seeded Zero fixture also retained
its saved stopping time. Build checks passed (no unit-test sources configured).
The test server stopped cleanly and its temporary world was deleted. Rendered
motion and reconnect behavior remain manual. No commit/push/publication is
performed without explicit direction.
## Native orbital bearing slice
`1.0.1.76-beta.1` ports the four Angle pages and the existing 1.21.1
`CelestialPageValues` number rule (15° per number, modulo 360). North/East/
South/West map to 0/90/180/270. The interim grammar accepts one Angle before
Normal Time, independent of Length, Phase and Direction. Missing Angle keeps
the native orientation rather than enabling random-bearing completion.
The cycle codec adds an optional bearing defaulting to -1 (native). Existing
origin/phase/direction defaults and lifecycle persistence remain unchanged.
Catalog protocol 5 carries the extended profile; older peers must update.
Extracted sky state carries/resets bearing. Native SkyRenderer's Y rotation
for the shared sun/moon/star path uses the explicit value; the sunrise/sunset
pose receives the corresponding delta from the native -90° body bearing, with
balanced pose-stack restoration. No live-world lookup occurs during drawing.
Colors, native geometry/textures, phase timing, illumination, and direction
are retained. Angle changes only horizontal orientation, not altitude. Body
counts/sizes/colors and eclipses remain pending; no extra rendering backend,
asset or registry variant is introduced. #110 is deliberately not implemented
as part of this port slice.
The port build passes (no unit-test sources configured), and the targeted
PoseStack invocation signature was checked against the patched native class.
Disposable-server fixtures exercise cardinal values, all 0–24 Number values,
six-field profile fallback, and the complete catalog stream codec. All four
frozen-sunrise fixtures sampled the same time 0 and sky light ~14.19; only
their saved bearings differ. Number 3 gave 45°, Number 24 gave 0°. Unwritten
bearing retained -1. East survived unload/reload; the 45° profile retained its
bearing after reseed. Client rendering/glow alignment and travel isolation
still require manual validation; server probes cannot prove the drawn result.
All six explicit bearings and the native fallback restored correctly after
restart. The test server stopped cleanly and its temporary world was deleted.
No commit/push/publication is performed without an explicit request.
## Celestial-compatible missing-Sky fallback
`1.0.1.77-beta.1` restricts the missing-Sky fallback for celestial writing to
the current renderer's compatible style, Overworld. Normal Time no longer
inherits an unsuitable seeded Nether/End/Static background. The resolver
also recognizes Sun/Moon intentions for future support without enabling
those pages prematurely. Explicit Sky pages always win; no-celestial random
selection, terrain, and independent weather/lighting streams are unchanged.
No packet or saved-profile format changes are needed. Existing Ages retain
their saved style; tests of the fix must create new Ages.
1.21.1 comparison: `AgeSkyProfile.compile` starts with inherited sky style;
the bundled Age profiles all use the Overworld dimension type. Authored Sun/
Moon selects `AgeEnvironmentCompiler.CUSTOM_SKY_EFFECTS`, whose renderer draws
the body list after its background without a sky-style exclusion. Thus the
bundled 1.21.1 paths already avoid this visibility regression, and no follow-up
issue or root-code change is needed for them. This is not a claim about every
possible third-party datapack profile.
The environment diagnostic checks missing/explicit Sky for Normal Time, Sun,
and Moon, including both explicit-page orders, and verifies other environment
choices are unchanged. The day-cycle fixture now supplies no Sky page and
uses the same environment resolver as player books. Client creation/travel
checks remain manual. Build and disposable-server creation checks passed:
Normal Time without Sky selected native Overworld for seeds 0, 6 and 8,
while the same seeds without celestials retained Nether, Static and End.
Explicit-Sky precedence and independent environment choices passed the
diagnostic checks, including Cave terrain. The server stopped cleanly and
its temporary world was deleted. No commit/push/publication is performed
without an explicit request.
## Normal Time sun size
`1.0.1.78-beta.1` ports Small/Normal/Large Celestial Size modifiers to the
native Normal Time sun. Presets are 0.5×/1×/2×. An immediately preceding Number
uses the root compiler's `0.25 + number * (2.75 / 24)` rule, covering 0.25×
through 3×. Root Normal Time creates a size-modified sun and a 1× moon; this
slice preserves that distinction rather than resizing both. Standalone Sun/
Moon controllers, multiple bodies, per-body colors and eclipses remain pending.
No random size completion is added yet.
`PortDayCycle` persists optional `sun_size`, defaults old profiles to 1×,
validates the supported range and transmits it in catalog protocol 6. Size
is extracted into the sky render state and multiplies only the native sun
transform. Native texture/glow and rendering pipeline remain; no new assets
or buffers are allocated. State resets/defaults prevent size leaking to other
dimensions. Clock sampling, illumination and orbit bearing are unaffected.
The `create_size` op fixture freezes the sun at Zenith with Zero Length and
omits Sky to exercise compatible completion. Diagnostic checks cover all
25 numeric sizes, presets, older profile defaults, unchanged timing and
catalog round trips. Disposable dedicated-server checks produced sizes
0.5/1/2/0.25/1.625/3 with the same noon angle and sky light; reload, reseed
and full restart retained them. Build passed. Visual size/glow alignment,
unchanged moon, and travel isolation still require the user's client check.
The server stopped cleanly and its temporary world was deleted. Nothing is
committed, pushed or published without an explicit request.
## Normal Time shared celestial color
`1.0.1.79-beta.1` ports the root `AgeSkyProfile` behavior that consumes a
pending shared color group at Normal Time and applies it to both paired
bodies. `PortAgeColors` now saves an optional `celestial` RGB value, default
-1 (native/untinted), with catalog protocol 7 for synchronization. Existing
sky/ambient fields and old profiles retain their values. Color accumulation
passes through non-color celestial modifiers, clamps at the target, resets
after consumption, and leaves trailing colors assigned to sky as before.
Extraction copies the saved tint into `SkyRenderState`. A narrowly scoped
native sun/moon uniform modification multiplies RGB while retaining alpha;
there are no live world reads during drawing, new textures, pipelines or GPU
buffers. Native weather fading, transparent halos, moon phases, stars and
sunrise glow remain unchanged. Time and effective illumination are not tied
to RGB. State reset/defaults prevent cross-dimension tint leakage. Independent
Sun/Moon pages, multiple bodies and per-body colors remain unported.
The `create_celestial_color` fixture checks three separate target groups,
completed-group clamping, modifier passthrough, consumed-group reset, seeded
unnumbered colors, old codec defaults and catalog round trips. Client checks
must cover a frozen Zenith sun, Nadir moon, mixed colors, transparent halos,
restart and return to an untinted dimension. Server probes validate saved
profiles and attributes, not rendered output. Build passed; disposable-server
fixtures retained separate sky/ambient/body colors through reload, reseed and
restart, including zero/black colors and untouched native defaults. Sampled
time/light remained unchanged. The server stopped cleanly and its temporary
world was deleted. No commit/push/publication is performed without an explicit
request.
## Standalone Sun and Moon controllers
`1.0.1.80-beta.1` extends the existing cycle profile with optional `body_mode`
(paired=0, Sun=1, Moon=2); old profiles default to the paired renderer.
Catalog protocol 8 includes this field. One celestial controller is accepted
per book, with existing Length/Phase/Direction/Angle/Size and shared Color
groups. Multiple controllers and dangling/duplicate modifiers retain the
interim strict rejection rather than losing written pages.
Standalone bodies use a linear angular orbit as in root `AgeSkyProfile.Body`.
Both native body-angle attributes point at that orbit; render-state mode
suppresses the absent counterpart. The selected Moon consumes Size itself;
Normal Time retains its original sun-only sizing. Moon-only sunrise glow is
suppressed before any horizon pose is pushed. Shared RGB/alpha handling and
native buffers/pipelines are reused, with extraction/reset defaults protecting
other dimensions. Missing Sky completion uses Overworld, as before. Explicit
Nether/End/Static still does not draw bodies in this native-renderer slice.
The gameplay skylight attribute follows root `lightAt` and
`LevelSkyBrightnessMixin`: positive cosine altitude, 0.18 for a moon, weather
attenuation, then the 11-level sky-darkening range. It does not infer light
from color or size, and does not bypass Bright/Dark or no-skylight terrain.
Native background/star/moon-phase schedules remain, rather than claiming a
full custom sky port. Seeded default phase/bearing completion, multiple
independent bodies and eclipses remain future work.
The op `create_body` fixture checks all named phases for both bodies, light
weights, numeric size, reverse motion, order rejection, old-profile defaults,
compatible missing Sky and catalog synchronization. Actual body visibility,
moon size, glow transparency and travel isolation require manual client
validation. Build and disposable-server probes passed: Zenith sun/moon
skylight was 15/6, Nadir and horizon were 4; named phase angles were correct.
The paired fixture retained its opposite moon and native lighting. Reload,
reseed and full restart preserved body mode, color, size, bearing and phase.
The test server stopped and its temporary world was deleted. No commit/push/
publication is performed without an explicit request.
## Multiple independent authored celestials
`1.0.1.81-beta.1` adds an optional immutable `PortCelestialBody` list to the
cycle profile and catalog protocol 9. Existing profiles default to an empty
list and use their validated native paired/single path. Books with multiple
controllers compile ordered modifier groups into independent body orbits;
Normal Time expands into opposite-phase sun/moon entries. Colors are consumed
at each controller, with original page indices retained for seeded amounts.
Uncolored bodies reset to native white rather than inheriting the previous
body's tint. Size/phase/length/bearing/direction also reset per group.
The profile constructor and authoring gate enforce the root ten-sun/ten-moon
limit, with Normal Time counting toward both. Duplicate modifiers within a
group and dangling modifiers remain strict errors until grammar recovery is
ported. The first controller continues to govern the shared day timeline and
native background/star/moon-phase schedules. Positive-altitude sunlight sums
to at most 1; only if no sunlight contributes is summed 0.18-weight moonlight
used. Weather and Bright/Dark remain separate. No eclipse attenuation is
included yet.
Extraction resolves body angles into immutable presentation snapshots. The
native body pass is replaced only for a nonempty multi-body list: draw suns
first, then moons with their own color, size and bearing, then native stars
once. Native buffers, pipelines and alpha are reused. Temporary renderer
parameters and pose transforms restore in finally blocks; no world lookup is
performed during drawing. Explicit Nether/End/Static rendering remains a
separate limitation. Eclipse disc occlusion, corona and sky/light attenuation
will be the following slice, not a claim of this implementation.
`create_celestials` checks independent motion/color/size, modifier reset, Normal
Time expansion, ten-pair acceptance/overflow rejection, profile codecs and
catalog round trips. Manual checks cover body placement/alpha, multiple
controllers, restart and ordinary-dimension isolation. Build passed, as did
disposable-server profile/catalog checks, combined-light invariants, reload,
reseed and full restart. Single-body, paired and tinted fixtures retained
their earlier behavior. The test server stopped and its temporary world was
deleted. No commit/push/release is performed without explicit instruction.
## Eclipse effects
`1.0.1.82-beta.1` adapts root `AgeSkyProfile.eclipseFor`, `eclipseAt` and
`lightAt`, plus `RivencraftSkyEffects.drawBody`. The dot-product separation
of normalized orbit directions is compared with the sum of quarter-disc
angular radii; each body takes the strongest opposite-kind contact. This is
root's radial proximity formula, not a new physical disc-area model. Bearing,
phase, size, motion and direction all affect contact. Same-kind and isolated
bodies have no eclipse; only an above-horizon sun contributes global shading.
Sunlight is multiplied by `1 - 0.85 * overlap` before the existing light
aggregation and weather handling. Extraction shades sky RGB by
`1 - 0.65 * strongestVisibleSolarOverlap`. Moon RGB scales by `1 - overlap`;
sun RGB moves toward white by `pow(overlap, 8) * 0.8`. Values are derived from
saved profiles, requiring neither a new saved schema nor packet fields.
Existing multi-body Ages gain the effects on update; single/paired native
paths stay unchanged. Overlap calculations are bounded by the 20-body limit,
and extracted presentation values are reused without live-world drawing reads.
Native transparent glows draw before each body's central ordinary-alpha disc.
A registered pipeline cloned from native Celestial uses conventional alpha
blending; cached center-cropped atlas meshes retain native UV orientation.
An eclipsed moon uses the full-moon core to avoid transparent phase pixels
exposing the sun (root always drew that full-moon center). Weather alpha is
retained. The helper drops meshes on atlas-generation change and closes them
with the renderer. There is no generated art or per-frame mesh allocation.
Explicit Nether/End/Static body rendering remains outside this slice.
`create_eclipse` supplies aligned, partial, clear, below-horizon and moving
fixtures; it checks overlap/color/light constants, same-kind exclusion and
motion out of contact. The multi-body op fixture is renamed
`create_celestials` to avoid merging with the unrelated existing terrain
`create_multi` command. Manual checks must confirm disc opacity, halo,
corona/sky darkening, resource reload and travel isolation. Build passed.
Disposable-server fixtures passed with overlap 1/0.293/0 for aligned/partial/
clear cases and no global shading for below-horizon alignment. Aligned
sunlight was 0.15, clear sunlight 1; sampled skylight was 6/12/15 for aligned/
partial/clear. Moving contact ended as expected. Reload, reseed, catalog
round trips and full restart retained profiles and derived light behavior;
earlier standalone/paired fixtures remained unchanged. The test server stopped
and its temporary world was deleted. No commit/push/publication is performed
without an explicit request.
## Authored moon sprite correction
`1.0.1.83-beta.1` removes the mixed native-phase/full-core adaptation introduced
with the opaque eclipse pass. Standalone and multi-body authored moons now
draw full-moon glow and center consistently, matching root's custom renderer,
which always samples the first (full-moon) atlas cell. Under ordinary alpha,
native dark phase pixels can produce black opaque centers; the old overlay
glow had made those dark pixels effectively invisible. The ordinary native
Normal Time pair retains its calendar phases. No eclipse math, saved profile,
catalog protocol or world data changes are needed.
The user's `celest` Age was read without modification. Its body colors are
all -1 (native white), not corrupted black values. Its first Moon and second
Sun both have period 1, phase 0, origin 0, clockwise direction and native
bearing -1; they remain exactly coincident. That moon's full eclipse and its
occlusion of the sun are expected under the newly added root overlap rules,
independent of the phase-sprite correction. Do not silently alter player-authored
orbits to conceal the intentional alignment. Manual checks cover nonaligned
moons, the known permanent eclipse, Native Normal Time, resource reload and
cross-dimension isolation. No user save was modified, and nothing is committed,
pushed or published without explicit instruction.
## Celestials over explicit non-Overworld skies
`1.0.1.84-beta.1` removes the presentation exclusion that hid authored bodies
over Nether/End/Static. Root `RivencraftSkyEffects` draws its body list after
any chosen background. The native 26.3 paths instead returned after End or
skipped a NONE sky entirely. An extracted overlay-mode flag now schedules an
authored body layer without changing the actual dimension type or gameplay.
Single Sun/Moon and Normal Time profiles expand into temporary presentation
bodies on these backgrounds; saved profiles are not rewritten. Existing
Overworld single/paired/multi-body paths stay unchanged.
End uses a RETURN hook that includes the native early return, after its pass
is closed. Static closes its own background pass before drawing the overlay.
Fog-only Nether presentation schedules an extracted END sky pass, suppresses
its End background/flash drawing, and retains the fog clear color. Overlay
passes load existing targets without clearing, reuse native body resources
and suppress additional stars/horizon glow on non-Overworld backgrounds.
Weather alpha is extracted even when the native NONE/END branch omits it.
All presentation flags reset when the render state is reused.
Eclipse shading modulates End/Static background tint; Nether-style fog color
uses the same root shade factor through an environment attribute layer.
Native untinted fog and authored sky colors are both supported; other
backgrounds retain their existing fog behavior. Body lighting and eclipse
geometry do not depend on style. Missing Sky selection still chooses
Overworld for authored celestials. No schema/protocol changes or new assets
are required. The eclipse fixture accepts an optional explicit Sky; server
checks cover saved choices, fog/light behavior and persistence, while visual
layering, no duplication, resource reload and travel isolation require manual
client checks. Build and disposable-server checks passed for all four sky
styles: aligned eclipse skylight stayed 6, clear stayed 15, and Nether fog
scaled by 0.35 only during overlap. No-celestial and tinted-Nether fixtures
retained their expected colors. Saved profiles, style, light and fog survived
reload/reseed and full restart. The test server stopped and its temporary
world was deleted. No commit/push/publication is performed without explicit
request.
## Bare celestial seeded randomization
`1.0.1.85-beta.1` adds per-controller randomization specifically for bare
Sun/Moon groups, as requested for easier testing. This deliberately uses the
root **random-Age** ranges rather than its authored compile defaults (which
reuse shared seeded phase/bearing and default size/color). A dedicated stream
mixes Age seed with controller ordinal, independent of unrelated page indices,
terrain/weather/lighting RNG and sky selection. Palette/mixing and 0.75–1.75
size come from `AgeSkyProfile.random`; 0.2–2 periods with 1/7 stopped chance
come from `AgeTraits.select`. Bearing and phase use the port's existing degree/
tick granularity. Direction is random per body. Counts and body-kind limits
still follow explicitly written controller pages.
The compiler recognizes whether a controller has any written celestial
modifier. Colors already consumed by Sky/Ambient do not suppress randomization.
Any written celestial modifier retains the previous authored path as a whole,
not just individual field overrides; partially authored groups do not gain
new random missing fields in this slice. Normal Time and absent controllers
are unchanged. Bare controllers materialize immutable full body profiles,
including a one-body list for standalone cases. Multi-body compilation carries
their colors/orbits without replacing them with native defaults. No new
saved schema, protocol or client renderer code is needed.
Only newly created Ages compile these defaults. Older saved profiles load
unchanged; GUI opening, restart and terrain reseeding do not reroll them.
`create_random_celestials` checks reproducibility, ordinal independence,
unrelated-page stability, 128-seed bounds/pool coverage and unchanged authored/
Normal Time behavior. The regular fixtures still exercise explicit groups.
Manual checks cover visible variation, moving/stopped bodies, mixed authored
groups and restart. Build and disposable-server checks passed, including
single bare bodies, multi-body/128-seed coverage, catalog round trips,
unrelated-page stability, explicit/eclipsed fixtures, reload, terrain reseed
and full restart. Saved random parameters remained unchanged while moving
orbits continued with the clock. The server stopped and its temporary world
was deleted. No commit/push/publication occurs without explicit request.
## Missing celestial branch completion
`1.0.1.86-beta.1` adds creation-only `PortDayCycle.resolve`. Written controllers
delegate to the validated compiler unchanged. If none exist, the root
`AgeSkyProfile.random` draw positions select 0–3 suns and 0–3 moons: consume
the sky-style draw and mixed sky-color draws, then the two counts. Body
settings reuse .85's independent per-controller streams. This matches root's
unrestricted count model, not bit-identical per-body values; the .85 per-body
length/direction independence is retained. Missing sky tint completion and
random-page policy parity are not claimed by this slice.
The shared resolver is used by player book creation and the `create_random`
operator command. Other exact diagnostic fixtures continue using `compile`
or native profiles to isolate their subject. A saved NONE body mode (3)
represents a resolved zero-body sky. Its sun/moon/horizon drawing is suppressed
without switching to Dark lighting or changing the native background/star
timeline. Old missing profiles still decode to NATIVE rather than being
retroactively completed. The mode-domain extension uses catalog protocol 10.
No generation runs or rerolls happen during GUI rendering, load or reseed.
`create_completed_sky` tests 256-seed count bounds and coverage of empty,
sun-only, moon-only and mixed results; reproducibility and unrelated-page
stability; explicit-controller precedence; old defaults; and catalog round
trips. Manual checks cover varied new books, empty skies, explicit-controller
counts, all backgrounds, restart and Overworld isolation. No commit/push/
publication is performed without explicit instruction.
The .86 build and disposable dedicated-server checks passed: four background
fixtures, the seed-14 empty sky, random Age creation, explicit controllers,
catalog round trips, unload/reload, terrain reseeding and full restart. Saved
body parameters survived unchanged. The test server was stopped and its world
deleted; client visual confirmation remains a manual check.
## Random Age sky-color completion
`1.0.1.87-beta.1` uses creation-only `PortAgeColors.resolve` for player books
and `age create_random`. Empty symbol lists choose a sky tint from root
`AgeSkyProfile.random`'s palette and draw order, including its rounded channel
averages. Nonempty symbol lists delegate to the existing compiler unchanged.
This intentionally distinguishes wholly random Ages from authored books with
an omitted sky-color branch, as 1.21.1 does. The existing .85 per-body random
color truncation is preserved by a shared palette helper; celestial count and
body random streams do not change.
Colors are stored in the existing profile and catalog fields. Old native
colors are not retroactively randomized; reload, restart and terrain reseed
do not rerun completion. No protocol update is necessary. The completed-sky
diagnostic checks six root seed/color vectors, codec persistence, authored
precedence (including explicit black) and old-profile defaults. Random-page
blocklist parity remains separate pending work.
Build and disposable dedicated-server checks passed: root vectors and authored
precedence, color attributes/catalog round trips for all four background
styles, explicit sky/ambient colors, unload/reload, reseed and full restart.
Saved random colors stayed unchanged after reseeding and restart. The test
server was stopped and its disposable world deleted. Client rendering is
still a manual check. No commit, push or publication was performed.
## Authored biome branch completion
`1.0.1.88-beta.1` ports the explicit-controller missing-pool behavior from
1.21.1 `AgeBiomeSelection.compile`: Single requires one biome; other nonnative
controllers require two distinct biomes. An entirely omitted pool uses the
seeded 2:1 continuation/stop draw up to the eligible pool size. Authored pools
fill only to the minimum, preserve order and duplicate weights, and never add
an unrequested third biome once the minimum is met. Native still disallows
biome pages. The binder's availability validation accepts incomplete pools;
the server resolves actual registry eligibility before creating the Age.
Player creation now passes the actual Age seed to biome compilation. Exact
older diagnostics retain the registry-only compiler; the new completion
fixture exercises the production seeded path. Cave uses recognized Cave and
Nether biomes. Void does not inject The Void alongside authored biomes and
reports a clear distinct-biome error when completion is impossible. Pools
are stored in existing `PortBiomePlan` fields and never rerolled on restart
or terrain reseed. No protocol change is needed. Broader writing recovery,
structure-driven missing-biome selection and random-page policies remain
separate parity work.
The build and disposable dedicated-server checks passed. The completion
fixture checked every distribution over 32 seeds, partial/full/weighted pools
and codec round trips. Created Standard Single, Flat Tiny, Cave Tiny and Void
Single plans; Cave included the new 26.3 Sulfur Caves biome. An impossible
controller-only Void Tiny pool was refused with the distinct-biome message.
Generator pools survived unload/reload, reseed and full server restart.
The server was stopped and the temporary world deleted. Binder interaction
and in-game biome layouts still require manual validation. No commit, push
or publication was performed.
## Unpaired material completion
`1.0.1.89-beta.1` adapts 1.21.1 `AgeFeatureSelection.implied`. A shared pure
normalizer expands an unpaired material into an internal material/feature
pair, keyed by Age seed, material ID and its original book index. Rock, lake
and terrain-feature compilers all use the same completed view. Original book
pages stay unchanged and no random selection happens at render/load time.
Explicit feature targets suppress completion, including incompatible targets
that must still be rejected by the current strict grammar.
Candidate ordering and terrain restrictions follow root's material-feature
list: Rocks/Floating Islands/Tendrils/Spheres/Spikes/Obelisks for solids and
the three lake types for fluids, filtered by supported terrain. Cave only
permits the two terrain-independent solid features; Void also permits floating
islands; Flat excludes Rocks. No fallback fluid feature exists on Flat, Cave
or Void. This does not add page-free random features, nor remove the existing
per-feature caps or introduce instability recovery. Resulting plans use their
existing save codecs, so no catalog/protocol change is needed.
The operator fixture checks 64 seeds on each terrain: independent consecutive
materials, deterministic/idempotent completion, explicit precedence, candidate
coverage, fluid retention and incompatible-fluid rejection. Persistence and
actual generator plans are inspected with `feature_plan` without generating
chunks. Client binder interaction and feature visibility remain manual checks.
The .89 build and disposable server checks passed: seeded fixture assertions,
Standard Glowstone Spikes, Cave Diamond Spheres, Void Stone Tendrils, Flat
Glowstone Obelisks and Standard Water Deep Lakes. Cave Water was refused.
Feature plans and materials survived unload/reload, terrain reseed and full
restart. The server was stopped and its temporary world deleted. No commit,
push or publication was performed.
## Page-free random material features
`1.0.1.90-beta.1` adapts the material and rare-formation portion of 1.21.1
`AgeFeatureSelection.randomChoices`. A new creation-only selector shares the
production authored plan compilers rather than duplicating generator logic.
It rolls 0–2 unique material feature types, uses root's candidate ordering and
Legacy rank chooser, removes chosen types, and selects full-collision solids
or source fluids from the registered sorted pools. Terrain eligibility uses
the current port validator. The separate seeded Skylands and Star Fissure
rolls and the 1-in-10 Crystal Formations roll follow root's rules.
Player Link-Panel-only creation and `age create_random` share this selector.
Authored books still use their own feature compilers, including implied
materials from .89. Plans are frozen in existing save fields, without extra
book pages or a protocol change. Old Ages keep their original plans.
Random structures, random-page policies and instability are not claimed by
this slice. Material values can be valuable/hazardous, matching the root pool;
the instability port must account for that before stable release.
`create_random_features` checks 64 seeds across all terrain types: seeded
determinism, counts 0/1/2, unique feature types, all nine candidate families,
terrain compatibility, rare-feature coverage, and plan codec round trips.
`feature_plan` treats an absent feature generator as a valid empty result.
Client feature visibility remains a manual check.
The .90 build and disposable server checks passed. The seeded matrix covered
all six terrains and all nine material feature families. Created surface,
Cave, Flat and Void fixtures, including lakes, rare Skylands and a Star
Fissure, and verified the production `create_random` plan. Seed 0 Standard
correctly produced no features; seed 1 produced a single lake. Saved plans
survived unload/reload, reseed and full restart. The server was stopped and
its temporary world deleted. Nothing was committed, pushed or published.
## Page-free random structures
`1.0.1.91-beta.1` ports `AgeStructureSelection.randomChoices`: an independent
seed stream rolls 0–2 unique candidates using Legacy ranks. Terrain and
registry availability are checked, then the selected biome pool must intersect
the structure set's normal biome eligibility. This is deliberately stricter
than authored pages, which retain their existing biome overrides. Native
Flat uses Plains, Native Cave uses the backend's Lush Caves fallback, and
other native noise terrain uses the Overworld LevelStem biome source. A
non-Native plan uses its saved biome IDs. Abandoned Camps are added after
the root candidate list at rank 3. Cave Dungeons remain excluded by current
port support, whereas root permits that combination; it needs a separate
placement validation before enabling it.
The combined random feature resolver preserves .90 material/rare choices,
adds Dungeons separately, and merges structure pages into the saved terrain
feature plan. A new optional `structure_control` field defaults false for
old profiles and is true for new random Ages, even for an empty selection.
The generator applies its existing controlled-set filter when that flag is
true. This prevents zero choices from accidentally retaining all vanilla
controlled sets. Other native structure families still use their normal
biome gate. Existing authored/old plans are not rewritten, and no catalog
protocol change is needed.
The operator fixture checks seeded counts/uniqueness, all terrains, fixed
Plains/End/Nether biome pools, native defaults, biome eligibility, the empty
controlled-set gate, explicit Village precedence, merge/codec persistence,
and old-profile defaults. Actual placement remains an in-game check.
The .91 build and disposable server checks passed. Fixtures exercised Plains,
Native Flat, Nether-biome Cave, End-biome surface and empty Void selection,
plus the production random-Age command. Village, Fortress and Dungeon plans,
and an intentionally empty controlled plan, survived unload/reload, reseed
and full restart. Namespaced biome arguments were checked. The server was
stopped and its temporary world deleted. No commit, push or publication was
performed; generated structure placement remains a manual client check.
## Cave Dungeon parity
`1.0.1.92-beta.1` closes the Cave Dungeon terrain exclusion documented in .91.
Root `AgeStructureSelection.error` permits Dungeons on noise terrain, which
includes Cave. The 26.3 feature and placement implementation were already in
place; the port's shared lake/dungeon Cave rejection blocked authoring and,
through the availability check, random selection. Splitting that validation
permits Cave Dungeons without allowing Cave lakes or Flat/Void Dungeons.
The two targets' `worldgen/placed_feature/dungeons.json` files compare exactly:
vanilla monster_room, count 8, in-square and full-height uniform placement
using above-bottom/below-top anchors. No legacy Y=0 assumption is introduced.
Vanilla's solid floor/ceiling and opening-count requirements still determine
successful placement. The 32-page cap and per-occurrence deterministic seed
remain unchanged. New random Cave Ages now consider Dungeons automatically;
old frozen plans are not changed.
The extended `create_dungeons` fixture checks Cave stacking/cap and the
remaining lake/Flat/Void restrictions. The random-structure matrix now requires
Cave Dungeon coverage. `dungeons_probe` accepts an optional 1–4 chunk-side
bound for manual tests; it is not run automatically, avoiding a large sync
chunk-generation scan. Actual dungeon placement is handed to the client check.
The .92 build and disposable server checks passed: Cave and surface authored
fixtures, 32-page stacking/overflow, retained lake and Flat/Void rejection,
and random-structure coverage including a Nether Cave Dungeon selection.
Dungeon counts survived unload/reload and full restart; frozen random plans
survived reseed. Placement JSON matched the 1.21.1 file byte-for-byte. The
server was stopped and its temporary world deleted. No commit, push or
publication was performed. No dungeon chunk scan was run automatically.
## Biome-specific Nether and End materials
`1.0.1.93-beta.1` ports root `AgeDimensionService.withBiomeMaterialRules`.
The backend was using `caves.materialRule()` unchanged, which selects
`minecraft:overworld_caves` and can apply Overworld grass to Nether biomes.
The new noise-settings wrapper sequences the five vanilla End biomes' registered
End rule, then the five vanilla Nether biomes' registered Nether rule, then
the original terrain rule. This fixes Cave Nether coverings and the equivalent
End/Nether mismatch in authored Standard, Amplified and Island noise Ages.
It uses the active rule registry rather than copying vanilla material tables.
All non-material settings are preserved. Dry Cave's AIR default fluid, empty
aquifer config and minimum-relative sea level remain intact. Native Nether
surface rules can still place their own lava patches; this does not restore
flooded Cave aquifers. Flat/Void layer materials and custom feature materials
are not rewritten. Old saved Ages pick up the rule when reloaded, but only
newly generated chunks change; no generated blocks are retroactively edited.
No profile field or network protocol change is required.
The creation fixture verifies unchanged geometry/router/default blocks and
fluids, aquifers and sea level for four noise presets, and round-trips the
composed material rule with registry-aware codecs. `material_probe` limits
generation to one terrain-stage chunk and reports actual block counts.
Build, registry-aware rule codec tests and disposable server terrain checks
passed. All five Nether Cave fixtures generated their native material families
without grass/dirt: Nylium, Soul Sand/Soil, Basalt/Blackstone or Netherrack.
Standard The End and Island End Highlands generated End Stone; Lush Cave's
original Overworld materials remained present. Reload retained the rules, and
fresh chunks after full restart again used Nylium/End Stone. No full feature
or entity chunk scans were run. The server was stopped and temporary world
deleted. Nothing was committed, pushed or published.
## Structure-aware biome completion
`1.0.1.94-beta.1` adapts root `AgeBiomeSelection.completeStructureBiomes` for
explicit non-Native biome controllers. It reads compatible biome IDs from
the active registered structure sets and shares this lookup with random
structure eligibility, avoiding two different compatibility definitions.
Repeated structure pages produce one requirement; Dungeons are excluded.
Single with no supplied biome chooses from the intersection of all structure
requirements and terrain-eligible biomes. No intersection leaves ordinary
seeded filling intact. An explicit Single biome is never rewritten.
Multi-biome completion adds one seeded compatible biome for each unmet
requirement where a terrain-eligible candidate exists, before ordinary minimum
filling. Root's salts, requirement order and shuffled candidate selection are
preserved. Existing biome order and duplicate weights remain, but a structure
can intentionally extend a pool beyond the usual minimum. Native and the
port's no-controller fallback remain unchanged. Impossible requirements do
not become new writing rejections: authored structure overrides still apply.
No saved format, network protocol or generated chunks are changed.
The completed-biome fixture accepts an optional structure page and checks
32 seeds for compatible Single/Cave Fortress choices, common Village/Stronghold
requirements, explicit End Single precedence, Native behavior, multi-biome
prefix preservation and avoiding unnecessary additions for already-compatible
or repeated structure pages. Existing biome plan codec checks remain in place.
The .94 build and disposable server checks passed. Village Single and Tiny
fixtures included compatible Plains; Cave Fortress Single selected Crimson
Forest. The 32-seed authoring assertions and the preexisting no-structure
completion checks passed. Saved generator pools survived unload/reload,
terrain reseed and full restart. The server was stopped and its temporary
world deleted. No structure-placement chunk scan was needed. Client book
authoring remains a manual check; no commit, push or publication occurred.
## Omitted biome-controller completion
`1.0.1.95-beta.1` ports the no-controller branch of root `AgeBiomeSelection`
and the first `AgeTraits.select` draw. The rank table and seed stream are
shared with `PortRandomAgeSelection` rather than duplicated. The production
seeded biome compiler uses that default when there is no explicit controller;
the registry-only diagnostic overload retains its exact older defaults.
Explicit controllers are unchanged. Native rolls with authored biomes, or
Single rolls with more than one biome page, fall back by authored count to
Single/Tiled/Medium. Other multi-biome rolls retain their distribution and
ordinary minimum-only filling, plus .94's structure requirements.
Void's omitted controller remains Single for empty pools and count-based
for supplied biome pages. Cave's omitted Native roll follows the port's
existing page-free seeded Single workaround; a native multi-cave source is
still not implemented. Explicit Native is not silently converted. No other
terrain, weather, lighting, color or body seed stream changes. Saved plans
remain frozen through restart and terrain reseed; old Ages are not rewritten.
The completed-biome diagnostic accepts `auto` and checks 128 seeds for all
nine distribution results, independence from unrelated weather pages,
authored prefix preservation, one/two-biome fallbacks, Void behavior and
structure-aware completion. Existing explicit-controller checks still run.
The .95 build and disposable-server checks passed. The expanded 128-seed
matrix covered all distributions, authored one/two-biome rules and Cave pools.
Created automatic Standard, Cave, Void and Cave Fortress fixtures, plus the
unchanged full-random command and explicit Single/Native Cave controls.
Generator pools survived unload/reload, reseed and full restart. A second seed
produced Small regions with three biomes, while explicit Native Cave retained
its Lush Caves source. No chunk-generation scan was needed. The server was
stopped and its temporary world deleted. Client authoring remains a manual
check; nothing was committed, pushed or published.
## Omitted terrain completion
`1.0.1.96-beta.1` adapts root `AgeRuntimeProfiles.selectForWriting`. A partly
authored book without terrain starts with the shared ranked terrain draw;
if unsupported, compatible profiles in stable ID order are indexed using
`floorMod(Long.hashCode(seed), count)`. Explicit terrain is never substituted.
Unlike root's feature-only candidate test, the port additionally preflights
registry-backed biome restrictions to avoid selecting an unloadable Cave
combination for supplied surface biomes. This is a deliberate compatibility
guard while the broader writing/instability recovery remains unported.
Binder availability checks now consider whether any supported terrain can
host an omitted-terrain book instead of assuming Standard. The server resolves
the actual terrain and biome plan once, then passes the resolved internal page
view to material/feature compilers. The inferred terrain is appended internally,
not inserted before original pages or written back to the book. Original
indices and ordered modifiers remain intact. Environment controllers use the
selected terrain, while sky colors and celestials still compile from original
pages. Page-free random books retain their original path and seed streams.
The chosen terrain and generator plans use existing saved fields, so no
network protocol change or retroactive terrain reroll is introduced.
The fixture checks 64 seeds for terrain coverage, deterministic selection,
original page prefixes, Cave-only Fortress support, implied-fluid constraints,
surface-biome compatibility, explicit terrain precedence and Binder
availability. Generator placement still uses the previously ported routines.
The .96 build and disposable server checks passed. The 64-seed assertions
covered all six terrains, deterministic fallback, page-prefix preservation,
explicit Flat, surface-biome protection and Cave-only Fortress availability.
Created Sky-only, Fortress-only, Water-only, Plains-only, explicit Flat and
full-random fixtures. A Water page retained Water as its implied lake fluid;
Fortress-only selected Cave with eligible biomes. Plans survived unload/reload,
reseed and full restart. The server was stopped and its temporary world
deleted. No chunk scan was needed; client Binder checks remain manual.
Nothing was committed, pushed or published.
## Native Cave regions
`1.0.1.97-beta.1` ports root `AgeBiomeSelection`'s full Native Cave pool and
`AgeDimensionService.createBiomeSource`'s Native-to-Tiny mapping. New Native
Cave plans retain distribution NATIVE with a saved recognized Cave/Nether
list, and the backend uses `PortScaledBiomeSource` at scale 0 (or Fixed for
a one-biome pool). Explicit Native biome pages remain prohibited. Both authored
and page-free/omitted-controller paths use the same eligibility query; the
temporary Native-to-Single Cave conversions are removed.
Native pool data is permitted only for Cave terrain at backend validation.
Other Native terrain sources are unchanged. Empty older Native Cave records
still load the old Lush source; old Single choices also remain frozen. New
Native pools are saved through the existing biome-plan codec without a new
network protocol, but earlier betas cannot decode populated Native pools, so
downgrading those saves is not supported. The current pool is passed to random
structure eligibility rather than incorrectly assuming Lush Caves.
The fixture verifies registry-derived pool ordering, old empty Native codec
defaults, the actual generator source, deterministic Tiny-region equivalence,
horizontal region variation and sampled pool membership without loading
chunks. The omitted-controller matrix now expects Native Cave to remain
Native with its full pool. This does not implement modded surface rules.
The .97 build and disposable-server checks passed: explicit and omitted
Native Cave, the full-random Native Cave path (seed 114), Native + Fortresses,
explicit Single and the legacy Lush-only control. The vanilla registry pool
contained nine biomes, including Sulfur Caves and all five Nether biomes;
the actual Native source passed Tiny-equivalence and sample-membership checks.
Pools survived unload/reload, reseed and full restart. The server was stopped
and its temporary world deleted. No chunk scan was needed. Client exploration
remains a manual check; nothing was committed, pushed or published.
## Verification of this first slice
The 1.21.1 `compileJava` and `build` tasks passed offline after the backend
extraction. The GameTest server ran 93 tests; 92 passed, while
`twoblockdeskdropsonce` failed because breaking either desk half dropped zero
desks instead of one. That desk failure is outside the dimension-backend edit
and must be resolved or rechecked before a release. The 1.21.1 `build` task
passed again after the 26.3 registry slice.
On 2026-11-01, the default 1.21.1 GameTest server was rerun and all 93
required tests passed, including the desk test. Issue #97 was then closed;
remaining 26.3 parity work stays under #98–#104.