Skip to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Forge 1.20.1 World Generation Architecture Review — Dynamic Rising Sea Level System

Featured Replies

Forge 1.20.1 World Generation Architecture Review — Dynamic Rising Sea Level System

Hello. I am developing a Forge 1.20.1 mod called World FloodEnd.

The core mechanic of the mod is a gradually rising global ocean level.

Every 5 in-game days the global water level increases by 1 block.

Example:

Day 0:  Sea level Y=63
Day 5:  Sea level Y=64
Day 10: Sea level Y=65
...

The main challenge is performance.

I do not want to use the common approach:

Increase water level
        |
        v
Scan the entire world
        |
        v
Place millions of water blocks

because this will eventually destroy TPS on large worlds.

The goal is to make the rising ocean behave like a world generation parameter, not like a giant block update operation.


Intended architecture

The world should have a global value:

FloodLevel = current ocean height

This value is stored by the mod and increases every 5 Minecraft days.

The system is divided into three cases:

                     FloodWorldData
                           |
                           |
                    Current FloodLevel
                           |
          ┌────────────────┼────────────────┐
          |                |                |
          v                v                v

 New unexplored       Loaded chunks       Unloaded chunks

 chunks               around players      stored on disk


 World generation     FloodManager        No processing
 uses current         handles gradual     while inactive
 FloodLevel           flooding


1. New unexplored chunks

When a player travels into unexplored territory, the chunk should already generate with the current ocean level.

Example:

Day 100
FloodLevel = Y=100

Player travels far away

New chunks should generate already matching Y=100

The goal is:

Chunk generation
        |
        v
Current FloodLevel applied
        |
        v
Chunk appears already flooded

Not:

Generate chunk
        |
        v
Place thousands of water blocks afterwards

because that causes huge performance spikes.


Currently I am investigating the world generation stage.

I created a Mixin into:

NoiseBasedChunkGenerator.fillFromNoise()

Example:

@Inject(method = "fillFromNoise", at = @At("HEAD"))
private void worldFloodEnd$fillFromNoise(
        Executor executor,
        Blender blender,
        RandomState randomState,
        StructureManager structureManager,
        ChunkAccess chunk,
        CallbackInfoReturnable<CompletableFuture<ChunkAccess>> cir
)
{
    int waterLevel = FloodWorldData.getWaterLevel();

    WorldFloodEnd.LOGGER.info(
        "[WorldFloodEnd] New chunk {} {} | Water Level {}",
        chunk.getPos().x,
        chunk.getPos().z,
        waterLevel
    );
}

However, this is currently only for testing.

The idea is not to manually place water inside this method.

The intended solution is to make the generator itself use the current FloodLevel.

Possible approaches I am considering:

  • dynamically replacing NoiseGeneratorSettings.seaLevel;

  • overriding ChunkGenerator#getSeaLevel() through Mixin;

  • another Forge-supported world generation hook.


2. Already generated and currently loaded chunks

These chunks are handled differently.

A separate FloodManager should only work with chunks that are currently loaded around players.

Example:

Player base area loaded

        |
        v

FloodManager gradually updates these chunks

        |
        v

Water level increases smoothly

The FloodManager should:

  • process only active chunks;

  • use a limited queue;

  • avoid large TPS spikes;

  • never scan the whole world.

The goal is that the player sees the ocean slowly advancing, while the server remains stable.


3. Previously generated but unloaded chunks

This is an important part.

I do not want unloaded chunks to be constantly processed.

Example:

Day 100
FloodLevel = Y=100

Chunk was generated years ago
Player leaves
Chunk unloads

↓

No background flooding process

Later:

Player returns

↓

Chunk loads again

↓

Chunk should know the current FloodLevel

↓

It updates to the correct state

The world should not require a full scan after every ocean level increase.


Desired final behavior

The complete system should work like this:

Every 5 days:

FloodLevel +1

        |

        |

New chunks:
generated with new water height


Loaded chunks:
FloodManager gradually updates them


Unloaded chunks:
wait until loaded again, then synchronize

Questions for experienced Forge developers

I would appreciate feedback on the architecture before continuing development.

  1. Is using dynamic NoiseGeneratorSettings.seaLevel the correct approach for making new chunks generate with a higher ocean level?

  2. Is NoiseBasedChunkGenerator.fillFromNoise() a good place to hook into, or is there a better generation stage?

  3. Would overriding ChunkGenerator#getSeaLevel() with Mixin be safe, or could it create compatibility issues with other world generation mods?

  4. What is the recommended Forge approach for unloaded chunks:

    • storing a FloodLevel value in chunk NBT?

    • using capabilities?

    • another chunk lifecycle event?

  5. Could this approach interfere with:

    • structures;

    • villages;

    • custom terrain generators;

    • biome generation mods;

    • aquifers?

  6. Is the architecture:

Generation modification for new chunks
+
FloodManager for active chunks
+
state synchronization for unloaded chunks

a reasonable way to implement a dynamic rising ocean without destroying server performance?

Environment:

  • Minecraft Forge 1.20.1

  • Java 17

I am not asking for a complete implementation. I mainly want an architecture review from people familiar with Minecraft world generation and Forge internals.

Thank you.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.