Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starter Structure can sometimes spawn at Y=255 in the nether #2817

Open
ExpensiveKoala opened this issue Dec 24, 2024 · 0 comments
Open

Starter Structure can sometimes spawn at Y=255 in the nether #2817

ExpensiveKoala opened this issue Dec 24, 2024 · 0 comments
Assignees
Labels
Incompatibility Two mods aren't working together. Mod Label Missing A new issue where the mod label has yet to be assigned.

Comments

@ExpensiveKoala
Copy link

Information

Minecraft version: 1.21
Modloader: All
Environment: All

First mod name: Starter Structures
First mod version: 3.9
Collective version: 7.87

Second mod name: Mod in current development

Description

I am currently working on a mod that allows you to set starting dimension to anything. I was testing for compatibility and found an interesting edge case. In testing for the nether, I found an instance where the starter structure winds up generating at y = 255.

Minecraft's spawn selection process does not check for a 2 block space, but rather if there is a solid block available for the level's shared spawn pos. The actual spawn position adjustment (to make sure player doesn't spawn inside a block and suffocate) happens within ServerPlayer#adjustSpawnLocation.
With this in mind, it is entirely possible for the LevelData's exact spawn position to be a 1 block high opening. This can be seen in PlayerRespawnLogic#getOverworldRespawnPos where it attempts to find the highest block with a solid top face given X and Z coordinates. ServerPlayer#adjustSpawnLocation repeatedly calls this method with (pseudo) random X and Z coordinates within spawn radius and checks for collision with the player. This allows player spawn selection to spawn the player in tall grass for example, where it is not air, but there is still no collision to prevent spawning.

This behavior ensures spawn center is on a solid block, without necessarily having the requirement of the spawn center being a valid spawn location.

Now, for determining Starter Structure generation position, you are attempting to find "the surface" at the spawn center's X and Z coordinates.
https://github.com/Serilum/Starter-Structure/blob/e38dbc789aff345773d48eb28e125c7804d4a384/Common/src/main/java/com/natamus/starterstructure/util/Util.java#L98C9-L100C10
This happens when the ignoreTreesDuringStructurePlacement config is true.

This calls BlockPosFunctions#getSurfaceBlockPos with the X and Z spawn coordinates.
The code here seems to attempt to handle surface finding for the nether by iterating from the bottom until finding a 2 block high AIR pocket. However, it is possible for the nether to generate such that the entire column of blocks does not have a 2 block high air pocket.

https://github.com/Serilum/Collective/blob/1f5be7914631cd117a62b3740c6a3a29031c46a8/Common/src/main/java/com/natamus/collective/functions/BlockPosFunctions.java#L214C4-L227C5

int maxHeight = 128;
BlockPos pos = new BlockPos(x, lowestY, z);
for (int y = lowestY; y < maxHeight; y++) {
    BlockState blockState = serverLevel.getBlockState(pos);
    if (blockState.getBlock().equals(Blocks.AIR)) {
        BlockState upstate = serverLevel.getBlockState(pos.above());
        if (upstate.getBlock().equals(Blocks.AIR)) {
            returnPos = pos.immutable();
            break;
        }
    }

    pos = pos.above();
}

This is the problematic code. If the for loop iterates through every block within the column, and fails to satisfy the inner if statements, returnPos is never updated. Unfortunately, this returnPos variable is initialized as BlockPos returnPos = new BlockPos(x, height-1, z);

This is the cause for BlockPosFunctions#getSurfaceBlockPos to return Y = 255 within the nether in certain coordinates and certain seeds.

Interestingly, if the ignoreTreesDuringStructurePlacement config is set to false, the starter structure simply generates at the spawn coordinates and in the seed I was testing with it places the structure completely encased within blocks.

A current limitation is that the bonus chest generates on top of the nether roof, as the feature placement only looks at heightmap. I believe this would also be an acceptable compromise, as spawn center selection is handled separately and is not in the scope of Starter Structures.

@ExpensiveKoala ExpensiveKoala added Incompatibility Two mods aren't working together. Mod Label Missing A new issue where the mod label has yet to be assigned. labels Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Incompatibility Two mods aren't working together. Mod Label Missing A new issue where the mod label has yet to be assigned.
Projects
None yet
Development

No branches or pull requests

2 participants