Skip to content

Conversation

@visz11
Copy link

@visz11 visz11 commented Dec 23, 2025

CodeAnt-AI Description

Set spawn, dimension, and world-storage overrides and skip spawn computation to speed world creation

What Changed

  • World creation can now skip computing the spawn location by providing a forced spawn position and rotation; when set, the world uses that spawn and does not spawn a bonus chest.
  • You can override the world's dimension type and the directory where the world's files are stored when creating a world; world data is written to the provided folder and the chosen dimension is applied.
  • World creation uses the provided world-file directory and applies the optional dimension override, and the server initialization will respect a forced spawn without loading chunks.

Impact

✅ Faster world creation (vanilla worlds: ~1s → ~20ms)
✅ Create worlds in a custom folder
✅ Create worlds with an explicit dimension and spawn without chunk loads

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

Warning

Rate limit exceeded

@visz11 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 90191f7 and 81130d3.

📒 Files selected for processing (8)
  • paper-api/src/main/java/org/bukkit/WorldCreator.java
  • paper-server/patches/features/0001-Moonrise-optimisation-patches.patch
  • paper-server/patches/features/0002-Rewrite-dataconverter-system.patch
  • paper-server/patches/features/0020-Incremental-chunk-and-player-saving.patch
  • paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch
  • paper-server/patches/features/0028-Optimize-Hoppers.patch
  • paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
  • paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/spawnloc-creation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @visz11, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces advanced customization options for world creation, allowing users to precisely define a new world's initial spawn point, its associated dimension type, and where its data files will be stored. These changes empower developers with more granular control over the world generation process, moving beyond standard defaults.

Highlights

  • Enhanced WorldCreator API: The WorldCreator class has been significantly extended to allow for explicit control over a new world's spawn position, yaw, pitch, dimension key, and storage directory. This provides greater flexibility for world generation.
  • Forced Spawn Position: New methods forcedSpawnPosition, forcedSpawnYaw, and forcedSpawnPitch have been added to WorldCreator to allow overriding the default or generator-determined spawn location and orientation. Setting a forced spawn position will prevent the bonus chest from spawning.
  • Dimension Key Override: The WorldCreator now includes dimensionKeyOverride and getDimensionKeyOverride methods, enabling developers to specify the dimension type (e.g., overworld, nether, end, or custom) for a new world, overriding vanilla or generator settings.
  • Custom World File Storage: A worldFileStorage method has been added to WorldCreator, allowing the specification of a custom parent directory for a new world's data, rather than using the default world container.
  • Integration with World Creation Logic: The CraftServer's createWorld method and MinecraftServer's initWorld method have been updated to consume and apply these new WorldCreator properties, ensuring that the specified overrides are respected during world initialization.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@refacto-visz
Copy link

refacto-visz bot commented Dec 23, 2025

Refacto PR Summary

Enhanced Minecraft world creation system with forced spawn positioning, custom dimension support, and flexible world file storage. The implementation adds comprehensive spawn location control during world creation, allowing server administrators to override vanilla spawn generation with precise coordinates and rotation values.

Key Changes:

  • Added forced spawn position API with Position interface supporting both block and fine coordinates
  • Implemented dimension key override system for custom world types (overworld, nether, end, custom)
  • Enhanced world file storage configuration allowing worlds to be stored in custom directories
  • Extended MinecraftServer initialization to handle forced spawn coordinates with yaw/pitch rotation
  • Integrated PaperAdventure key conversion for dimension type resolution from registry

Change Highlights

Click to expand
  • paper-api/src/main/java/org/bukkit/WorldCreator.java: Added spawn position override, dimension key override, and world file storage configuration methods
  • paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch: Enhanced initWorld method to accept forced position parameters and bypass vanilla spawn generation
  • paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java: Integrated dimension key override resolution and forced spawn parameter passing to server initialization
  • paper-server/patches/features/0001-Moonrise-optimisation-patches.patch: Updated MinecraftServer class structure for new world initialization parameters
  • paper-server/patches/features/0002-Rewrite-dataconverter-system.patch: Maintained compatibility with dataconverter system changes

Sequence Diagram

sequenceDiagram
    participant A as Admin/Plugin
    participant WC as WorldCreator
    participant CS as CraftServer
    participant MS as MinecraftServer
    participant SL as ServerLevel
    
    A->>WC: forcedSpawnPosition(position, yaw, pitch)
    A->>WC: dimensionKeyOverride(key)
    A->>WC: worldFileStorage(directory)
    A->>WC: createWorld()
    WC->>CS: Create world with overrides
    CS->>CS: Resolve dimension key via PaperAdventure
    CS->>MS: initWorld(level, data, options, position, pitch, yaw)
    alt Forced position provided
        MS->>SL: setSpawn(forcedPosition, yaw, pitch)
    else No forced position
        MS->>SL: setInitialSpawn(vanilla generation)
    end
    MS-->>CS: World initialized
    CS-->>A: World created successfully
Loading

Testing Guide

Click to expand
  1. Forced spawn creation: Create world with forcedSpawnPosition(Position.block(100, 64, 200), 90f, 0f), verify spawn location matches coordinates exactly
  2. Dimension override: Create world with dimensionKeyOverride(Key.key("minecraft:the_nether")), confirm world uses nether dimension type regardless of environment setting
  3. Custom storage directory: Use worldFileStorage(new File("/custom/worlds")), verify world files are created in specified directory instead of default world container
  4. Vanilla fallback: Create world without overrides, confirm normal spawn generation and default dimension behavior works
  5. Integration test: Create multiple worlds with different combinations of overrides, verify each world maintains independent configuration

@refacto-visz
Copy link

refacto-visz bot commented Dec 23, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Dec 23, 2025
@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

Sequence Diagram

Shows how a WorldCreator's new overrides (world storage path, dimension key, forced spawn position/yaw/pitch) flow through CraftServer into the server/world init so the spawn can be set without chunk loads.

sequenceDiagram
    participant Plugin
    participant CraftServer
    participant LevelStorage
    participant MinecraftServer

    Plugin->>CraftServer: createWorld(WorldCreator{worldFileStorage, dimensionKeyOverride, forcedSpawnPosition})
    CraftServer->>LevelStorage: createDefault(access using WorldCreator.getWorldFileStorage())
    LevelStorage-->>CraftServer: LevelStorageAccess
    CraftServer->>MinecraftServer: prepare LevelStem (apply dimensionKeyOverride if present) and create ServerLevel
    CraftServer->>MinecraftServer: initWorld(serverLevel, ..., forcedSpawnPosition, forcedPitch, forcedYaw)
    alt forcedSpawnPosition set
        MinecraftServer->>MinecraftServer: set spawn directly (no chunk loads)
    else
        MinecraftServer->>MinecraftServer: setInitialSpawn (generator/vanilla behavior)
    end
    MinecraftServer-->>CraftServer: world initialized
    CraftServer-->>Plugin: return created World
Loading

Generated by CodeAnt AI

@refacto-visz
Copy link

refacto-visz bot commented Dec 23, 2025

Code Review: WorldCreator File Path Security Enhancement

PR Confidence Score: 🟨 4 / 5

👍 Well Done
Clear API Design

Method signature provides clear null safety annotations and follows builder pattern conventions

📁 Selected files for review (8)
  • paper-api/src/main/java/org/bukkit/WorldCreator.java
  • paper-server/patches/features/0001-Moonrise-optimisation-patches.patch
  • paper-server/patches/features/0002-Rewrite-dataconverter-system.patch
  • paper-server/patches/features/0020-Incremental-chunk-and-player-saving.patch
  • paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch
  • paper-server/patches/features/0028-Optimize-Hoppers.patch
  • paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
  • paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
🎯 Custom Instructions
❌ Unapplied Instructions
Organization Guidelines

Reason: Your set path patterns [src/, config/] don't match any selected files for review; Your set extension patterns [.js, .ts] don't match any selected files for review

Comment on lines +258 to +261
public WorldCreator worldFileStorage(@NotNull File override) {
this.worldFileOverride = override;
return this;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe File Path

Method accepts arbitrary file paths without validation enabling path traversal attacks. Malicious users could specify paths like '../../../etc/passwd' to access sensitive system files or overwrite critical server data. Path canonicalization and directory traversal prevention required.

    public WorldCreator worldFileStorage(@NotNull File override) {
        Preconditions.checkNotNull(override, "World file storage cannot be null");
        try {
            File canonicalFile = override.getCanonicalFile();
            File worldContainer = Bukkit.getWorldContainer().getCanonicalFile();
            if (!canonicalFile.toPath().startsWith(worldContainer.toPath())) {
                throw new IllegalArgumentException("World storage path must be within server world container");
            }
            this.worldFileOverride = canonicalFile;
        } catch (java.io.IOException e) {
            throw new IllegalArgumentException("Invalid world storage path: " + override.getPath(), e);
        }
        return this;
    }
Commitable Suggestion
Suggested change
public WorldCreator worldFileStorage(@NotNull File override) {
this.worldFileOverride = override;
return this;
}
public WorldCreator worldFileStorage(@NotNull File override) {
Preconditions.checkNotNull(override, "World file storage cannot be null");
try {
File canonicalFile = override.getCanonicalFile();
File worldContainer = Bukkit.getWorldContainer().getCanonicalFile();
if (!canonicalFile.toPath().startsWith(worldContainer.toPath())) {
throw new IllegalArgumentException("World storage path must be within server world container");
}
this.worldFileOverride = canonicalFile;
} catch (java.io.IOException e) {
throw new IllegalArgumentException("Invalid world storage path: " + override.getPath(), e);
}
return this;
}
Standards
  • CWE-22
  • OWASP-A01
  • NIST-SSDF-PW.1

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new API in WorldCreator to override the spawn location, dimension type, and world storage location. The changes are well-implemented across the API and server logic. I've found a couple of issues in WorldCreator.java related to representation exposure and API consistency that should be addressed. My review includes suggestions to fix these issues by ensuring defensive copies of Position objects are used and by making the behavior of forcedSpawnPosition more consistent.

Comment on lines +308 to +321
public WorldCreator forcedSpawnPosition(@Nullable Position position, float yaw, float pitch
) {
if (position == null) {
this.spawnPositionOverride = null;
this.spawnYawOverride = yaw;
this.spawnPitchOverride = pitch;
return this;
}

this.spawnPositionOverride = position;
this.spawnYawOverride = yaw;
this.spawnPitchOverride = pitch;
return this;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method contains a redundant if block, as the logic is identical in both branches. This can be simplified.

Additionally, there are two other concerns:

  1. Representation Exposure: The method stores the passed position object directly. If the caller modifies this object after calling the method, the internal state of this WorldCreator will be changed. A defensive copy should be stored instead.
  2. API Inconsistency: If position is null, spawnPositionOverride is set to null, but spawnYawOverride and spawnPitchOverride are still set. This is inconsistent with the Javadoc for forcedSpawnYaw() and forcedSpawnPitch(), which state that yaw/pitch are only meaningful if a spawn position is present. When position is null, yaw and pitch overrides should also be cleared to reflect that vanilla behavior is being used for the entire spawn location.

Here is a suggested implementation that addresses these points:

    public WorldCreator forcedSpawnPosition(@Nullable Position position, float yaw, float pitch
    ) {
        if (position != null) {
            this.spawnPositionOverride = Position.fine(position.x(), position.y(), position.z());
            this.spawnYawOverride = yaw;
            this.spawnPitchOverride = pitch;
        } else {
            this.spawnPositionOverride = null;
            this.spawnYawOverride = null;
            this.spawnPitchOverride = null;
        }
        return this;
    }

Comment on lines +334 to +336
public Position forcedSpawnPosition() {
return this.spawnPositionOverride == null ? null : this.spawnPositionOverride;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method can be simplified by removing the redundant ternary operator. More importantly, the Javadoc states that a clone is returned, but the implementation returns the internal object directly. This is a representation exposure issue and violates the API contract. A defensive copy should be returned to prevent external modifications.

    public Position forcedSpawnPosition() {
        return this.spawnPositionOverride != null ? Position.fine(this.spawnPositionOverride.x(), this.spawnPositionOverride.y(), this.spawnPositionOverride.z()) : null;
    }

@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Tick loop complexity / timing
    The tick loop and new scheduling/catchup logic were substantially reworked. This introduces non-trivial timing and concurrency behavior (tickSchedule advance/period logic, task draining while waiting). Please add focused tests and review race conditions where nextTickTimeNanos, currentTickStart, scheduledTickStart, taskExecutionTime and waitingForNextTick are read/updated across methods to ensure they cannot be concurrently observed in inconsistent states causing incorrect scheduling or watchdog triggers.

  • Unhandled exceptions risk
    A call to this.moonrise$executeMidTickTasks() is injected into pollTaskInternal. If this method throws an exception it may propagate out of the poll loop and break task polling or the server tick loop. Ensure exceptions are caught or otherwise contained and that the call is safe to run on that code path.

  • Patch metadata inserted as patch content
    The patch file contains diff metadata lines (e.g. "index ..." and "@@ ...") that are prefixed with '+' and thus treated as added file content rather than diff markers. That will likely break applying the patch with standard tools (git/patch) and corrupt the target file.

  • Hunk header formatting
    The unified diff hunk header appears as an inserted line (with a '+'), not a hunk marker. This causes loss of context and may make the patch unappliable or produce an incorrect file state.

  • Blocking shutdown I/O
    The shutdown path now calls this.services().nameToIdCache().save(false); during server close. If save(false) performs blocking I/O or long work it may slow or deadlock shutdown. Verify whether the method is non-blocking; if not, persist asynchronously or with a bounded timeout to avoid stalling shutdown.

@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

CodeAnt AI finished reviewing your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants