Keep Cave Age spawns below the roof
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-22 16:27:56 -04:00
1 parent 31ba6f9c15
commit 251d0a2de8
3 files changed
+27 -7

No files matched your search

@@ -37,6 +37,7 @@ public final class AgeDimensionService {
private static final int PLATFORM_RADIUS = 2;
private static final int SURFACE_SEARCH_RADIUS = 16;
private static final int FALLBACK_PLATFORM_Y = 63;
private static final int CAVE_SPAWN_SEARCH_Y = 64;
private AgeDimensionService() {
}
@@ -64,7 +65,7 @@ public final class AgeDimensionService {
BlockPos spawn = definition.spawn();
if (spawn == null) {
spawn = createSafeSpawn(level);
spawn = createSafeSpawn(level, definition);
definition = AgeRegistrySavedData.get(level).setSpawn(definition.id(), spawn);
}
return Optional.of(new LinkTarget(
@@ -105,10 +106,19 @@ public final class AgeDimensionService {
return ResourceKey.create(net.minecraft.core.registries.Registries.DIMENSION, definition.dimensionId());
}
private static BlockPos createSafeSpawn(ServerLevel level) {
BlockPos floorCenter = isNetherStyle(level)
? netherSpawnFloor(level)
: highestFootedSurface(level).orElseGet(() -> fallbackSpawnFloor(level));
private static BlockPos createSafeSpawn(ServerLevel level, AgeDefinition age) {
BlockPos floorCenter;
if (age.generationProfile().equals(AgeGenerationProfiles.CAVE)) {
// Cave Ages are enclosed. Searching from the world ceiling would
// select or expose their roof, so begin with the floor beneath a
// player standing at Y=64 and search downward from there.
floorCenter = highestFootedSurface(level, CAVE_SPAWN_SEARCH_Y - 1)
.orElseGet(() -> fallbackSpawnFloor(level));
} else if (isNetherStyle(level)) {
floorCenter = netherSpawnFloor(level);
} else {
floorCenter = highestFootedSurface(level).orElseGet(() -> fallbackSpawnFloor(level));
}
for (int x = -PLATFORM_RADIUS; x <= PLATFORM_RADIUS; x++) {
for (int z = -PLATFORM_RADIUS; z <= PLATFORM_RADIUS; z++) {
@@ -138,8 +148,13 @@ public final class AgeDimensionService {
/** Selects the highest nearby terrain column that can naturally support a player. */
private static Optional<BlockPos> highestFootedSurface(ServerLevel level) {
return highestFootedSurface(level, level.getMaxBuildHeight() - 5);
}
private static Optional<BlockPos> highestFootedSurface(ServerLevel level, int requestedMaximumFloorY) {
BlockPos best = null;
int maximumFloorY = level.getMaxBuildHeight() - 5;
int maximumFloorY = Math.clamp(requestedMaximumFloorY,
level.getMinBuildHeight(), level.getMaxBuildHeight() - 5);
for (int x = -SURFACE_SEARCH_RADIUS; x <= SURFACE_SEARCH_RADIUS; x++) {
for (int z = -SURFACE_SEARCH_RADIUS; z <= SURFACE_SEARCH_RADIUS; z++) {