ExperWorldGen: Added perf logger

set ENABLE_PERF_LOGGING at WorldGenerationStep to true to enable it
This commit is contained in:
tom lee
2021-12-24 23:44:00 +08:00
parent 3521af9792
commit c721c14e27
@@ -19,13 +19,13 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.LodDimension;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
@@ -33,7 +33,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -47,24 +46,22 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.blending.Blender;
@@ -73,20 +70,120 @@ import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.storage.WorldData;
/*
Total: 3.135214124s
=====================================
Empty Chunks: 0.000558328s
StructureStart Step: 0.025177207s
StructureReference Step: 0.00189559s
Biome Step: 0.13789155s
Noise Step: 1.570347555s
Surface Step: 0.741238194s
Carver Step: 0.000009923s
Feature Step: 0.389072425s
Lod Generation: 0.269023348s
*/
public final class WorldGenerationStep {
public static final boolean ENABLE_PERF_LOGGING = false;
public static class Rolling {
private int size;
private double total = 0d;
private int index = 0;
private double samples[];
public Rolling(int size) {
this.size = size;
samples = new double[size];
for (int i = 0; i < size; i++)
samples[i] = 0d;
}
public void add(double x) {
total -= samples[index];
samples[index] = x;
total += x;
if (++index == size)
index = 0; // cheaper than modulus
}
public double getAverage() {
return total / size;
}
}
public static class PrefEvent {
long beginNano = 0;
long emptyNano = 0;
long structStartNano = 0;
long structRefNano = 0;
long biomeNano = 0;
long noiseNano = 0;
long surfaceNano = 0;
long carverNano = 0;
long featureNano = 0;
long endNano = 0;
}
public static class PerfCalculator {
public static final int SIZE = 50;
Rolling totalTime = new Rolling(SIZE);
Rolling emptyTime = new Rolling(SIZE);
Rolling structStartTime = new Rolling(SIZE);
Rolling structRefTime = new Rolling(SIZE);
Rolling biomeTime = new Rolling(SIZE);
Rolling noiseTime = new Rolling(SIZE);
Rolling surfaceTime = new Rolling(SIZE);
Rolling carverTime = new Rolling(SIZE);
Rolling featureTime = new Rolling(SIZE);
Rolling lodTime = new Rolling(SIZE);
public void recordEvent(PrefEvent e) {
totalTime.add(e.endNano - e.beginNano);
emptyTime.add(e.emptyNano - e.beginNano);
structStartTime.add(e.structStartNano - e.emptyNano);
structRefTime.add(e.structRefNano - e.structStartNano);
biomeTime.add(e.biomeNano - e.structRefNano);
noiseTime.add(e.noiseNano - e.biomeNano);
surfaceTime.add(e.surfaceNano - e.noiseNano);
carverTime.add(e.carverNano - e.surfaceNano);
featureTime.add(e.featureNano - e.carverNano);
lodTime.add(e.endNano - e.featureNano);
}
public String toString() {
return "Total: " + Duration.ofNanos((long) totalTime.getAverage()) + ", Empty: "
+ Duration.ofNanos((long) emptyTime.getAverage()) + ", StructStart: "
+ Duration.ofNanos((long) structStartTime.getAverage()) + ", StructRef: "
+ Duration.ofNanos((long) structRefTime.getAverage()) + ", Biome: "
+ Duration.ofNanos((long) biomeTime.getAverage()) + ", Noise: "
+ Duration.ofNanos((long) noiseTime.getAverage()) + ", Surface: "
+ Duration.ofNanos((long) surfaceTime.getAverage()) + ", Carver: "
+ Duration.ofNanos((long) carverTime.getAverage()) + ", Feature: "
+ Duration.ofNanos((long) featureTime.getAverage()) + ", Lod: "
+ Duration.ofNanos((long) lodTime.getAverage());
}
}
public static final int TIMEOUT_SECONDS = 30;
enum Steps {
Empty, StructureStart, StructureReference, Biomes, Noise, Surface, Carvers, LiquidCarvers, Features, Light,
}
public static final class GridList<T> extends ArrayList<T> implements List<T> {
public static class Pos {
public int x;
public int y;
public Pos(int xx, int yy) {x=xx;y=yy;}
public Pos(int xx, int yy) {
x = xx;
y = yy;
}
}
private static final long serialVersionUID = 1585978374811888116L;
@@ -102,36 +199,38 @@ public final class WorldGenerationStep {
public final T getOffsetOf(int index, int x, int y) {
return get(index + x + y * gridSize);
}
public final int offsetOf(int index, int x, int y) {
return index + x + y * gridSize;
}
public final Pos posOf(int index) {
return new Pos(index%gridSize, index/gridSize);
return new Pos(index % gridSize, index / gridSize);
}
public final int calculateOffset(int x, int y) {
return x + y * gridSize;
}
public GridList<T> subGrid(int gridCentreToEdge) {
int centreIndex = size()/2;
public final GridList<T> subGrid(int gridCentreToEdge) {
int centreIndex = size() / 2;
GridList<T> subGrid = new GridList<T>(gridCentreToEdge);
for (int oy = -gridCentreToEdge; oy <= gridCentreToEdge; oy++) {
int begin = offsetOf(centreIndex, -gridCentreToEdge, oy);
int end = offsetOf(centreIndex, gridCentreToEdge, oy);
subGrid.addAll(this.subList(begin, end+1));
subGrid.addAll(this.subList(begin, end + 1));
}
//System.out.println("========================================\n"+
//this.toDetailString() + "\nTOOOOOOOOOOOOO\n"+subGrid.toDetailString()+
//"==========================================\n");
// System.out.println("========================================\n"+
// this.toDetailString() + "\nTOOOOOOOOOOOOO\n"+subGrid.toDetailString()+
// "==========================================\n");
return subGrid;
}
@Override
public String toString() {
return "GridList "+gridSize+"*"+gridSize+"["+size()+"]";
return "GridList " + gridSize + "*" + gridSize + "[" + size() + "]";
}
public String toDetailString() {
StringBuilder str = new StringBuilder("\n");
int i = 0;
@@ -139,14 +238,14 @@ public final class WorldGenerationStep {
str.append(t.toString());
str.append(", ");
i++;
if (i%gridSize == 0) {
if (i % gridSize == 0) {
str.append("\n");
}
}
return str.toString();
}
}
public static final class GlobalParameters {
final ChunkGenerator generator;
final StructureManager structures;
@@ -155,16 +254,17 @@ public final class WorldGenerationStep {
final ThreadedLevelLightEngine lightEngine;
final LodBuilder lodBuilder;
final LodDimension lodDim;
final Registry<Biome> biomes;
final Registry<Biome> biomes;
final RegistryAccess registry;
final long worldSeed;
final ChunkScanAccess chunkScanner;
final ServerLevel level; //TODO: Figure out a way to remove this. Maybe ClientLevel also works?
final ServerLevel level; // TODO: Figure out a way to remove this. Maybe ClientLevel also works?
final DataFixer fixerUpper;
public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) {
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
this.level = level;
public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) {
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
this.level = level;
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
MinecraftServer server = level.getServer();
WorldData worldData = server.getWorldData();
@@ -177,29 +277,32 @@ public final class WorldGenerationStep {
generator = level.getChunkSource().getGenerator();
chunkScanner = level.getChunkSource().chunkScanner();
fixerUpper = server.getFixerUpper();
}
}
}
public static final class ThreadedParameters {
private static ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
final ServerLevel level;
final StructureFeatureManager structFeat;
final StructureCheck structCheck;
public final PerfCalculator perf = new PerfCalculator();
public static final ThreadedParameters getOrMake(GlobalParameters param) {
ThreadedParameters tParam = localParam.get();
if (tParam != null && tParam.level == param.level) return tParam;
if (tParam != null && tParam.level == param.level)
return tParam;
tParam = new ThreadedParameters(param);
localParam.set(tParam);
return tParam;
}
private ThreadedParameters(GlobalParameters param) {
level = param.level;
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed, param.fixerUpper);
structFeat = new StructureFeatureManager(level, param.worldGenSettings, structCheck);
}
private ThreadedParameters(GlobalParameters param) {
level = param.level;
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed,
param.fixerUpper);
structFeat = new StructureFeatureManager(level, param.worldGenSettings, structCheck);
}
}
public static final class GenerationEvent {
@@ -211,7 +314,8 @@ public final class WorldGenerationStep {
long nanotime;
final int id;
final Steps target;
final PrefEvent pEvent = new PrefEvent();
public GenerationEvent(ChunkPos pos, int range, WorldGenerationStep generationGroup, Steps target) {
nanotime = System.nanoTime();
this.pos = pos;
@@ -221,19 +325,23 @@ public final class WorldGenerationStep {
this.tParam = ThreadedParameters.getOrMake(generationGroup.params);
future = generationGroup.executors.submit(() -> {
generationGroup.generateLodFromList(this);
});
});
}
public final boolean isCompleted() {
return future.isDone();
}
public final boolean hasTimeout(int duration, TimeUnit unit) {
long currentTime = System.nanoTime();
long delta = currentTime - nanotime;
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
}
public final void terminate() {
future.cancel(true);
}
public final void join() {
try {
future.get();
@@ -241,25 +349,26 @@ public final class WorldGenerationStep {
e.printStackTrace();
}
}
public final boolean tooClose(int cx, int cz, int cr) {
int dist = Math.min(Math.abs(cx - pos.x), Math.abs(cz - pos.z));
return dist<range+cr;
return dist < range + cr;
}
public final void refreshTimeout() {
nanotime = System.nanoTime();
}
@Override
public String toString() {
return id + ":"+ range + "@"+ pos+"("+target+")";
return id + ":" + range + "@" + pos + "(" + target + ")";
}
}
private final static <T> T joinAsync(CompletableFuture<T> f) {
//while (!f.isDone()) Thread.yield();
return f.join();
}
final LinkedList<GenerationEvent> events = new LinkedList<GenerationEvent>();
final GlobalParameters params;
final StepStructureStart stepStructureStart = new StepStructureStart();
@@ -268,26 +377,25 @@ public final class WorldGenerationStep {
final StepNoise stepNoise = new StepNoise();
final StepSurface stepSurface = new StepSurface();
final StepCarvers stepCarvers = new StepCarvers();
final StepLiquidCarvers stepLiquidCarvers = new StepLiquidCarvers();
final StepFeatures stepFeatures = new StepFeatures();
//public ExecutorService executors = Executors.newWorkStealingPool();
public final ExecutorService executors = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
//public ExecutorService executors = Executors.newFixedThreadPool(8, new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
public final ExecutorService executors = Executors
.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
public final boolean tryAddPoint(int px, int pz, int range, Steps target) {
int boxSize = range*2+1;
int boxSize = range * 2 + 1;
int x = Math.floorDiv(px, boxSize) * boxSize + range;
int z = Math.floorDiv(pz, boxSize) * boxSize + range;
for (GenerationEvent event : events) {
if (event.tooClose(x, z, range)) return false;
if (event.tooClose(x, z, range))
return false;
}
//System.out.println(x + ", "+z);
events.add(new GenerationEvent(new ChunkPos(x,z), range, this, target));
// System.out.println(x + ", "+z);
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target));
return true;
}
public final void updateAllFutures() {
// Update all current out standing jobs
Iterator<GenerationEvent> iter = events.iterator();
@@ -302,7 +410,7 @@ public final class WorldGenerationStep {
iter.remove();
}
} else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
System.err.println(event.id+": Timed out and terminated!");
System.err.println(event.id + ": Timed out and terminated!");
try {
event.terminate();
} finally {
@@ -311,163 +419,152 @@ public final class WorldGenerationStep {
}
}
}
public WorldGenerationStep(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) {
System.out.println("================WORLD_GEN_STEP_INITING=============");
params = new GlobalParameters(level, lodBuilder, lodDim);
}
//ConcurrentHashMap<Long, ChunkAccess> chunks = new ConcurrentHashMap<Long, ChunkAccess>();
// No longer using Long2ObjectLinkedOpenHashMap as I doubt it is multithread
// safe.
/*
private final ChunkAccess getCachedChunk(ChunkPos pos) {
ChunkAccess chunk = chunks.get(pos.toLong());
if (chunk != null)
return chunk;
chunk = new ProtoChunk(pos, UpgradeData.EMPTY, params.level, params.biomes, null);
ChunkAccess oldVal = chunks.putIfAbsent(pos.toLong(), chunk);
if (oldVal != null)
return oldVal;
return chunk;
}*/
public final void generateLodFromList(GenerationEvent event) {
try {
//System.out.println("Started event: "+event);
Instant start = Instant.now();
GridList<ChunkAccess> referencedChunks;
DistanceGenerationMode generationMode;
referencedChunks = generateDirect(event, event.range, event.target);
switch (event.target) {
case Empty:
return;
case StructureStart:
generationMode = DistanceGenerationMode.NONE;
break;
case StructureReference:
generationMode = DistanceGenerationMode.NONE;
break;
case Biomes:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Noise:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Surface:
generationMode = DistanceGenerationMode.SURFACE;
break;
case Carvers:
generationMode = DistanceGenerationMode.SURFACE;
break;
case Features:
generationMode = DistanceGenerationMode.FEATURES;
break;
case LiquidCarvers:
return;
case Light:
return;
default:
return;
}
int centreIndex = referencedChunks.size() / 2;
// System.out.println("Started event: "+event);
event.pEvent.beginNano = System.nanoTime();
GridList<ChunkAccess> referencedChunks;
DistanceGenerationMode generationMode;
referencedChunks = generateDirect(event, event.range, event.target);
//System.out.println("Lod Generate Event: "+event);
for (int oy = -event.range; oy <= event.range; oy++) {
for (int ox = -event.range; ox <= event.range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkAccess target = referencedChunks.get(targetIndex);
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target), new LodBuilderConfig(generationMode));
switch (event.target) {
case Empty:
return;
case StructureStart:
generationMode = DistanceGenerationMode.NONE;
break;
case StructureReference:
generationMode = DistanceGenerationMode.NONE;
break;
case Biomes:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Noise:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Surface:
generationMode = DistanceGenerationMode.SURFACE;
break;
case Carvers:
generationMode = DistanceGenerationMode.SURFACE;
break;
case Features:
generationMode = DistanceGenerationMode.FEATURES;
break;
case LiquidCarvers:
return;
case Light:
return;
default:
return;
}
int centreIndex = referencedChunks.size() / 2;
// System.out.println("Lod Generate Event: "+event);
for (int oy = -event.range; oy <= event.range; oy++) {
for (int ox = -event.range; ox <= event.range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkAccess target = referencedChunks.get(targetIndex);
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target),
new LodBuilderConfig(generationMode));
}
}
event.pEvent.endNano = System.nanoTime();
event.refreshTimeout();
if (ENABLE_PERF_LOGGING) {
event.tParam.perf.recordEvent(event.pEvent);
ClientApi.LOGGER.info(event.tParam.perf);
}
}
event.refreshTimeout();
//for (ChunkAccess sync : referencedChunks) {
// chunks.remove(sync.getPos().toLong());
//}
Instant finish = Instant.now();
Duration timeElapsed = Duration.between(start, finish);
System.out.println("Ended event: "+event + "("+timeElapsed+")");
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
}
}
}
public final GridList<ChunkAccess> generateDirect(GenerationEvent e, int range, Steps step) {
int cx = e.pos.x;
int cy = e.pos.z;
int rangeEmpty = range+3;
if (rangeEmpty < 7) rangeEmpty = 7; // For some reason the Blender needs at least range 7???
int rangeEmpty = range + 3;
if (rangeEmpty < 7)
rangeEmpty = 7; // For some reason the Blender needs at least range 7???
GridList<ChunkAccess> chunks = new GridList<ChunkAccess>(rangeEmpty);
for (int oy = -rangeEmpty; oy <= rangeEmpty; oy++) {
for (int ox = -rangeEmpty; ox <= rangeEmpty; ox++) {
//ChunkAccess target = getCachedChunk(new ChunkPos(cx+ox, cy+oy));
ChunkAccess target = new ProtoChunk(new ChunkPos(cx+ox, cy+oy), UpgradeData.EMPTY, params.level, params.biomes, null);
// ChunkAccess target = getCachedChunk(new ChunkPos(cx+ox, cy+oy));
ChunkAccess target = new ProtoChunk(new ChunkPos(cx + ox, cy + oy), UpgradeData.EMPTY, params.level,
params.biomes, null);
chunks.add(target);
}
}
e.pEvent.emptyNano = System.nanoTime();
e.refreshTimeout();
WorldGenRegion region = new WorldGenRegion(params.level, chunks, ChunkStatus.STRUCTURE_STARTS, range+1);
WorldGenRegion region = new WorldGenRegion(params.level, chunks, ChunkStatus.STRUCTURE_STARTS, range + 1);
GridList<ChunkAccess> subRange = chunks.subGrid(range);
stepStructureStart.generateGroup(e.tParam, region, subRange);
e.pEvent.structStartNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureStart) return subRange;
if (step == Steps.StructureStart)
return subRange;
stepStructureReference.generateGroup(e.tParam, region, subRange);
e.pEvent.structRefNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureReference) return subRange;
if (step == Steps.StructureReference)
return subRange;
stepBiomes.generateGroup(e.tParam, region, subRange);
e.pEvent.biomeNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Biomes) return subRange;
if (step == Steps.Biomes)
return subRange;
stepNoise.generateGroup(e.tParam, region, subRange);
e.pEvent.noiseNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Noise) return subRange;
if (step == Steps.Noise)
return subRange;
stepSurface.generateGroup(e.tParam, region, subRange);
e.pEvent.surfaceNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Surface) return subRange;
if (step == Steps.Surface)
return subRange;
stepCarvers.generateGroup(e.tParam, region, subRange);
e.pEvent.carverNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Carvers) return subRange;
if (step == Steps.Carvers)
return subRange;
stepFeatures.generateGroup(e.tParam, region, subRange);
e.pEvent.featureNano = System.nanoTime();
e.refreshTimeout();
return subRange;
}
public final class StepStructureStart {
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
// Note: Not certain StructureFeatureManager.forWorldGenRegion(...) is thread safe
for (ChunkAccess chunk : chunks) {
if (params.worldGenSettings.generateFeatures()) {
//System.out.println("StepStructureStart: "+chunk.getPos());
// Should be thread safe
params.generator.createStructures(params.registry, tParams.structFeat, chunk, params.structures, params.worldSeed);
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
if (params.worldGenSettings.generateFeatures()) {
for (ChunkAccess chunk : chunks) {
// System.out.println("StepStructureStart: "+chunk.getPos());
params.generator.createStructures(params.registry, tParams.structFeat, chunk, params.structures,
params.worldSeed);
((ProtoChunk) chunk).setStatus(STATUS);
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
}
((ProtoChunk) chunk).setStatus(STATUS);
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
}
}
/*
static ChunkAccess load(ServerLevel level, ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
return chunk;
}*/
}
public final class StepStructureReference {
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private void createReferences(WorldGenLevel worldGenLevel, StructureFeatureManager structureFeatureManager,
private void createReferences(WorldGenRegion worldGenLevel, StructureFeatureManager structureFeatureManager,
ChunkAccess chunkAccess) {
int i = 8;
ChunkPos chunkPos = chunkAccess.getPos();
int j = chunkPos.x;
int k = chunkPos.z;
@@ -478,9 +575,9 @@ public final class WorldGenerationStep {
for (int n = j - 8; n <= j + 8; n++) {
for (int o = k - 8; o <= k + 8; o++) {
if (!worldGenLevel.hasChunk(n, o))
continue;
long p = ChunkPos.asLong(n, o);
if (!worldGenLevel.hasChunk(n, o)) continue;
for (StructureStart<?> structureStart : worldGenLevel.getChunk(n, o).getAllStarts().values()) {
try {
if (structureStart.isValid()
@@ -504,138 +601,93 @@ public final class WorldGenerationStep {
}
}
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
// Note: Not certain StructureFeatureManager.forWorldGenRegion(...) is thread safe
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
//System.out.println("StepStructureReference: "+chunk.getPos());
// System.out.println("StepStructureReference: "+chunk.getPos());
createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepBiomes {
public final ChunkStatus STATUS = ChunkStatus.BIOMES;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
//System.out.println("StepBiomes: "+chunk.getPos());
chunk = joinAsync(params.generator.createBiomes(params.biomes, Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
// System.out.println("StepBiomes: "+chunk.getPos());
chunk = joinAsync(params.generator.createBiomes(params.biomes, Runnable::run,
Blender.of(worldGenRegion), tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepNoise {
public final ChunkStatus STATUS = ChunkStatus.NOISE;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
//System.out.println("StepNoise: "+chunk.getPos());
// System.out.println("StepNoise: "+chunk.getPos());
chunk = joinAsync(params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepSurface {
public final ChunkStatus STATUS = ChunkStatus.SURFACE;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
//System.out.println("StepSurface: "+chunk.getPos());
// System.out.println("StepSurface: "+chunk.getPos());
params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion),
chunk);
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepCarvers {
public final ChunkStatus STATUS = ChunkStatus.CARVERS;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
//System.out.println("StepCarvers: "+chunk.getPos());
//Blender.addAroundOldChunksCarvingMaskFilter((WorldGenLevel) worldGenRegion, (ProtoChunk) chunk);
//params.generator.applyCarvers(worldGenRegion, params.worldSeed, params.biomeManager, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk,
// GenerationStep.Carving.AIR);
// DISABLED CURRENTLY!
// System.out.println("StepCarvers: "+chunk.getPos());
// Blender.addAroundOldChunksCarvingMaskFilter((WorldGenLevel) worldGenRegion,
// (ProtoChunk) chunk);
// params.generator.applyCarvers(worldGenRegion, params.worldSeed,
// params.biomeManager, tParams.structFeat.forWorldGenRegion(worldGenRegion),
// chunk,
// GenerationStep.Carving.AIR);
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepLiquidCarvers {
public final ChunkStatus STATUS = ChunkStatus.LIQUID_CARVERS;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, List<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
Blender.addAroundOldChunksCarvingMaskFilter((WorldGenLevel) worldGenRegion, (ProtoChunk) chunk);
params.generator.applyCarvers(worldGenRegion, params.worldSeed, params.biomeManager, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk,
GenerationStep.Carving.AIR);
((ProtoChunk) chunk).setStatus(STATUS);
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
public final class StepFeatures {
public final ChunkStatus STATUS = ChunkStatus.FEATURES;
public final int RANGE = STATUS.getRange();
public final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion, GridList<ChunkAccess> chunks) {
for (int i=0; i<chunks.size(); i++) {
ChunkAccess chunk = chunks.get(i);
public final void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
GridList<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
ProtoChunk protoChunk = (ProtoChunk) chunk;
try {
protoChunk.setLightEngine(params.lightEngine);
params.generator.applyBiomeDecoration(worldGenRegion, chunk, tParams.structFeat.forWorldGenRegion(worldGenRegion));
params.generator.applyBiomeDecoration(worldGenRegion, chunk,
tParams.structFeat.forWorldGenRegion(worldGenRegion));
Blender.generateBorderTicks(worldGenRegion, chunk);
} catch (ReportedException e) {
//e.printStackTrace();
// FIXME: Features concurrent modification issue. Something about cocobeans just aren't happy
// e.printStackTrace();
// FIXME: Features concurrent modification issue. Something about cocobeans just
// aren't happy
// For now just retry.
} finally {
Heightmap.primeHeightmaps(chunk,
@@ -645,68 +697,5 @@ public final class WorldGenerationStep {
}
}
}
/*
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}*/
}
/*
public static class StepLight {
public static final ChunkStatus STATUS = ChunkStatus.LIGHT;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public static final ChunkAccess generate(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return joinAsync(lightEngine.lightChunk(chunk, chunk.isLightCorrect()));
}
public static final ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return joinAsync(lightEngine.lightChunk(chunk, chunk.isLightCorrect()));
}
}
*/
// The following may not be needed
/*
* public static class Spawn implements SimpleGen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final void doSimpleWork(ChunkStatus targetStatus,
* ServerLevel level, ChunkGenerator generator, List<ChunkAccess> chunkList,
* ChunkAccess chunk) { if (!chunk.isUpgrading())
* generator.spawnOriginalMobs(new WorldGenRegion(level, chunkList,
* targetStatus, -1)); } } public static class Heightmaps implements SimpleGen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final void doSimpleWork(ChunkStatus targetStatus,
* ServerLevel level, ChunkGenerator generator, List<ChunkAccess> chunkList,
* ChunkAccess chunk) { // Apearently nothing again??? Decompiler Error? } }
*
* public static class Full implements Gen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final ChunkAccess doWork(ChunkStatus targetStatus, Executor
* worker, ServerLevel level, ChunkGenerator generator, StructureManager
* structures, ThreadedLevelLightEngine lightEngine, Mutator function,
* List<ChunkAccess> chunkList, ChunkAccess chunk, boolean alwaysRegenerate) {
* return function.call(chunk); }
*
* @Override public final ChunkAccess load(ChunkStatus targetStatus, ServerLevel
* level, StructureManager structures, ThreadedLevelLightEngine lightEngine,
* Mutator function, ChunkAccess chunk) { return function.call(chunk); } }
*
*
*/
}