make pregen use block radius as input

This commit is contained in:
Julian Krings 2025-03-06 15:50:52 +01:00 committed by Julian Krings
parent bdb7cc61e5
commit c468eb1ab1
7 changed files with 97 additions and 52 deletions

View File

@ -140,7 +140,7 @@ public class CommandDeveloper implements DecreeExecutor {
public void packBenchmark( public void packBenchmark(
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld") @Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
IrisDimension dimension, IrisDimension dimension,
@Param(description = "Radius in regions", defaultValue = "5") @Param(description = "Radius in regions", defaultValue = "2048")
int radius, int radius,
@Param(description = "Open GUI while benchmarking", defaultValue = "false") @Param(description = "Open GUI while benchmarking", defaultValue = "false")
boolean gui boolean gui

View File

@ -19,9 +19,7 @@
package com.volmit.iris.core.commands; package com.volmit.iris.core.commands;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.gui.PregeneratorJob;
import com.volmit.iris.core.pregenerator.LazyPregenerator;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeExecutor;
@ -29,12 +27,9 @@ import com.volmit.iris.util.decree.annotations.Decree;
import com.volmit.iris.util.decree.annotations.Param; import com.volmit.iris.util.decree.annotations.Param;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.File;
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!") @Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
public class CommandPregen implements DecreeExecutor { public class CommandPregen implements DecreeExecutor {
@Decree(description = "Pregenerate a world") @Decree(description = "Pregenerate a world")
@ -52,13 +47,12 @@ public class CommandPregen implements DecreeExecutor {
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example."); sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
} }
radius = Math.max(radius, 1024); radius = Math.max(radius, 1024);
int w = (radius >> 9 + 1) * 2;
IrisToolbelt.pregenerate(PregenTask IrisToolbelt.pregenerate(PregenTask
.builder() .builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9)) .center(new Position2(center.getBlockX(), center.getBlockZ()))
.gui(true) .gui(true)
.width(w) .radiusX(radius)
.height(w) .radiusZ(radius)
.build(), world); .build(), world);
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ(); String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
sender().sendMessage(msg); sender().sendMessage(msg);

View File

@ -24,7 +24,6 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
@ -45,8 +44,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
public class PregeneratorJob implements PregenListener { public class PregeneratorJob implements PregenListener {
private static final Color COLOR_EXISTS = parseColor("#4d7d5b"); private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
private static final Color COLOR_BLACK = parseColor("#4d7d5b"); private static final Color COLOR_BLACK = parseColor("#4d7d5b");
@ -81,12 +78,12 @@ public class PregeneratorJob implements PregenListener {
this.task = task; this.task = task;
this.pregenerator = new IrisPregenerator(task, method, this); this.pregenerator = new IrisPregenerator(task, method, this);
max = new Position2(0, 0); max = new Position2(0, 0);
min = new Position2(0, 0); min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE);
task.iterateRegions((xx, zz) -> { task.iterateAllChunks((xx, zz) -> {
min.setX(Math.min(xx << 5, min.getX())); min.setX(Math.min(xx, min.getX()));
min.setZ(Math.min(zz << 5, min.getZ())); min.setZ(Math.min(zz, min.getZ()));
max.setX(Math.max((xx << 5) + 31, max.getX())); max.setX(Math.max(xx, max.getX()));
max.setZ(Math.max((zz << 5) + 31, max.getZ())); max.setZ(Math.max(zz, max.getZ()));
}); });
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) { if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener {
} }
public void drawRegion(int x, int z, Color color) { public void drawRegion(int x, int z, Color color) {
J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> { J.a(() -> task.iterateChunks(x, z, (xx, zz) -> {
draw(xx, zz, color); draw(xx, zz, color);
J.sleep(3); J.sleep(3);
})); }));

View File

@ -165,8 +165,11 @@ public class ChunkUpdater {
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) { if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
return; return;
} }
if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) {
return;
}
PregenTask.iterateRegion(rX, rZ, (x, z) -> { task.iterateChunks(rX, rZ, (x, z) -> {
while (paused.get() && !cancelled.get()) { while (paused.get() && !cancelled.get()) {
J.sleep(50); J.sleep(50);
} }
@ -348,8 +351,8 @@ public class ChunkUpdater {
int width = maxZ - minZ + 1; int width = maxZ - minZ + 1;
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder() return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
.width((int) Math.ceil(width / 2d)) .radiusZ((int) Math.ceil(width / 2d * 512))
.height((int) Math.ceil(height / 2d)) .radiusX((int) Math.ceil(height / 2d * 512))
.center(new Position2(oX, oZ)) .center(new Position2(oX, oZ))
.build()); .build());
} }

View File

@ -19,7 +19,6 @@
package com.volmit.iris.core.pregenerator; package com.volmit.iris.core.pregenerator;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.pack.IrisPack;
import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
@ -83,7 +82,7 @@ public class IrisPregenerator {
generatedLast = new AtomicInteger(0); generatedLast = new AtomicInteger(0);
generatedLastMinute = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0);
totalChunks = new AtomicInteger(0); totalChunks = new AtomicInteger(0);
task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet());
startTime = new AtomicLong(M.ms()); startTime = new AtomicLong(M.ms());
ticker = new Looper() { ticker = new Looper() {
@Override @Override
@ -194,7 +193,7 @@ public class IrisPregenerator {
} else if (!regions) { } else if (!regions) {
hit = true; hit = true;
listener.onRegionGenerating(x, z); listener.onRegionGenerating(x, z);
PregenTask.iterateRegion(x, z, (xx, zz) -> { task.iterateChunks(x, z, (xx, zz) -> {
while (paused.get() && !shutdown.get()) { while (paused.get() && !shutdown.get()) {
J.sleep(50); J.sleep(50);
} }

View File

@ -32,17 +32,26 @@ import java.util.Comparator;
@Data @Data
public class PregenTask { public class PregenTask {
private static final Position2 ZERO = new Position2(0, 0); private static final Position2 ZERO = new Position2(0, 0);
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>(); private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
@Builder.Default @Builder.Default
private boolean gui = false; private final boolean gui = false;
@Builder.Default @Builder.Default
private Position2 center = new Position2(0, 0); private final Position2 center = new Position2(0, 0);
@Builder.Default @Builder.Default
private int width = 1; private final int radiusX = 1;
@Builder.Default @Builder.Default
private int height = 1; private final int radiusZ = 1;
private final Bounds bounds = new Bounds();
protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) {
this.gui = gui;
this.center = new ProxiedPos(center);
this.radiusX = radiusX;
this.radiusZ = radiusZ;
bounds.update();
}
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) { public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) { for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
@ -70,29 +79,72 @@ public class PregenTask {
return p; return p;
} }
private static KList<Position2> computeChunkOrder() { public void iterateRegions(Spiraled s) {
Position2 center = new Position2(15, 15); var bound = bounds.region();
KList<Position2> p = new KList<>(); new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> {
new Spiraler(33, 33, (x, z) -> { if (bound.check(x, z)) s.on(x, z);
int xx = x + 15; })).setOffset(center.getX() >> 9, center.getZ() >> 9).drain();
int zz = z + 15;
if (xx < 0 || xx > 31 || zz < 0 || zz > 31) {
return;
}
p.add(new Position2(xx, zz));
}).drain();
p.sort(Comparator.comparing((i) -> i.distance(center)));
return p;
} }
public void iterateRegions(Spiraled s) { public void iterateChunks(int rX, int rZ, Spiraled s) {
new Spiraler(getWidth() * 2, getHeight() * 2, s) var bound = bounds.chunk();
.setOffset(center.getX(), center.getZ()).drain(); iterateRegion(rX, rZ, ((x, z) -> {
if (bound.check(x, z)) s.on(x, z);
}));
} }
public void iterateAllChunks(Spiraled s) { public void iterateAllChunks(Spiraled s) {
new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s)) iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s)));
.setOffset(center.getX(), center.getZ()).drain(); }
private class Bounds {
private Bound chunk = null;
private Bound region = null;
public void update() {
int maxX = center.getX() + radiusX;
int maxZ = center.getZ() + radiusZ;
int minX = center.getX() - radiusX;
int minZ = center.getZ() - radiusZ;
chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16));
region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512));
}
public Bound chunk() {
if (chunk == null) update();
return chunk;
}
public Bound region() {
if (region == null) update();
return region;
}
}
private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) {
private Bound(int minX, int minZ, int maxX, int maxZ) {
this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1);
}
boolean check(int x, int z) {
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
}
}
private static class ProxiedPos extends Position2 {
public ProxiedPos(Position2 p) {
super(p.getX(), p.getZ());
}
@Override
public void setX(int x) {
throw new IllegalStateException("This Position2 may not be modified");
}
@Override
public void setZ(int z) {
throw new IllegalStateException("This Position2 may not be modified");
}
} }
} }

View File

@ -146,8 +146,8 @@ public class IrisPackBenchmarking {
IrisToolbelt.pregenerate(PregenTask IrisToolbelt.pregenerate(PregenTask
.builder() .builder()
.gui(gui) .gui(gui)
.width(radius) .radiusX(radius)
.height(radius) .radiusZ(radius)
.build(), Bukkit.getWorld("benchmark") .build(), Bukkit.getWorld("benchmark")
); );
} }