From 5a9a13f35cf897aa4477534625767b063b53ec42 Mon Sep 17 00:00:00 2001 From: Dustin Norberg Date: Mon, 21 Sep 2026 08:20:06 -0400 Subject: [PATCH] Expand and color destination previews --- README.md | 7 ++++--- docs/PORTING.md | 4 ++++ gradle.properties | 2 +- .../preview/PonderDestinationPreviewRenderer.java | 10 ++++++---- .../rivencraft/network/LinkPreviewPayload.java | 8 +++++--- .../net/dnorberg/rivencraft/network/ModNetworking.java | 9 +++++---- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7279fed..319f405 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,10 @@ 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 small, server-validated snapshot around their -destination and render its blocks as a rotating Ponder scene on the left page. -The snapshot is visual only; the server independently validates every link. +Bound Linking Books request a server-validated 9-by-7-by-17 snapshot around +their destination and render its blocks 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. ## Requirements diff --git a/docs/PORTING.md b/docs/PORTING.md index 307c9c3..b64974f 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -114,6 +114,10 @@ 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. + The preview code is separated behind a renderer interface and uses an isolated Ponder level. The first iteration supplies the animated loading boundary; the next iteration will add server-authoritative snapshot transport and populate diff --git a/gradle.properties b/gradle.properties index e0912c5..e462837 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.13 +mod_version=0.1.14 # 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 ad37bfa..5c439c2 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java +++ b/src/main/java/net/dnorberg/rivencraft/client/preview/PonderDestinationPreviewRenderer.java @@ -38,11 +38,12 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie private final PonderSceneElement section; private int ticks; private boolean loaded; + private int backgroundColor = 0xFF080C18; public PonderDestinationPreviewRenderer() { Minecraft minecraft = Minecraft.getInstance(); previewLevel = new PonderLevel(BlockPos.ZERO, minecraft.level); - selection = SelectionImpl.of(new BoundingBox(0, 0, 0, 8, 6, 8)); + selection = SelectionImpl.of(new BoundingBox(0, 0, 0, 8, 6, 16)); section = new WorldSectionElementImpl(selection); } @@ -51,6 +52,7 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie selection.forEach(pos -> previewLevel.setBlock(pos, Blocks.AIR.defaultBlockState(), 2)); payload.blocks().forEach(block -> previewLevel.setBlock(block.pos(), block.state(), 2)); ((net.createmod.ponder.api.element.WorldSectionElement)section).queueRedraw(); + backgroundColor = 0xFF000000 | payload.skyColor() & 0x00FFFFFF; loaded = true; } @@ -62,7 +64,7 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie @Override public void render(GuiGraphics graphics, int left, int top, int width, int height, float partialTick) { - graphics.fill(left, top, left + width, top + height, 0xFF080C18); + graphics.fill(left, top, left + width, top + height, backgroundColor); graphics.renderOutline(left, top, width, height, 0xFF7B6AA8); if (loaded) { @@ -103,8 +105,8 @@ public final class PonderDestinationPreviewRenderer implements DestinationPrevie poseStack.mulPose(Axis.XP.rotationDegrees(-28.0F)); poseStack.mulPose(Axis.YP.rotationDegrees((ticks + partialTick) * 0.6F)); UIRenderHelper.flipForGuiRender(poseStack); - poseStack.scale(10.0F, 10.0F, 10.0F); - poseStack.translate(-4.5F, -1.5F, -4.5F); + poseStack.scale(7.0F, 7.0F, 7.0F); + poseStack.translate(-4.5F, -1.5F, -8.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 ed8eea6..9dcae18 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java +++ b/src/main/java/net/dnorberg/rivencraft/network/LinkPreviewPayload.java @@ -11,13 +11,14 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public record LinkPreviewPayload(List blocks) implements CustomPacketPayload { - private static final int MAX_BLOCKS = 9 * 7 * 9; +public record LinkPreviewPayload(int skyColor, List blocks) implements CustomPacketPayload { + private static final int MAX_BLOCKS = 9 * 7 * 17; public static final Type TYPE = new Type<>( ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "link_preview") ); public static final StreamCodec STREAM_CODEC = StreamCodec.of( (buffer, payload) -> { + buffer.writeInt(payload.skyColor); buffer.writeVarInt(payload.blocks.size()); for (SnapshotBlock block : payload.blocks) { buffer.writeBlockPos(block.pos); @@ -25,6 +26,7 @@ public record LinkPreviewPayload(List blocks) implements CustomPa } }, buffer -> { + int skyColor = buffer.readInt(); int size = buffer.readVarInt(); if (size < 0 || size > MAX_BLOCKS) { throw new IllegalArgumentException("Invalid link preview size: " + size); @@ -33,7 +35,7 @@ public record LinkPreviewPayload(List blocks) implements CustomPa for (int i = 0; i < size; i++) { blocks.add(new SnapshotBlock(buffer.readBlockPos(), Block.stateById(buffer.readVarInt()))); } - return new LinkPreviewPayload(List.copyOf(blocks)); + return new LinkPreviewPayload(skyColor, List.copyOf(blocks)); } ); diff --git a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java index 08d8076..dad735a 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java +++ b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java @@ -30,7 +30,7 @@ public final class ModNetworking { } public static void register(RegisterPayloadHandlersEvent event) { - PayloadRegistrar registrar = event.registrar("2"); + PayloadRegistrar registrar = event.registrar("3"); registrar.playToServer(BindLinkingBookPayload.TYPE, BindLinkingBookPayload.STREAM_CODEC, ModNetworking::bindBook); registrar.playToServer(UseLinkingBookPayload.TYPE, UseLinkingBookPayload.STREAM_CODEC, ModNetworking::useBook); registrar.playToServer(UseBookStandPayload.TYPE, UseBookStandPayload.STREAM_CODEC, ModNetworking::useBookStand); @@ -114,13 +114,14 @@ public final class ModNetworking { BlockPos origin = target.location().pos(); List blocks = new ArrayList<>(); - for (BlockPos pos : BlockPos.betweenClosed(origin.offset(-4, -2, -4), origin.offset(4, 4, 4))) { + for (BlockPos pos : BlockPos.betweenClosed(origin.offset(-4, -2, -8), origin.offset(4, 4, 8))) { var state = level.getBlockState(pos); if (!state.isAir()) { - blocks.add(new LinkPreviewPayload.SnapshotBlock(pos.subtract(origin).offset(4, 2, 4), state)); + blocks.add(new LinkPreviewPayload.SnapshotBlock(pos.subtract(origin).offset(4, 2, 8), state)); } } - PacketDistributor.sendToPlayer(player, new LinkPreviewPayload(List.copyOf(blocks))); + int skyColor = level.getBiome(origin).value().getSkyColor(); + PacketDistributor.sendToPlayer(player, new LinkPreviewPayload(skyColor, List.copyOf(blocks))); } private static InteractionHand hand(boolean offhand) {