Public Access
1 parent
5a9a13f35c
commit
b6f321e6cb
5 files changed
+86
-2
No files matched your search
@@ -34,6 +34,7 @@ bin/
|
|||||||
|
|
||||||
### Minecraft Modding ###
|
### Minecraft Modding ###
|
||||||
run/
|
run/
|
||||||
|
logs/
|
||||||
!**/src/**/run/
|
!**/src/**/run/
|
||||||
**/src/generated/**/.cache/
|
**/src/generated/**/.cache/
|
||||||
repo/
|
repo/
|
||||||
|
|||||||
+6
-1
@@ -54,7 +54,7 @@ the symbol grammar is introduced.
|
|||||||
- [x] Server-provided destination snapshots rendered as rotating Ponder scenes.
|
- [x] Server-provided destination snapshots rendered as rotating Ponder scenes.
|
||||||
- [x] Book Stand floating names synchronized from the stored book stack.
|
- [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] Open the stored book screen from a Book Stand with server-validated linking.
|
||||||
- [ ] Automated in-game tests for binding, persistence, and travel.
|
- [x] Automated in-game tests for binding, persistence, and travel.
|
||||||
|
|
||||||
The temporary shapeless Linking Book recipe makes the linking subsystem easy
|
The temporary shapeless Linking Book recipe makes the linking subsystem easy
|
||||||
to test. It can move into the writing/bookbinder progression when that system
|
to test. It can move into the writing/bookbinder progression when that system
|
||||||
@@ -118,6 +118,11 @@ 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
|
the Z axis, rescales the rotating scene to expose that depth, and colors the
|
||||||
panel background with the destination biome's sky color.
|
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`.
|
||||||
|
|
||||||
The preview code is separated behind a renderer interface and uses an isolated
|
The preview code is separated behind a renderer interface and uses an isolated
|
||||||
Ponder level. The first iteration supplies the animated loading boundary; the
|
Ponder level. The first iteration supplies the animated loading boundary; the
|
||||||
next iteration will add server-authoritative snapshot transport and populate
|
next iteration will add server-authoritative snapshot transport and populate
|
||||||
|
|||||||
+1
-1
@@ -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.
|
# 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
|
mod_license=LGPL-3.0-or-later
|
||||||
# The mod version. See https://semver.org/
|
# The mod version. See https://semver.org/
|
||||||
mod_version=0.1.14
|
mod_version=0.1.15
|
||||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
# 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.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package net.dnorberg.rivencraft.gametest;
|
||||||
|
|
||||||
|
import net.dnorberg.rivencraft.Rivencraft;
|
||||||
|
import net.dnorberg.rivencraft.book.LinkTarget;
|
||||||
|
import net.dnorberg.rivencraft.book.LinkingService;
|
||||||
|
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||||
|
import net.dnorberg.rivencraft.registry.ModItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.GlobalPos;
|
||||||
|
import net.minecraft.gametest.framework.GameTest;
|
||||||
|
import net.minecraft.gametest.framework.GameTestHelper;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.neoforged.neoforge.gametest.GameTestHolder;
|
||||||
|
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;
|
||||||
|
|
||||||
|
/** Server-side regression coverage for persistent linking-book data and travel safety. */
|
||||||
|
@GameTestHolder(Rivencraft.MOD_ID)
|
||||||
|
@PrefixGameTestTemplate(false)
|
||||||
|
public final class LinkingGameTests {
|
||||||
|
private static final BlockPos ORIGIN = new BlockPos(0, 1, 0);
|
||||||
|
|
||||||
|
private LinkingGameTests() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GameTest(template = "empty")
|
||||||
|
public static void linkTargetSurvivesItemSerialization(GameTestHelper helper) {
|
||||||
|
LinkTarget expected = new LinkTarget(
|
||||||
|
GlobalPos.of(helper.getLevel().dimension(), helper.absolutePos(ORIGIN)),
|
||||||
|
127.5F,
|
||||||
|
-31.25F
|
||||||
|
);
|
||||||
|
ItemStack book = new ItemStack(ModItems.LINKING_BOOK.get());
|
||||||
|
book.set(ModDataComponents.LINK_TARGET.get(), expected);
|
||||||
|
|
||||||
|
CompoundTag serialized = (CompoundTag) book.saveOptional(helper.getLevel().registryAccess());
|
||||||
|
ItemStack restored = ItemStack.parseOptional(helper.getLevel().registryAccess(), serialized);
|
||||||
|
|
||||||
|
helper.assertValueEqual(restored.get(ModDataComponents.LINK_TARGET.get()), expected,
|
||||||
|
"A Linking Book must retain its dimension, position, and orientation after serialization");
|
||||||
|
helper.succeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GameTest(template = "empty")
|
||||||
|
public static void travelUsesRecordedSafePosition(GameTestHelper helper) {
|
||||||
|
helper.setBlock(ORIGIN.below(), Blocks.STONE);
|
||||||
|
BlockPos destination = helper.absolutePos(ORIGIN);
|
||||||
|
ServerPlayer player = helper.makeMockServerPlayerInLevel();
|
||||||
|
LinkTarget target = new LinkTarget(GlobalPos.of(helper.getLevel().dimension(), destination), 90.0F, 15.0F);
|
||||||
|
|
||||||
|
LinkingService.LinkResult result = LinkingService.travel(player, target);
|
||||||
|
|
||||||
|
helper.assertValueEqual(result, LinkingService.LinkResult.SUCCESS,
|
||||||
|
"A Linking Book must travel to a clear location with a sturdy floor");
|
||||||
|
helper.assertTrue(player.level() == helper.getLevel(), "Travel must remain in the recorded dimension");
|
||||||
|
helper.assertTrue(Math.abs(player.getYRot() - 90.0F) < 0.01F && Math.abs(player.getXRot() - 15.0F) < 0.01F,
|
||||||
|
"Travel must restore the recorded orientation");
|
||||||
|
helper.succeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GameTest(template = "empty")
|
||||||
|
public static void travelRejectsBlockedDestination(GameTestHelper helper) {
|
||||||
|
BlockPos absoluteOrigin = helper.absolutePos(ORIGIN);
|
||||||
|
for (BlockPos position : BlockPos.betweenClosed(
|
||||||
|
absoluteOrigin.offset(-4, -2, -4), absoluteOrigin.offset(4, 2, 4))) {
|
||||||
|
helper.getLevel().setBlockAndUpdate(position, Blocks.STONE.defaultBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerPlayer player = helper.makeMockServerPlayerInLevel();
|
||||||
|
LinkTarget target = new LinkTarget(GlobalPos.of(helper.getLevel().dimension(), absoluteOrigin), 0.0F, 0.0F);
|
||||||
|
|
||||||
|
helper.assertValueEqual(LinkingService.travel(player, target), LinkingService.LinkResult.NO_SAFE_DESTINATION,
|
||||||
|
"Linking must fail rather than placing a player inside a blocked destination");
|
||||||
|
helper.succeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in new issue
Block a user