33

I want to create a new world on our Minecraft server, but exploring a new map and generating terrain causes massive lag.

Is there a way to pre generate the chunks (with the default map generator) in a specific radius around the spawn?

I'm looking for a Bukkit plugin or tool I can use on our Linux machine. An offline tool I can run on my local machine is ok, too.

11 Answers 11

29

In this thread on Reddit, I found a command line script that will generate terrain by repeatedly restarting a server with varying spawn points until the area you specify is filled. This seems like just what you're looking for.

There's also a Bukkit plugin named WorldGenerationControl which can do it on a live server.

5
  • 1
    for future readers, command line script (gist) doesn't exist and WGC is outdated
    – dmnc
    Commented May 8, 2013 at 18:03
  • Boo. That's disappointing.
    – Brant
    Commented May 8, 2013 at 19:04
  • 1
    the command line script is at github.com/DMBuce/mcexplore
    – glob
    Commented Mar 14, 2015 at 10:50
  • Thank you so much @glob! I needed a script like this that works with modded servers very badly last night.
    – PatPeter
    Commented Dec 2, 2018 at 18:05
  • The WorldGenerationControl link does not work anymore Commented Oct 20, 2019 at 15:40
13

It's slow, but you can automatically teleport yourself across all the chunks in a specific area of the map to have them generated using Python and the pexpect module (which I've used to send the teleport commands).

First, make a copy of your game data for testing purposes, then open a command prompt at that directory and do the following:

$ virtualenv venv

$ source venv/bin/activate

$ pip install pexpect

Paste this code into teleport-expect.py (adjust playername and the xcoord and zcoord ranges):

#!/usr/bin/python

import sys
import pexpect
import time

# set this to your minecraft username
playername='yourplayername'

child = pexpect.spawn('java -Xms2048M -Xmx2048M -jar minecraft_server.jar nogui')
child.logfile = sys.stdout
child.expect('%s joined the game' % playername)
child.sendline('gamemode 1 %s' % playername)

for xcoord in range(1000000, 1005000, 16):
    for zcoord in range(1000000, 1005000, 16):
        child.sendline('tp %s %i 255 %i' % (playername, xcoord, zcoord))
        child.expect('Teleported %s' % playername)
        # Time between teleports. Smaller value means more stress for the server.
        time.sleep(0.5)
child.sendline('say all done!')

$ python teleport-expect.py

Once the server starts, login to the game. You should see your player automatically being teleported one chunk at a time across the area of interest. Visiting a 5000x5000 area will take multiple hours to run.

It's not a fast way to generate a map, but neat to see the scenery fly by. I mainly wanted to test running the Minecraft server inside a pexpect session. Lots of potential for other automation (say, watching for user-created commands on a vanilla server)!

2
  • 2
    this worked really well, even now in 2020. and because there's no reliance on world versions/etc, this solution will probably continue to work for a long time. I've found that a 0.08 time instead of 0.5 is perfectly fine even for not-very-powerful machines, because the server is going to generate surrounding chunks anyway, so MOST of the time, the chunk you're visiting is already generated. Commented Oct 1, 2020 at 21:44
  • 1
    Note that this code is Python 2.7 specific, and would need to be adjusted if you needed to use Python 3.
    – Unionhawk
    Commented Jun 17, 2021 at 13:53
5

Minecraft Land Generator:

expands your current vanilla (or modded if you have the server mods) world.

http://www.minecraftforum.net/topic/187737-minecraft-land-generator/

1
3

A totally vanilla way would be to generate a world in singleplayer and explore that manually. This will be a lot of work of course :)

I am not aware of any other methods.

3
  • 8
    If you do that it's much faster to do so in Creative mode, where you can fly and make maps at any points to keep track of your progress. Filling in a map takes about 10 minutes in flight for ~25 MB of chunks.
    – badp
    Commented Oct 12, 2011 at 15:54
  • 1
    This can be combined with Single Player Commands' teleport commands to dramatically lower the time needed.
    – Ben Blank
    Commented Oct 12, 2011 at 16:47
  • 2
    Not sure why this is an answer. OP is obviously looking for a method to automatically, pre-generate his world. Exploring it manually, even with creative mode, is essentially the exact opposite of this.
    – arkon
    Commented Jun 30, 2015 at 23:08
2

The WorldBorder plugin for Bukkit lets you set a predefined map size (measured in radius from spawn), and optionally autogenerate the terrain within your borders.

It automatically generates terrain in the background while the server is running. It took about 24 hours to generate my 3000 block radius round world on a quad core server with 4GB allocated to Minecraft. It seemed like memory was the limiting factor - it would chug along faster than Java's GC routines and have to pause periodically to wait for memory to free up again. Forcing a server restart when memory usage got high did speed it up, but in the end I just ignored it and it managed to finish on it's own.

3
  • 1
    I recommend to use WorldGenerationControl, it is much faster! We combined booth plugins on our server, WorldGenerationControl to generate the world and WorldBorder to keep it in size.
    – Fox32
    Commented Dec 10, 2011 at 13:04
  • @Fox32 I'll have to check that out, thanks.
    – Saiboogu
    Commented Dec 10, 2011 at 22:37
  • WorldBorder plugin is now outdated
    – dmnc
    Commented May 8, 2013 at 18:04
1

A better way of doing this now, is to grab yourself a copy of mcedit from http://www.mcedit.net/ and open up your world with that. download a copy of the minecraft server jar (as the one that comes with MCedit is from 1.5.2) and place it in \ServerJarStorage\release . make sure that the jar is called "minecraft_server.jar" Then just use the Chunk generator tool to generate new chunks of an existing map. Or you could use mcedit to generate a complately new map.

1

enter image description here

#!/usr/bin/python

import sys
import pexpect
import time

# set this to your minecraft username
playername='yourplayername'

child = pexpect.spawn('java -Xms2048M -Xmx2048M -jar minecraft_server.jar nogui')
child.logfile = sys.stdout
child.expect('%s joined the game' % playername)
child.sendline('gamemode 1 %s' % playername)

for xcoord in range(1000000, 1005000, 16):
    for zcoord in range(1000000, 1005000, 16):
        child.sendline('tp %s %i 255 %i' % (playername, xcoord, zcoord))
        child.expect('Teleported %s' % playername)
        # Time between teleports. Smaller value means more stress for the server.
        time.sleep(0.5)
child.sendline('say all done!')
1

The Chunky mod for Fabric, Forge, Bukkit, & Sponge is designed for pregenerating chunks. It can be used in single-player worlds or multiplayer servers. On servers, it can be run either client-side or server-side and can be run with or without players connected. It supports Minecraft versions 1.16 - 1.20 (the latest version as of this post; it appears to be under active development so it should support future versions).

I have found this mod to work much better in almost every aspect than any data pack or script for pregenerating chunks. For instance, datapacks that rely on teleporting the active player around won't reliably generate every single chunk, leaving unsightly gaps in your world.

0

Here is a version, inspired by the pexpect one above.

To run, use Python 3 and have click installed (maybe in a virtual environment). Then, find help in the command line:

$ python explore.py --help
Usage: explore.py [OPTIONS]

  Travel your minecraft world

Options:
  -p, --player TEXT     Set this a a logged in minecraft player name
  -s, --start TEXT      Starting point x:z
  -r, --radius INTEGER  Width of the world you want generated
  --help                Show this message and exit.

Starting from a point, it will teleport a player in an outward spiral by step until a certain width is attained.

The code below presumes your world is running in a docker image. Edit the run_mc_command function to fit your hosting.

It is slow: Generating a 1000x1000 world is (1000/16)^2 = 3906 teleports at minimum half a second each.

Here is the code:

#!/usr/bin/python

from subprocess import run

from itertools import cycle, count

import click


@click.command()
@click.option("-p", "--player",
              help="Set this a a logged in minecraft player name")
@click.option("-s", "--start",
              help="Starting point x:z",
              default="0:0")
@click.option("-r", "--radius",
              help="Width of the world you want generated",
              default=5000)
def main(player: str, start: str, radius):
    """Travel your minecraft world"""
    start = start.split(":", 2)
    parsed_start = float(start[0]), float(start[1])

    click.echo("Exploring world")
    click.echo(f"  Puppeteering {player!s}")
    click.echo(f"  Starting from {parsed_start!s}")
    click.echo(f"  Until reached {radius!s} meters radius (square, of course)")
    explore(player, parsed_start, float(radius))


def explore(player: str, start: tuple, width: float, step: float = 16) -> None:
    """
    Travel you minecaft world

    Args:
        player: A logged in player will be teleported.  This is its playername.
        start: Starting coordinate (x, z).
        width: Width of the square you want explored.
        step: Length of jumps.  Defaults to 16 minecraft blocks.
    """
    run_mc_command(f"gamemode creative {player!s}")
    for position in walk_spiral(start, step):
        run_mc_command(f"tp {player!s} {position[0]!s} 255 {position[1]!s}")
        distance = position[0] - start[0], position[1] - start[1]
        if distance[0] > width:
            break


def run_mc_command(command: str) -> None:
    """
    Run a Minecraft console command..

    Here you can customize base on where you world is hosted.  This
    implementation use the itzg/minecraft-server docker image.

    Args:
        command: A Minecraft command, such as "say hello"
    """
    run(
        [
            "docker", "exec", "mc", "rcon-cli",
            command
        ]
    )


def walk_spiral(start: tuple, step: float = 16) -> tuple:
    """
    Generate positions to teleport to.

    This is an infinite generator.

    Args:
        start: Starting position
        step: Length of jumps.

    Yields:
        Position to teleport to in a spiral.
    """
    current_movement_x, current_movement_z = start
    movements = spiral_movements()

    while True:
        yield current_movement_x, current_movement_z
        next_x_movement, next_y_movement = next(movements)
        current_movement_x += next_x_movement * step
        current_movement_z += next_y_movement * step


def spiral_movements():

    def _spiral_distances():
        for steps in count(1):
            for _ in (0, 1):
                yield steps

    def _clockwise_directions():
        left = (-1, 0)
        right = (1, 0)
        up = (0, -1)
        down = (0, 1)
        return cycle((right, down, left, up))

    for distance, direction in zip(_spiral_distances(), _clockwise_directions()):
        for _ in range(distance):
            yield direction


if __name__ == "__main__":
    main()
0

There's no way to pre generate the chunks. Chunks ONLY generate when a player is in that chunk and visual render distance. As for lag that usually only last a couple days of play and usually isn't that bad on servers with adequate hardware . In any case pre generating the whole world would take up a lot of space. A 50k x 50k map is about 400GB of hard drive space and the preset 29999984 would take up about 100TB of hard drive space. Just do a tp grid of the area you want to gen and let the rest happen as the game progresses. You can use command blocks to do this. Search YouTube for the video.

0

In this Video a Datapack/Commandblock Script is shown that teleports a player to generate Chunks. This method is not very fast but it gets the job done.

Here you can download it.

The 1.15 V2 Version worked for me in 1.16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .