Add new /forge gen command to generate large amounts of chunks.
Usage: /forge gen <position> <count> [dimension] [notifications] Position is in Block Coords, and can be relative to the player. These will be converted to chunk coords for you. Count is the number of chunks to load. This is not a radius, actual total number of chunks. Dimension is optional, you can use this to pregen other worlds. Notifications is the chunk interval to inform you of the generating progress. This is optional and will be 5% or 100 whichever is higher. Added new config option to modify vanilla world gen to fix various cascading issues. MC-117810 MC-114332 and more. This WILL change block placement from vanilla world gen. So this is a opt-in value. Do not report differences in worlds with this flag enabled.
This commit is contained in:
parent
036191cd52
commit
0ad4218bc2
|
@ -35,7 +35,7 @@
|
|||
}
|
||||
|
||||
public void func_180622_a(World p_180622_1_, Random p_180622_2_, ChunkPrimer p_180622_3_, int p_180622_4_, int p_180622_5_, double p_180622_6_)
|
||||
@@ -88,4 +81,24 @@
|
||||
@@ -88,4 +81,25 @@
|
||||
EXTRA_TREES,
|
||||
MUTATED;
|
||||
}
|
||||
|
@ -48,7 +48,8 @@
|
|||
+ int count = 3 + rand.nextInt(6);
|
||||
+ for (int i = 0; i < count; i++)
|
||||
+ {
|
||||
+ BlockPos blockpos = pos.func_177982_a(rand.nextInt(16), rand.nextInt(28) + 4, rand.nextInt(16));
|
||||
+ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-114332
|
||||
+ BlockPos blockpos = pos.func_177982_a(rand.nextInt(16) + offset, rand.nextInt(28) + 4, rand.nextInt(16) + offset);
|
||||
+
|
||||
+ net.minecraft.block.state.IBlockState state = worldIn.func_180495_p(blockpos);
|
||||
+ if (state.func_177230_c().isReplaceableOreGen(state, worldIn, blockpos, net.minecraft.block.state.pattern.BlockMatcher.func_177642_a(Blocks.field_150348_b)))
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
for (int l1 = 0; l1 < 16; ++l1)
|
||||
{
|
||||
this.field_177467_w.func_180709_b(this.field_185952_n, this.field_185954_p, blockpos.func_177982_a(this.field_185954_p.nextInt(16), this.field_185954_p.nextInt(108) + 10, this.field_185954_p.nextInt(16)));
|
||||
@@ -402,17 +434,22 @@
|
||||
@@ -402,17 +434,23 @@
|
||||
|
||||
int i2 = this.field_185952_n.func_181545_F() / 2 + 1;
|
||||
|
||||
|
@ -106,7 +106,9 @@
|
|||
+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.field_185952_n, this.field_185954_p, p_185931_1_, p_185931_2_, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA2))
|
||||
for (int j2 = 0; j2 < 16; ++j2)
|
||||
{
|
||||
this.field_177473_x.func_180709_b(this.field_185952_n, this.field_185954_p, blockpos.func_177982_a(this.field_185954_p.nextInt(16), this.field_185954_p.nextInt(108) + 10, this.field_185954_p.nextInt(16)));
|
||||
- this.field_177473_x.func_180709_b(this.field_185952_n, this.field_185954_p, blockpos.func_177982_a(this.field_185954_p.nextInt(16), this.field_185954_p.nextInt(108) + 10, this.field_185954_p.nextInt(16)));
|
||||
+ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-117810
|
||||
+ this.field_177473_x.func_180709_b(this.field_185952_n, this.field_185954_p, blockpos.func_177982_a(this.field_185954_p.nextInt(16) + offset, this.field_185954_p.nextInt(108) + 10, this.field_185954_p.nextInt(16) + offset));
|
||||
}
|
||||
|
||||
biome.func_180624_a(this.field_185952_n, this.field_185954_p, new BlockPos(i, 0, j));
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
--- ../src-base/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java
|
||||
@@ -161,7 +161,8 @@
|
||||
|
||||
if (p_180709_1_.func_175675_v(p_180709_3_.func_177982_a(k2, 4, l3)))
|
||||
{
|
||||
- p_180709_1_.func_180501_a(p_180709_3_.func_177982_a(k2, 4, l3), Blocks.field_150432_aD.func_176223_P(), 2);
|
||||
+ int flag = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 2| 16 : 2; //Forge: With bit 5 unset, it will notify neighbors and load adjacent chunks.
|
||||
+ p_180709_1_.func_180501_a(p_180709_3_.func_177982_a(k2, 4, l3), Blocks.field_150432_aD.func_176223_P(), flag); //Forge
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ import net.minecraftforge.event.world.WorldEvent;
|
|||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ServerTickEvent;
|
||||
|
||||
public class ForgeInternalHandler
|
||||
{
|
||||
|
@ -68,7 +70,7 @@ public class ForgeInternalHandler
|
|||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
public void onDimensionSave(WorldEvent.Save event)
|
||||
{
|
||||
ForgeChunkManager.saveWorld(event.getWorld());
|
||||
ForgeChunkManager.saveWorld(event.getWorld());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
|
@ -78,4 +80,11 @@ public class ForgeInternalHandler
|
|||
if (event.getWorld() instanceof WorldServer)
|
||||
FakePlayerFactory.unloadWorld((WorldServer) event.getWorld());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerTick(ServerTickEvent event)
|
||||
{
|
||||
WorldWorkerManager.tick(event.phase == TickEvent.Phase.START);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ import net.minecraftforge.fml.common.event.FMLModIdMappingEvent;
|
|||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
|
@ -117,6 +118,8 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
|
|||
public static boolean alwaysSetupTerrainOffThread = false; // In RenderGlobal.setupTerrain, always force the chunk render updates to be queued to the thread
|
||||
public static int dimensionUnloadQueueDelay = 0;
|
||||
public static boolean logCascadingWorldGeneration = true; // see Chunk#logCascadingWorldGeneration()
|
||||
public static boolean fixVanillaCascading = false; // There are various places in vanilla that cause cascading worldgen. Enabling this WILL change where blocks are placed to prevent this.
|
||||
// DO NOT contact Forge about worldgen not 'matching' vanilla if this flag is set.
|
||||
|
||||
static final Logger log = LogManager.getLogger(ForgeVersion.MOD_ID);
|
||||
|
||||
|
@ -288,6 +291,12 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
|
|||
prop.setLanguageKey("forge.configgui.logCascadingWorldGeneration");
|
||||
propOrder.add(prop.getName());
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "fixVanillaCascading", false,
|
||||
"Fix vanilla issues that cause worldgen cascading. This DOES change vanilla worldgen so DO NOT report bugs related to world differences if this flag is on.");
|
||||
fixVanillaCascading = prop.getBoolean();
|
||||
prop.setLanguageKey("forge.configgui.fixVanillaCascading");
|
||||
propOrder.add(prop.getName());
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "dimensionUnloadQueueDelay", 0,
|
||||
"The time in ticks the server will wait when a dimension was queued to unload. " +
|
||||
"This can be useful when rapidly loading and unloading dimensions, like e.g. throwing items through a nether portal a few time per second.");
|
||||
|
@ -509,6 +518,13 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
|
|||
{
|
||||
evt.registerServerCommand(new ForgeCommand());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void serverStopping(FMLServerStoppingEvent evt)
|
||||
{
|
||||
WorldWorkerManager.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldWorkerManager
|
||||
{
|
||||
private static List<IWorker> workers = new ArrayList<IWorker>();
|
||||
private static long startTime = -1;
|
||||
|
||||
public static void tick(boolean start)
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
startTime = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
|
||||
IWorker task = getNext();
|
||||
if (task == null)
|
||||
return;
|
||||
|
||||
long time = 50 - (System.currentTimeMillis() - startTime);
|
||||
if (time < 10)
|
||||
time = 10; //If ticks are lagging, give us at least 10ms to do something.
|
||||
time += System.currentTimeMillis();
|
||||
|
||||
while (System.currentTimeMillis() < time)
|
||||
{
|
||||
task.work();
|
||||
|
||||
if (!task.hasWork())
|
||||
{
|
||||
time = 0; //Break loop
|
||||
remove(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void addWorker(IWorker worker)
|
||||
{
|
||||
workers.add(worker);
|
||||
}
|
||||
|
||||
private static synchronized IWorker getNext()
|
||||
{
|
||||
return workers.size() > 0 ? workers.get(0) : null;
|
||||
}
|
||||
|
||||
private static synchronized void remove(IWorker worker)
|
||||
{
|
||||
workers.remove(worker);
|
||||
}
|
||||
|
||||
//Internal only, used to clear everything when the server shuts down.
|
||||
public static synchronized void clear()
|
||||
{
|
||||
workers.clear();
|
||||
}
|
||||
|
||||
public static interface IWorker
|
||||
{
|
||||
boolean hasWork();
|
||||
void work();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package net.minecraftforge.server.command;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.server.management.PlayerChunkMapEntry;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.ForgeChunkManager;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import net.minecraftforge.common.WorldWorkerManager.IWorker;
|
||||
|
||||
public class ChunkGenWorker implements IWorker
|
||||
{
|
||||
private final ICommandSender listener;
|
||||
protected final BlockPos start;
|
||||
protected final int total;
|
||||
private final int dim;
|
||||
private final Queue<BlockPos> queue;
|
||||
private final int notificationFrequency;
|
||||
private int lastNotification = 0;
|
||||
private int genned = 0;
|
||||
private int oldUnloadDelay = -1;
|
||||
|
||||
public ChunkGenWorker(ICommandSender listener, BlockPos start, int total, int dim, int interval)
|
||||
{
|
||||
this.listener = listener;
|
||||
this.start = start;
|
||||
this.total = total;
|
||||
this.dim = dim;
|
||||
this.queue = buildQueue();
|
||||
this.notificationFrequency = interval != -1 ? interval : Math.max(total / 20, 100); //Every 5% or every 100, whichever is more.
|
||||
}
|
||||
|
||||
protected Queue<BlockPos> buildQueue()
|
||||
{
|
||||
Queue<BlockPos> ret = new ArrayDeque<BlockPos>();
|
||||
ret.add(start);
|
||||
|
||||
//This *should* spiral outwards, starting on right side, down, left, up, right, but hey we'll see!
|
||||
int radius = 1;
|
||||
while (ret.size() < total)
|
||||
{
|
||||
for (int q = -radius + 1; q <= radius && ret.size() < total; q++)
|
||||
ret.add(start.add(radius, 0, q));
|
||||
|
||||
for (int q = radius - 1; q >= -radius && ret.size() < total; q--)
|
||||
ret.add(start.add(q, 0, radius));
|
||||
|
||||
for (int q = radius - 1; q >= -radius && ret.size() < total; q--)
|
||||
ret.add(start.add(-radius, 0, q));
|
||||
|
||||
for (int q = -radius + 1; q <= radius && ret.size() < total; q++)
|
||||
ret.add(start.add(q, 0, -radius));
|
||||
|
||||
radius++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public TextComponentTranslation getStartMessage()
|
||||
{
|
||||
return new TextComponentTranslation("commands.forge.gen.start", total, start.getX(), start.getZ(), dim);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWork()
|
||||
{
|
||||
return queue.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void work()
|
||||
{
|
||||
BlockPos next = queue.poll();
|
||||
|
||||
if (next != null)
|
||||
{
|
||||
WorldServer world = DimensionManager.getWorld(dim);
|
||||
if (world == null)
|
||||
{
|
||||
DimensionManager.initDimension(dim);
|
||||
world = DimensionManager.getWorld(dim);
|
||||
if (world == null)
|
||||
{
|
||||
listener.sendMessage(new TextComponentTranslation("commands.forge.gen.dim_fail", dim));
|
||||
queue.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//While we work we don't want to cause world load spam so pause unloading worlds.
|
||||
if (oldUnloadDelay == -1)
|
||||
{
|
||||
oldUnloadDelay = ForgeModContainer.dimensionUnloadQueueDelay;
|
||||
ForgeModContainer.dimensionUnloadQueueDelay = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
if (++lastNotification >= notificationFrequency)
|
||||
{
|
||||
listener.sendMessage(new TextComponentTranslation("commands.forge.gen.progress", total - queue.size(), total));
|
||||
lastNotification = 0;
|
||||
}
|
||||
|
||||
int x = next.getX();
|
||||
int z = next.getZ();
|
||||
|
||||
Chunk target = world.getChunkFromChunkCoords(x, z);
|
||||
Chunk[] chunks = { target };
|
||||
|
||||
if (!target.isTerrainPopulated())
|
||||
{
|
||||
// In order for a chunk to populate, The chunks around its bottom right corner need to be loaded.
|
||||
// So lets load those chunks, but this needs to be done in a certain order to make this trigger.
|
||||
// So this does load more chunks then it should, and is a hack, but lets go!.
|
||||
chunks = new Chunk[] {
|
||||
target,
|
||||
world.getChunkFromChunkCoords(x + 1, z),
|
||||
world.getChunkFromChunkCoords(x + 1, z + 1),
|
||||
world.getChunkFromChunkCoords(x, z + 1),
|
||||
};
|
||||
genned++;
|
||||
}
|
||||
|
||||
for (Chunk chunk : chunks) //Now lets unload them. Note: Saving is done off thread so there may be cache hits, but this should still unload everything.
|
||||
{
|
||||
PlayerChunkMapEntry watchers = world.getPlayerChunkMap().getEntry(chunk.x, chunk.z);
|
||||
if (watchers == null) //If there are no players watching this, this will be null, so we can unload.
|
||||
world.getChunkProvider().queueUnload(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
if (queue.size() == 0)
|
||||
{
|
||||
listener.sendMessage(new TextComponentTranslation("commands.forge.gen.complete", genned, total, dim));
|
||||
ForgeModContainer.dimensionUnloadQueueDelay = oldUnloadDelay;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,14 +20,21 @@
|
|||
package net.minecraftforge.server.command;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.WorldWorkerManager;
|
||||
import net.minecraftforge.server.ForgeTimeTracker;
|
||||
|
||||
public class ForgeCommand extends CommandBase {
|
||||
|
@ -64,22 +71,47 @@ public class ForgeCommand extends CommandBase {
|
|||
}
|
||||
else if ("tps".equals(args[0]))
|
||||
{
|
||||
displayTPS(server, sender,args);
|
||||
displayTPS(server, sender, args);
|
||||
}
|
||||
else if ("tpslog".equals(args[0]))
|
||||
/*else if ("tpslog".equals(args[0]))
|
||||
{
|
||||
doTPSLog(server, sender,args);
|
||||
doTPSLog(server, sender, args);
|
||||
}
|
||||
*/
|
||||
else if ("track".equals(args[0]))
|
||||
{
|
||||
handleTracking(server, sender, args);
|
||||
}
|
||||
else if ("gen".equals(args[0]))
|
||||
{
|
||||
handleGen(server, sender, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos)
|
||||
{
|
||||
if (args.length <= 1)
|
||||
return getListOfStringsMatchingLastWord(args, new String[] {"help", "tps", "track", "gen"});
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
case "gen":
|
||||
if (args.length > 1 && args.length <= 4)
|
||||
return getTabCompletionCoordinate(args, 1, targetPos);
|
||||
if (args.length == 5) //Chunk Count? No completion
|
||||
return Collections.emptyList();
|
||||
if (args.length == 6) // Dimension, Add support for names? Get list of ids? Meh
|
||||
return Collections.emptyList();
|
||||
break;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void handleTracking(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException
|
||||
{
|
||||
if (args.length != 3)
|
||||
|
@ -140,6 +172,23 @@ public class ForgeCommand extends CommandBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleGen(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException
|
||||
{
|
||||
// gen x y z chunkCount [dim] [shape?]
|
||||
if (args.length < 5)
|
||||
throw new WrongUsageException("commands.forge.gen.usage");
|
||||
|
||||
BlockPos blockpos = parseBlockPos(sender, args, 1, false);
|
||||
int count = parseInt(args[4], 10);
|
||||
int dim = args.length >= 6 ? parseInt(args[5]) : sender.getEntityWorld().provider.getDimension();
|
||||
int interval = args.length >= 7 ? parseInt(args[6]) : -1;
|
||||
BlockPos chunkpos = new BlockPos(blockpos.getX() >> 4, 0, blockpos.getZ() >> 4);
|
||||
|
||||
ChunkGenWorker worker = new ChunkGenWorker(sender, chunkpos, count, dim, interval);
|
||||
sender.sendMessage(worker.getStartMessage());
|
||||
WorldWorkerManager.addWorker(worker);
|
||||
}
|
||||
|
||||
private static long mean(long[] values)
|
||||
{
|
||||
long sum = 0l;
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
commands.forge.usage=Use /forge <subcommand>. Subcommands are tps, track
|
||||
commands.forge.usage=Use /forge <subcommand>. Subcommands are tps, track, gen
|
||||
commands.forge.usage.tracking=Use /forge track <type> <duration>. Valid types are te (Tile Entities). Duration is < 60.
|
||||
commands.forge.tps.summary=%s : Mean tick time: %d ms. Mean TPS: %d
|
||||
commands.forge.gen.usage=Use /forge gen <x> <y> <z> <chunkCount> [dimension] [interval]
|
||||
commands.forge.gen.dim_fail=Failed to load world for dimension %d, Task terminated.
|
||||
commands.forge.gen.progress=Generation Progress: %d/%d
|
||||
commands.forge.gen.complete=Finished generating %d new chunks (out of %d) for dimension %d.
|
||||
commands.forge.gen.start=Starting to generate %d chunks in a spiral around %d, %d in dimension %d.
|
||||
|
||||
commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds.
|
||||
commands.tree_base.invalid_cmd=Invalid subcommand '%s'!
|
||||
|
@ -69,6 +74,8 @@ forge.configgui.playerTicketCount.tooltip=The number of tickets a player can be
|
|||
forge.configgui.playerTicketCount=Player Ticket Limit
|
||||
forge.configgui.logCascadingWorldGeneration=Log Cascading World Gen
|
||||
forge.configgui.logCascadingWorldGeneration.tooltip=Log cascading chunk generation issues during terrain population.
|
||||
forge.configgui.fixVanillaCascading=Fix Vanilla Cascading
|
||||
forge.configgui.fixVanillaCascading.tooltip=Fix various bugs in vanilla world gen that causes extra chunks to load. This WILL change your worldgen from vanilla. Do not report differences if this is enabled.
|
||||
|
||||
fml.config.sample.basicDouble.tooltip=A double property with no defined bounds.
|
||||
fml.config.sample.basicDouble=Unbounded Double
|
||||
|
|
Loading…
Reference in New Issue