This commit is contained in:
BuildTools 2020-12-16 13:08:28 +01:00
commit 2f29953ccb
15 changed files with 160 additions and 76 deletions

View File

@ -1,2 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4" /> <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="EclipseModuleManager">
<conelement value="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER" />
<src_description expected_position="2">
<src_folder value="file://$MODULE_DIR$/src/main/java" expected_position="0" />
<src_folder value="file://$MODULE_DIR$/src/main/resources" expected_position="1" />
<src_folder value="file://$MODULE_DIR$/src/test/java" expected_position="4" />
</src_description>
</component>
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/target/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="JavaSE-1.8" jdkType="JavaSDK" />
<orderEntry type="library" name="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER" level="application" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,3 +1,3 @@
@echo off @echo off
cd gource cd gource
gource -f -a 1 -s 0.5 --colour-images --max-file-lag 10 --title MyGuide --user-scale 1.67 --max-user-speed 725 --filename-time 2 gource -f -a 1 -s 0.01 -t 100000 --colour-images --max-file-lag 35 --title MyGuide --user-scale 1.67 --max-user-speed 725 --filename-time 2 -title Chimera --user-friction 2.5 --padding 1.2 --user-scale 1.25 --filename-time 2 --bloom-intensity 0.1 --bloom-multiplier 3 --hide filenames,dirnames

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.volmit</groupId> <groupId>com.volmit</groupId>
<artifactId>Iris</artifactId> <artifactId>Iris</artifactId>
<version>1.1.5</version> <version>1.1.6</version>
<name>Iris</name> <name>Iris</name>
<properties> <properties>
<skip.copy>false</skip.copy> <skip.copy>false</skip.copy>

View File

@ -34,7 +34,7 @@ public class IrisSettings
public String defaultWorldType = "overworld"; public String defaultWorldType = "overworld";
@DontObfuscate @DontObfuscate
public int maxAsyncChunkPregenThreads = 32; public int maxAsyncChunkPregenThreads = 128;
@DontObfuscate @DontObfuscate
public boolean maximumPregenGuiFPS = false; public boolean maximumPregenGuiFPS = false;

View File

@ -1,10 +1,10 @@
package com.volmit.iris.generator; package com.volmit.iris.generator;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.scaffold.engine.*; import com.volmit.iris.scaffold.engine.*;
import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.J; import com.volmit.iris.util.J;
import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
@ -52,7 +52,6 @@ public class IrisEngine extends BlockPopulator implements Engine
private volatile int minHeight; private volatile int minHeight;
private int permits; private int permits;
private boolean failing; private boolean failing;
private ChronoLatch cl = new ChronoLatch(10000);
private boolean closed; private boolean closed;
private int cacheId; private int cacheId;
private Semaphore s; private Semaphore s;
@ -62,7 +61,7 @@ public class IrisEngine extends BlockPopulator implements Engine
{ {
Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)");
metrics = new EngineMetrics(32); metrics = new EngineMetrics(32);
permits = 1000; permits = 10000;
this.s = new Semaphore(permits); this.s = new Semaphore(permits);
this.target = target; this.target = target;
this.framework = new IrisEngineFramework(this); this.framework = new IrisEngineFramework(this);
@ -110,36 +109,49 @@ public class IrisEngine extends BlockPopulator implements Engine
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<BlockData> postblocks, Hunk<Biome> vbiomes) { public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<BlockData> postblocks, Hunk<Biome> vbiomes) {
try try
{ {
boolean multicore = !IrisSettings.get().isUseGleamPregenerator(); //TODO: LATER
s.acquire(1); s.acquire(1);
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
Hunk<Biome> biomes = vbiomes; Hunk<Biome> biomes = vbiomes;
Hunk<BlockData> blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); Hunk<BlockData> blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t));
Hunk<BlockData> pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); Hunk<BlockData> pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t));
Hunk<BlockData> fringe = Hunk.fringe(blocks, pblocks); Hunk<BlockData> fringe = Hunk.fringe(blocks, pblocks);
if(multicore)
{
MultiBurst.burst.burst(
() -> getFramework().getEngineParallax().generateParallaxArea(x, z),
() -> getFramework().getBiomeActuator().actuate(x, z, biomes),
() -> getFramework().getTerrainActuator().actuate(x, z, blocks)
);
MultiBurst.burst.burst(
() -> getFramework().getCaveModifier().modify(x, z, blocks),
() -> getFramework().getRavineModifier().modify(x, z, blocks),
() -> getFramework().getPostModifier().modify(x, z, blocks),
() -> getFramework().getDecorantActuator().actuate(x, z, fringe),
() -> getFramework().getEngineParallax().insertParallax(x, z, fringe)
);
}
else
{
getFramework().getEngineParallax().generateParallaxArea(x, z); getFramework().getEngineParallax().generateParallaxArea(x, z);
getFramework().getBiomeActuator().actuate(x, z, biomes); getFramework().getBiomeActuator().actuate(x, z, biomes);
getFramework().getTerrainActuator().actuate(x, z, blocks); getFramework().getTerrainActuator().actuate(x, z, blocks);
getFramework().getCaveModifier().modify(x, z, blocks); getFramework().getCaveModifier().modify(x, z, blocks);
getFramework().getRavineModifier().modify(x, z, blocks); getFramework().getRavineModifier().modify(x, z, blocks);
getFramework().getDepositModifier().modify(x, z, blocks);
getFramework().getPostModifier().modify(x, z, blocks); getFramework().getPostModifier().modify(x, z, blocks);
getFramework().getDecorantActuator().actuate(x, z, fringe); getFramework().getDecorantActuator().actuate(x, z, fringe);
getFramework().getEngineParallax().insertParallax(x, z, fringe); getFramework().getEngineParallax().insertParallax(x, z, fringe);
}
getFramework().getDepositModifier().modify(x, z, blocks);
getMetrics().getTotal().put(p.getMilliseconds()); getMetrics().getTotal().put(p.getMilliseconds());
s.release(1); s.release(1);
if(cl.flip())
{
MultiBurst.burst.lazy(() -> {
try {
s.acquire(permits);
getFramework().recycle(); getFramework().recycle();
s.release(permits);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
} }
catch(Throwable e) catch(Throwable e)

View File

@ -1,15 +1,22 @@
package com.volmit.iris.generator; package com.volmit.iris.generator;
import com.volmit.iris.generator.actuator.*; import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.generator.actuator.IrisBiomeActuator;
import com.volmit.iris.generator.actuator.IrisDecorantActuator;
import com.volmit.iris.generator.actuator.IrisTerrainActuator;
import com.volmit.iris.generator.modifier.IrisCaveModifier; import com.volmit.iris.generator.modifier.IrisCaveModifier;
import com.volmit.iris.generator.modifier.IrisDepositModifier; import com.volmit.iris.generator.modifier.IrisDepositModifier;
import com.volmit.iris.generator.modifier.IrisPostModifier; import com.volmit.iris.generator.modifier.IrisPostModifier;
import com.volmit.iris.generator.modifier.IrisRavineModifier; import com.volmit.iris.generator.modifier.IrisRavineModifier;
import com.volmit.iris.scaffold.engine.*; import com.volmit.iris.scaffold.engine.*;
import com.volmit.iris.util.ChronoLatch;
import lombok.Getter; import lombok.Getter;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import java.util.concurrent.atomic.AtomicBoolean;
public class IrisEngineFramework implements EngineFramework { public class IrisEngineFramework implements EngineFramework {
@Getter @Getter
@ -42,6 +49,9 @@ public class IrisEngineFramework implements EngineFramework {
@Getter @Getter
private final EngineModifier<BlockData> postModifier; private final EngineModifier<BlockData> postModifier;
private final AtomicBoolean cleaning;
private final ChronoLatch cleanLatch;
public IrisEngineFramework(Engine engine) public IrisEngineFramework(Engine engine)
{ {
this.engine = engine; this.engine = engine;
@ -54,6 +64,38 @@ public class IrisEngineFramework implements EngineFramework {
this.ravineModifier = new IrisRavineModifier(getEngine()); this.ravineModifier = new IrisRavineModifier(getEngine());
this.caveModifier = new IrisCaveModifier(engine); this.caveModifier = new IrisCaveModifier(engine);
this.postModifier = new IrisPostModifier(engine); this.postModifier = new IrisPostModifier(engine);
cleaning = new AtomicBoolean(false);
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().parallaxChunkEvictionMS, IrisSettings.get().parallaxRegionEvictionMS)));
}
@Override
public synchronized void recycle() {
if(!cleanLatch.flip())
{
return;
}
if (cleaning.get())
{
cleanLatch.flipDown();
return;
}
cleaning.set(true);
try
{
getEngine().getParallax().cleanup();
getData().getObjectLoader().clean();
}
catch(Throwable e)
{
Iris.error("Cleanup failed!");
e.printStackTrace();
}
cleaning.lazySet(false);
} }
@Override @Override

View File

@ -3,6 +3,8 @@ package com.volmit.iris.generator.decorator;
import com.volmit.iris.object.DecorationPart; import com.volmit.iris.object.DecorationPart;
import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisDecorator; import com.volmit.iris.object.IrisDecorator;
import com.volmit.iris.scaffold.cache.Cache;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.Engine;
import com.volmit.iris.scaffold.engine.EngineAssignedComponent; import com.volmit.iris.scaffold.engine.EngineAssignedComponent;
@ -25,15 +27,19 @@ public abstract class IrisEngineDecorator extends EngineAssignedComponent implem
protected IrisDecorator getDecorator(IrisBiome biome, double realX, double realZ) protected IrisDecorator getDecorator(IrisBiome biome, double realX, double realZ)
{ {
KList<IrisDecorator> v = new KList<>();
RNG rng = new RNG(Cache.key((int)realX, (int)realZ));
for(IrisDecorator i : biome.getDecorators()) for(IrisDecorator i : biome.getDecorators())
{ {
if(i.getPartOf().equals(part)) if(i.getPartOf().equals(part) && i.getBlockData(biome, this.rng, realX, realZ, getData()) != null)
{ {
if(i.getBlockData(biome, rng, realX, realZ, getData()) != null) v.add(i);
{
return i;
} }
} }
if(v.isNotEmpty()) {
return v.get(rng.nextInt(v.size()));
} }
return null; return null;

View File

@ -70,6 +70,14 @@ public class IrisWorldCreator
{ {
return World.Environment.NORMAL; return World.Environment.NORMAL;
} }
else if(dimensionName == "NETHER")
{
return World.Environment.NETHER;
}
else if(dimensionName == "END")
{
return World.Environment.THE_END;
}
IrisDimension dim = IrisDataManager.loadAnyDimension(dimensionName); IrisDimension dim = IrisDataManager.loadAnyDimension(dimensionName);

View File

@ -614,14 +614,16 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
@Override @Override
public void close() { public void close() {
J.car(art); J.car(art);
if (getComposite() != null) {
getComposite().close(); getComposite().close();
if(isStudio())
{ if (isStudio()) {
IrisWorlds.evacuate(getComposite().getWorld()); IrisWorlds.evacuate(getComposite().getWorld());
Bukkit.unloadWorld(getComposite().getWorld(), !isStudio()); Bukkit.unloadWorld(getComposite().getWorld(), !isStudio());
} }
} }
}
@Override @Override
public boolean isClosed() { public boolean isClosed() {

View File

@ -3,7 +3,6 @@ package com.volmit.iris.scaffold.engine;
import com.volmit.iris.generator.IrisComplex; import com.volmit.iris.generator.IrisComplex;
import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.scaffold.data.DataProvider;
import com.volmit.iris.util.M;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -20,17 +19,10 @@ public interface EngineFramework extends DataProvider
} }
default void recycle() default void recycle()
{
if(M.r(0.1))
{
synchronized (getEngine().getParallax())
{ {
getEngine().getParallax().cleanup(); getEngine().getParallax().cleanup();
}
getData().getObjectLoader().clean(); getData().getObjectLoader().clean();
} }
}
public EngineActuator<BlockData> getTerrainActuator(); public EngineActuator<BlockData> getTerrainActuator();

View File

@ -9,9 +9,9 @@ import java.io.IOException;
public class HunkRegionSlice<T> public class HunkRegionSlice<T>
{ {
public static final Function2<Integer, CompoundTag, HunkRegionSlice<BlockData>> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BlockDataHunkIOAdapter(), c, "blockdata"); public static final Function2<Integer, CompoundTag, HunkRegionSlice<BlockData>> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new BlockDataHunkIOAdapter(), c, "blockdata");
public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<String>> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new StringHunkIOAdapter(), c, t); public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<String>> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new StringHunkIOAdapter(), c, t);
public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<Boolean>> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BooleanHunkIOAdapter(), c, t); public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<Boolean>> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new BooleanHunkIOAdapter(), c, t);
private final Function3<Integer, Integer, Integer, Hunk<T>> factory; private final Function3<Integer, Integer, Integer, Hunk<T>> factory;
private final HunkIOAdapter<T> adapter; private final HunkIOAdapter<T> adapter;
private final CompoundTag compound; private final CompoundTag compound;

View File

@ -66,15 +66,19 @@ public abstract class PaletteHunkIOAdapter<T> implements HunkIOAdapter<T> {
int x = din.readShort() - Short.MIN_VALUE; int x = din.readShort() - Short.MIN_VALUE;
int y = din.readShort() - Short.MIN_VALUE; int y = din.readShort() - Short.MIN_VALUE;
int z = din.readShort() - Short.MIN_VALUE; int z = din.readShort() - Short.MIN_VALUE;
T v = palette.getPalette().get(din.readShort() - Short.MIN_VALUE); int vf = din.readShort() - Short.MIN_VALUE;
if(v == null) T v = null;
if( palette.getPalette().hasIndex(vf))
{ {
throw new IOException("NULL VALUE AT " + x + " " + y + " " + z); v = palette.getPalette().get(vf);
} }
if(v != null)
{
t.setRaw(x,y,z, v); t.setRaw(x,y,z, v);
} }
}
in.close(); in.close();
return t; return t;

View File

@ -90,7 +90,7 @@ public class ParallaxRegion extends HunkRegion
return getMetaHunkR(); return getMetaHunkR();
} }
public synchronized Hunk<ParallaxChunkMeta> loadMetaHunk() public Hunk<ParallaxChunkMeta> loadMetaHunk()
{ {
lastUse = M.ms(); lastUse = M.ms();
if(meta == null) if(meta == null)
@ -115,7 +115,7 @@ public class ParallaxRegion extends HunkRegion
return meta; return meta;
} }
public synchronized void unloadMetaHunk() public void unloadMetaHunk()
{ {
if(dirtyMeta) if(dirtyMeta)
{ {
@ -126,7 +126,7 @@ public class ParallaxRegion extends HunkRegion
meta = null; meta = null;
} }
public synchronized void saveMetaHunk() public void saveMetaHunk()
{ {
if(meta != null && dirtyMeta) if(meta != null && dirtyMeta)
{ {

View File

@ -54,7 +54,7 @@ public class ParallaxWorld implements ParallaxAccess
return m; return m;
} }
public synchronized void close() public void close()
{ {
for(ParallaxRegion i : loadedRegions.v()) for(ParallaxRegion i : loadedRegions.v())
{ {
@ -65,7 +65,7 @@ public class ParallaxWorld implements ParallaxAccess
loadedRegions.clear(); loadedRegions.clear();
} }
public synchronized void save(ParallaxRegion region) public void save(ParallaxRegion region)
{ {
try try
{ {
@ -83,7 +83,7 @@ public class ParallaxWorld implements ParallaxAccess
return loadedRegions.containsKey(key(x, z)); return loadedRegions.containsKey(key(x, z));
} }
public synchronized void save(int x, int z) public void save(int x, int z)
{ {
if(isLoaded(x, z)) if(isLoaded(x, z))
{ {
@ -91,7 +91,7 @@ public class ParallaxWorld implements ParallaxAccess
} }
} }
public synchronized void unload(int x, int z) public void unload(int x, int z)
{ {
long key = key(x, z); long key = key(x, z);
@ -107,7 +107,7 @@ public class ParallaxWorld implements ParallaxAccess
} }
} }
public synchronized ParallaxRegion load(int x, int z) public ParallaxRegion load(int x, int z)
{ {
if(isLoaded(x, z)) if(isLoaded(x, z))
{ {
@ -157,7 +157,7 @@ public class ParallaxWorld implements ParallaxAccess
} }
@Override @Override
public synchronized Hunk<BlockData> getBlocksRW(int x, int z) public Hunk<BlockData> getBlocksRW(int x, int z)
{ {
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31); return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
} }
@ -169,7 +169,7 @@ public class ParallaxWorld implements ParallaxAccess
} }
@Override @Override
public synchronized Hunk<String> getObjectsRW(int x, int z) public Hunk<String> getObjectsRW(int x, int z)
{ {
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31); return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
} }
@ -181,7 +181,7 @@ public class ParallaxWorld implements ParallaxAccess
} }
@Override @Override
public synchronized Hunk<Boolean> getUpdatesRW(int x, int z) public Hunk<Boolean> getUpdatesRW(int x, int z)
{ {
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31); return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
} }
@ -227,10 +227,8 @@ public class ParallaxWorld implements ParallaxAccess
} }
@Override @Override
public synchronized void saveAllNOW() { public void saveAllNOW() {
for(ParallaxRegion i : loadedRegions.v()) for(ParallaxRegion i : loadedRegions.v())
{
synchronized (save)
{ {
if(save.contains(key(i.getX(), i.getZ()))) if(save.contains(key(i.getX(), i.getZ())))
{ {
@ -238,5 +236,4 @@ public class ParallaxWorld implements ParallaxAccess
} }
} }
} }
}
} }

View File

@ -52,7 +52,7 @@ public class PregenJob implements Listener
private double cps = 0; private double cps = 0;
private int lg = 0; private int lg = 0;
private long lt = M.ms(); private long lt = M.ms();
private int cubeSize = IrisSettings.get().isUseGleamPregenerator() ? 11 : 32; private int cubeSize = (IrisSettings.get().isUseGleamPregenerator() && PaperLib.isPaper()) ? 11 : 32;
private long nogen = M.ms(); private long nogen = M.ms();
private KList<ChunkPosition> requeueMCA = new KList<ChunkPosition>(); private KList<ChunkPosition> requeueMCA = new KList<ChunkPosition>();
private RollingSequence acps = new RollingSequence(PaperLib.isPaper() ? 8 : 32); private RollingSequence acps = new RollingSequence(PaperLib.isPaper() ? 8 : 32);
@ -65,7 +65,7 @@ public class PregenJob implements Listener
public PregenJob(World world, int size, MortarSender sender, Runnable onDone) public PregenJob(World world, int size, MortarSender sender, Runnable onDone)
{ {
gleaming = IrisSettings.get().isUseGleamPregenerator(); gleaming = (IrisSettings.get().isUseGleamPregenerator() && PaperLib.isPaper());
g.set(0); g.set(0);
burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc()); burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc());
instance = this; instance = this;
@ -431,7 +431,7 @@ public class PregenJob implements Listener
consumer.accept(new ChunkPosition(cx, cz), Color.magenta); consumer.accept(new ChunkPosition(cx, cz), Color.magenta);
} }
Chunk chunk = PaperLib.getChunkAtAsync(world, cx, cz, true).join(); Chunk chunk = PaperLib.getChunkAtAsync(world, cx, cz, true, true).join();
working.release(); working.release();
genned++; genned++;
nogen = M.ms(); nogen = M.ms();