diff --git a/README.md b/README.md index 1207110..41ef6ee 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ right-clicking with an empty hand. Sneak-right-click with an empty hand to take the book back and restore the vanilla lectern. Breaking a Book Stand drops both the stored book and a vanilla lectern. -Bound Linking Books request a server-validated 9-by-64-by-9 snapshot around -their destination. The book renders a fixed 9-by-7-by-9 window centered on the -link point as a rotating Ponder scene on the left page, backed by the +Bound Linking Books request a server-validated 18-by-18-by-18 snapshot around +their destination. The book keeps its target-centered close-up framing as a +rotating Ponder scene on the left page, backed by the destination biome's sky color. The snapshot is visual only; the server independently validates every link. diff --git a/docs/PORTING.md b/docs/PORTING.md index d853656..3f8d5b7 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -138,6 +138,10 @@ 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. + The preview code is separated behind a renderer interface and uses an isolated Ponder level populated from server-authoritative destination snapshots. diff --git a/gradle.properties b/gradle.properties index fda5ed8..9190884 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ mod_name=Rivencraft # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=LGPL-3.0-or-later # The mod version. See https://semver.org/ -mod_version=0.1.19 +mod_version=0.1.20 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java b/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java index f4c25a4..17e482e 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java +++ b/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java @@ -43,7 +43,12 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie public PonderDestinationPreviewRenderer() { Minecraft minecraft = Minecraft.getInstance(); previewLevel = new PonderLevel(BlockPos.ZERO, minecraft.level); - snapshotSelection = SelectionImpl.of(new BoundingBox(0, 0, 0, 8, 63, 8)); + snapshotSelection = SelectionImpl.of(new BoundingBox( + 0, 0, 0, + LinkPreviewPayload.SNAPSHOT_SIZE - 1, + LinkPreviewPayload.SNAPSHOT_SIZE - 1, + LinkPreviewPayload.SNAPSHOT_SIZE - 1 + )); // Keep the target-centered 9×7×9 camera framing below, but give Ponder // the entire snapshot so terrain above and below that window is still // part of the rotating scene. @@ -109,7 +114,9 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie poseStack.mulPose(Axis.YP.rotationDegrees((ticks + partialTick) * 0.6F)); UIRenderHelper.flipForGuiRender(poseStack); poseStack.scale(7.0F, 7.0F, 7.0F); - poseStack.translate(-4.5F, -31.5F, -4.5F); + // The target moves from (4, 32, 4) to (9, 9, 9) in the cubic + // snapshot, so retain its existing camera position relative to it. + poseStack.translate(-9.5F, -8.5F, -9.5F); SuperRenderTypeBuffer buffer = DefaultSuperRenderTypeBuffer.getInstance(); section.renderFirst(previewLevel, buffer, graphics, partialTick); diff --git a/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java b/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java index 43497de..7c21b6a 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java +++ b/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java @@ -12,8 +12,10 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; public record LinkPreviewPayload(int skyColor, List blocks) implements CustomPacketPayload { - /** A square footprint keeps every side visible during an orbit, with a vertical snapshot cache. */ - private static final int MAX_BLOCKS = 9 * 64 * 9; + /** Each axis of the destination volume captured for the book preview. */ + public static final int SNAPSHOT_SIZE = 18; + /** A square footprint keeps every side visible during an orbit. */ + private static final int MAX_BLOCKS = SNAPSHOT_SIZE * SNAPSHOT_SIZE * SNAPSHOT_SIZE; public static final Type TYPE = new Type<>( ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "link_preview") ); diff --git a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java index f5a2c11..2a9c162 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java +++ b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java @@ -114,12 +114,17 @@ public final class ModNetworking { BlockPos origin = target.location().pos(); List blocks = new ArrayList<>(); - // The square footprint survives every angle of the orbit. Retain a - // 64-block vertical slice, while the renderer shows its 7-block window. - for (BlockPos pos : BlockPos.betweenClosed(origin.offset(-4, -32, -4), origin.offset(4, 31, 4))) { + // The cubic footprint survives every angle of the orbit. The target is + // kept at the preview camera's current center point. + int negativeRadius = LinkPreviewPayload.SNAPSHOT_SIZE / 2; + int positiveRadius = negativeRadius - 1; + for (BlockPos pos : BlockPos.betweenClosed( + origin.offset(-negativeRadius, -negativeRadius, -negativeRadius), + origin.offset(positiveRadius, positiveRadius, positiveRadius))) { var state = level.getBlockState(pos); if (!state.isAir()) { - blocks.add(new LinkPreviewPayload.SnapshotBlock(pos.subtract(origin).offset(4, 32, 4), state)); + blocks.add(new LinkPreviewPayload.SnapshotBlock( + pos.subtract(origin).offset(negativeRadius, negativeRadius, negativeRadius), state)); } } int skyColor = level.getBiome(origin).value().getSkyColor();