Files
rivencraft/docs/MINECRAFT_26_3_PORT.md
T
2026-11-02 15:49:58 -05:00

68 KiB
Raw Blame History

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

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, NeoForge 26.3 Maven metadata, NeoForge Java 25 setting, and NeoForge migration primers 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 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 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 Optional recipe/page guides Yes Port and test its plugin against the 26.3 API.
TerraBlender Optional modded biome support Yes Port and verify biome discovery and Age generation.
Serene Seasons and GlitchCore Optional seasons Yes Port and repeat the per-Age seasonal matrix.
Biomes O' Plenty Optional TerraBlender test addon Yes Test modded biome registration and decoration.
Ruins (Structure Spawning System) Optional authored ruins integration Yes Port and verify its generation hooks.
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 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 and its AR fork have no published 26.3 branch or artifact; DimLib is Fabric-only and stops at 1.21.1; and DimensionsCore 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.

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.

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.