Files
rivencraft/docs/PORTING.md
T
dnorberg 73dec80ae6
Build / build (push) Canceled after 0s
Persist random Age traits
2026-09-22 16:11:45 -04:00

360 lines
19 KiB
Markdown
Raw 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.
# Porting plan
Mystcraft Legacy contains more than 700 Java source files and targets Minecraft
1.12.2. The Minecraft world-generation, dimension, registry, networking, and
rendering APIs have all changed substantially since that release. The port is
split into independently testable milestones.
## Milestones
1. **Bootstrap** — NeoForge 1.21.1 build, mod metadata, item registration, and
CI. **Complete.**
2. **Books and linking** — descriptive/linking book data components, lectern-like
interaction, safe teleportation, and return links. **Complete.**
3. **Ages** — dimension definitions backed by data packs, deterministic seeds,
lifecycle management, and persistence. Make the legacy-style animated
linking panel the built-in destination preview. Provide optional
Create/Ponder and Immersive Portals integrations as alternative rotating-
snapshot renderers. The configurable preview modes are `AUTO`,
`IMMERSIVE_PORTALS`, `PONDER`, and `LEGACY`; `AUTO` prefers Immersive
Portals when it is installed, then Create/Ponder, and finally the built-in
legacy animation.
4. **Writing system** — pages, symbols, notebooks, desks, and book assembly.
5. **Age grammar** — translate symbol combinations into modern biome, noise,
dimension-type, and worldgen configuration. Optional integrations with
TerraBlender provide composable biome-region generation, while Serene
Seasons and Ecliptic Seasons allow Age generation to participate in their
respective seasonal systems. None of these integrations are required for
Rivencraft's core world generation.
6. **Instability** — deterministic validation and effects with server-safe
behavior.
7. **Structures and polish** — libraries, crystals, portals, recipes, models,
sounds, advancements, compatibility, and migration tests.
## Provenance rules
- New code uses the `net.dnorberg.rivencraft` package.
- Adapted Mystcraft code must retain its upstream copyright notice and be
tracked in this document or a nearby source comment.
- Do not copy generated, binary, or third-party dependency content from the
legacy repository.
- Preserve LGPL-3.0-or-later compatibility for the complete distributed mod.
## First vertical slice
The first functional target is: create a Descriptive Book, bind it to one
server-managed Age definition, travel to that Age, and use a Linking Book to
return. This exercises persistence, networking, dimensions, and safety before
the symbol grammar is introduced.
### Milestone 2 progress
- [x] Persistent, network-synchronized link-target data component.
- [x] Linking Book binding with dimension, block position, yaw, and pitch.
- [x] Server-authoritative cross-dimension travel with world-border, collision,
and fluid checks.
- [x] Nearby landing search and clear failure messages.
- [x] Descriptive Book identity and Age reference components.
- [x] Temporary vanilla-dimension Descriptive Book travel with return-link creation.
- [x] Lectern-to-Book-Stand conversion, displayed book, activation, removal,
persistence, and drops.
- [x] Book-screen foundation with server-authoritative naming, binding, and
explicit link activation.
- [x] Ponder dependency and isolated destination-preview level boundary.
- [x] Server-provided destination snapshots rendered as rotating Ponder scenes.
- [x] Book Stand floating names synchronized from the stored book stack.
- [x] Open the stored book screen from a Book Stand with server-validated linking.
- [x] Automated in-game tests for binding, persistence, and travel.
The temporary shapeless Linking Book recipe makes the linking subsystem easy
to test. It can move into the writing/bookbinder progression when that system
is implemented.
Age references use UUIDs rather than dimension keys. Milestone 3 will own the
mapping from that stable identity to server data and a runtime dimension. This
keeps saved books valid if an Age is migrated or regenerated.
Vanilla lecterns accept extensible item tags when inserting books, but their
block entity still validates only vanilla writable and written books. To avoid
an invalid lectern state, inserting a Rivencraft book converts the lectern into
a visually compatible Rivencraft Book Stand. Removing the book converts it
back.
Mystcraft Legacy did not impose an item cooldown when linking. Rivencraft's
initial cooldown used Minecraft's item-type cooldown system, which delayed all
Linking Book stacks at once. Version 0.1.3 removes that cooldown to match the
legacy behavior.
Version 0.1.4 moves Linking Book binding and travel behind a book screen. The
client requests an action, while the server revalidates the held book and owns
all changes to its destination and custom name. Descriptive Book Age references
now carry a display name alongside their stable UUID, with backward-compatible
decoding for existing UUID-only data.
Version 0.1.5 ensures the book interaction listener opens screens only for the
logical-client event. This avoids calling the render system from the integrated
server thread when a book is used in singleplayer.
Version 0.1.6 gives the Linking Book screen an open-book layout inspired by the
legacy interface. The destination preview occupies the left page, the book name
and destination details occupy the right page, and the preview itself is the
link action; the separate Link and Done buttons have been removed.
Version 0.1.7 suppresses Minecraft's default full-screen menu blur for the
Linking Book screen. The open-book texture supplies the GUI background while
the world remains sharp behind it.
Version 0.1.8 renders all Linking Book destination details in the same dark ink
color as the book name for consistent contrast against the parchment.
Version 0.1.9 synchronizes the Book Stand's stored stack to clients and renders
its display name as a camera-facing label above the book.
Version 0.1.10 corrects the nameplate transform and matches Minecraft's normal
plus see-through text passes so angled stand geometry cannot hide the label.
Version 0.1.11 opens the stored book interface when a Book Stand is used with
an empty hand. Linking Books travel through the preview panel, and the server
revalidates the stand position, interaction distance, stored item, and target.
Version 0.1.12 replaces the Linking Book screen's convenience text draws with
explicit no-shadow rendering for clearer dark ink on the parchment texture.
Version 0.1.13 requests a bounded, server-validated 9-by-7-by-9 block snapshot
from the held book or nearby Book Stand and renders it as a clipped, rotating
Ponder world section on the Linking Book's left page.
Version 0.1.14 expands the destination snapshot to 9-by-7-by-17 blocks along
the Z axis, rescales the rotating scene to expose that depth, and colors the
panel background with the destination biome's sky color.
Version 0.1.15 adds three dedicated-server GameTests covering Linking Book
component serialization, successful safe travel with restored orientation, and
rejection of fully blocked destinations. The test suite uses a minimal bundled
structure template and runs with `./gradlew runGameTestServer`.
Version 0.1.16 makes destination previews sample a centered 17-by-7-by-17
volume. The Ponder scene uses a scale that keeps its full horizontal diagonal
inside the panel, so the complete snapshot remains available during its orbit.
Version 0.1.17 changes destination previews to a 9-by-128-by-9 volume: a
square horizontal footprint with a vertical slice spanning 64 blocks below and
63 blocks above the recorded linking location.
Version 0.1.18 changes the preview cache to 9-by-64-by-9, spanning 32 blocks
below and 31 above the link point. Its camera is centered on a 9-by-7-by-9
window around the link point so the book retains a readable close-up.
Version 0.1.19 renders the complete 9-by-64-by-9 snapshot in that Ponder
scene while retaining the target-centered camera framing.
Version 0.1.20 uses a cubic 18-by-18-by-18 snapshot. The renderer remaps the
link point within that cube so its existing target-centered camera framing is
unchanged.
Version 0.1.21 treats air and leaf blocks as passable linking destinations;
links no longer require a solid floor beneath the player.
Version 0.2.0 completes Milestone 2. Until Milestone 3 provides generated Age
dimensions, Descriptive Book UUIDs deterministically resolve to vanilla
dimensions and create a bound Return Link to the source on successful travel.
Version 0.2.1 gives Descriptive Books the same open-parchment layout and
left-page link interaction as Linking Books.
Version 0.2.2 adds the same server-provided Ponder destination preview to
Descriptive Books. If no snapshot is available, the left page shows an
animated linking-panel fallback.
Version 0.2.3 requires Descriptive Book destinations to have a sturdy floor,
while Linking Books continue to permit passable floorless destinations.
Version 0.2.4 expands Descriptive Book arrival validation with an outward,
terrain-aware search for an alternate grounded location near an unsafe target.
Version 0.2.5 uses dimension-appropriate preview skies for vanilla Nether and
End destinations instead of their inherited Overworld biome sky tint.
Version 0.2.6 expands destination snapshots to a 32-by-32-by-32 cube while
keeping the existing target-centered Ponder camera position.
Version 0.2.7 persists each Age's first successful visit and creates its
Return Link only for that initial arrival.
Version 0.2.8 makes Return Link creation a server setting: `ON_CREATION`
(default), `ALWAYS`, or `DISABLED`.
Version 0.2.9.0 begins Milestone 3 with a server-owned, world-persistent Age
registry. Each Age UUID resolves exactly once to an immutable random seed,
generation profile, generation-version marker, canonical name, and creation
time. The temporary vanilla-dimension adapter remains in place until runtime
Age dimensions are introduced by a later release slice.
Version 0.2.10.0 makes page-free Descriptive Books playable. Naming an
unwritten book creates a dedicated, persistent vanilla-like Age through the
Dynamic Dimensions API. Each Age reloads with its server, retains its terrain,
and receives a five-by-five cobblestone platform with cleared arrival headroom.
Version 0.2.10.1 improves Age arrival placement. Non-Nether Ages select the
highest sturdy surface near the origin and fall back to a platform at Y=63 when
no suitable natural footing exists.
Version 0.2.10.2 allows leaf blocks to count as proper natural footing when
selecting the highest arrival surface.
Version 0.2.10.3 scans each candidate column downward from the dimension's top
before choosing footing, preventing cave floors from being selected as the Age
arrival surface. Columns covered by fluid remain ineligible.
Version 0.2.10.4 restores Mystcraft Legacy's standard linking sound for both
Linking and Descriptive Books. Successful travel plays the sound at its source
and destination with the legacy volume and pitch variation.
Version 0.2.10.5 derives each new Age's saved dimension folder from its
player-assigned name. Names are converted to safe lowercase resource paths,
and folder conflicts receive `_2`, `_3`, and later numeric suffixes. Existing
UUID-based dimension folders remain unchanged for save compatibility.
Version 0.2.10.6 prevents a Descriptive Book from reopening while its Age is
being generated. Screen opening now waits for the server's current copy of the
held or displayed book, so a delayed interaction opens only the completed Age.
Version 0.2.11.0 adds a dependency-free, legacy-style portal bloom as the
fallback destination preview for Linking and Descriptive Books. Clients with
Create installed retain the rotating Ponder snapshot; clients without Create
use the destination-tinted animation with the original effect's paired noisy
spirals.
Version 0.2.11.1 makes Create genuinely optional. Ponder remains a compile-time
API for the Create integration, while generated mod metadata no longer requires
Ponder and marks Create as an optional client dependency.
Version 0.2.12.0 introduces the first legacy-inspired Age generator profiles.
New page-free Ages deterministically select and persist Standard, Amplified,
Island, Cave, Flat, or Void base terrain. Existing `random_vanilla` Ages remain
mapped to their original Overworld generator for save compatibility. Terrain
alterations such as Skylands, Tendrils, Spheres, and Floating Islands remain
future Age-grammar work layered above these base profiles.
Version 0.2.12.1 displays the persisted terrain generator on the description
side of written Descriptive Books. Newly written books receive the synchronized
profile immediately, while older books are backfilled from the server-owned Age
registry when opened.
Version 0.2.13.0 constructs Standard, Amplified, Cave, and Island terrain from
Minecraft's worldgen registries instead of borrowing generator instances from
the vanilla levels. Noise settings and biome-source parameter lists therefore
honor the server's loaded data packs. Automated coverage also verifies that a
live Age's seed equals its immutable saved definition; Dynamic Dimensions
derives both from the Overworld seed and the Age dimension identifier.
Version 0.2.16.13 gives Cave and Island/Skylands Ages Overworld biomes, sky,
weather, lighting, and day/night behavior while retaining distinct terrain.
Caves remain enclosed. Skylands use Minecraft's uniform floating-island noise
and Overworld-like surfaces without the End's central dragon island.
Version 0.2.16.14 replaces the Explore text control with a compact eye symbol.
Books opened from a Book Stand display the control disabled, preventing
exploration while the book is mounted.
Version 0.2.16.15 restores Immersive Portals chunk loading for snapshots opened
from Book Stands. Snapshot chunk loading is independent from whether the Explore
control is enabled, so mounted books retain live terrain without allowing the
player to enter Explore mode.
Version 0.2.17.0 begins persistent random Age traits. New page-free Ages select
and save a legacy-inspired biome distribution, lighting mode, weather mode, and
celestial period, angle, and phase. The celestial ranges follow Legacy's random
symbol fallbacks: period 0.2–2.0, angle 0–360 degrees, and phase 0–1. Existing
Ages load with normal Legacy defaults instead of being rerolled. This immutable
trait layer is the foundation for applying each choice to modern worldgen.
Version 0.2.14.0 restores the legacy Linking and Descriptive Book artwork for
inventory items and gives each book its matching open-book texture when placed
on a Book Stand. Return Linking Books created inside another Age also retain and
display that Age's saved name instead of exposing its dimension identifier.
Version 0.2.14.1 gives every newly bound Linking Book a friendly destination
label. Standard books and Return Links use saved Age names inside Rivencraft
Ages and the familiar Overworld, The Nether, and The End names in vanilla
dimensions. Existing vanilla links receive the same presentation at display
time without requiring item migration.
Version 0.2.15.0 adds the client-side book-preview mode configuration and the
selection policy for `AUTO`, `IMMERSIVE_PORTALS`, `PONDER`, and `LEGACY`.
`AUTO` uses Ponder when Create is present and otherwise uses the built-in
legacy animation. Explicit optional modes fall back to `LEGACY` when their
renderer is unavailable.
Version 0.2.16.0 implements the optional Immersive Portals GUI renderer. Its
default view orbits the live destination like the Ponder snapshot. The Explore
control switches to a movable remote camera using movement keys and mouse drag;
right-click resets the camera and restores the passive book GUI. A validated
per-player chunk loader exists only while the screen is open and is released
on close. `AUTO` now prefers Immersive Portals, then Ponder, then `LEGACY`.
Version 0.2.16.1 corrects Immersive Portals detection to use its NeoForge mod
ID, `immersive_portals_core`. Rivencraft now also refreshes Immersive Portals'
integer dimension map whenever saved or newly created Ages are loaded, before
their chunks can be synchronized to a player.
Version 0.2.16.2 routes book travel through Immersive Portals' seamless
teleport API when that mod is installed, preserving its client-world registry
during links between Ages and vanilla dimensions. The Explore control is also
positioned fully below the live snapshot window on both book screens.
Version 0.2.16.3 restores the full window viewport immediately after drawing
an Immersive Portals snapshot. Book titles, destination details, and controls
therefore render in their normal page positions instead of being compressed
inside the snapshot rectangle.
Version 0.2.16.4 clears the Immersive Portals GUI framebuffer between remote
world renders, preventing moving camera frames from accumulating into a sky
smear. The framebuffer now follows Immersive Portals' shared-target lifecycle
so a queued end-of-frame render cannot target a texture destroyed on GUI close.
Version 0.2.16.5 expands live-preview chunk loading to Immersive Portals'
reference eight-chunk radius. Rivencraft prepares the central 3x3 destination
chunks and requests an immediate tracking update when the GUI opens, providing
terrain for the first useful snapshot while the remaining chunks stream in.
Version 0.2.16.6 makes Linking and Descriptive Book screens non-pausing. The
integrated server now continues ticking in single-player while a book is open,
allowing live preview chunks to generate and stream into the snapshot.
Version 0.2.16.7 handles configured movement bindings directly in both book
screens while Explore mode is active. Movement, jump, and sneak now move the
remote camera even though Minecraft suspends normal gameplay key states while
a GUI is open.
Version 0.2.16.8 links Explore mode to real player movement in the current
dimension. Entering Explore anchors the source player and destination camera;
walking, jumping, falling, or being moved shifts the snapshot camera by the
same displacement while the book remains open and normal collision still
applies.
The preview code is separated behind a renderer interface and uses an isolated
Ponder level populated from server-authoritative destination snapshots.
## Version policy
Versions follow `x.y.z.b`:
- `x`: major release point.
- `y`: number of completed milestones.
- `z`: release slice within the active milestone.
- `b`: bug-fix and additional-work iteration within that release slice.
Starting a release slice increments `z` and resets `b` to zero. Completing a
milestone increments `y` and resets both `z` and `b` to zero. The first
milestone-2 slice is therefore `0.1.1.0`; a fix on that slice is `0.1.1.1`;
and milestone 2 completion is `0.2.0.0`.
## Milestone 1 acceptance record
- The project builds on a Java 21 JDK with `./gradlew build`.
- Mod identity and dependencies are declared in generated NeoForge metadata.
- Registrations are isolated by registry type and use deferred registration.
- The Descriptive Book loads with a model, name, tooltip, and creative tab.
- CI builds every pushed commit and pull request.