Skip to content

Commit

Permalink
Use a persistent MultiGenerator instance for all chunks
Browse files Browse the repository at this point in the history
As opposed to creating a new instance per chunk. This seems to increase
generation speed quite noticeably, making it a lot more enjoyable to fly
around and generate new chunks with.
  • Loading branch information
Pixaurora committed Aug 18, 2023
1 parent 38858dd commit 92aacd1
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 118 deletions.
34 changes: 0 additions & 34 deletions src/main/java/net/pixaurora/janerator/Janerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ImposterProtoChunk;
import net.minecraft.world.level.chunk.LevelChunk;
import net.pixaurora.janerator.config.GraphProperties;
import net.pixaurora.janerator.config.JaneratorConfig;
import net.pixaurora.janerator.worldgen.generator.MultiGenerator;

public class Janerator {
public static final Logger LOGGER = LoggerFactory.getLogger("Janerator");

public static ChunkGenerator getGeneratorAt(
ResourceKey<Level> dimension,
ChunkGenerator defaultGenerator,
ChunkAccess chunk
) {
JaneratorConfig config = JaneratorConfig.getInstance();

boolean chunkAlreadyGenerated = chunk instanceof LevelChunk || chunk instanceof ImposterProtoChunk;

if (chunkAlreadyGenerated || config.missingPresetFor(dimension)) {
return defaultGenerator;
}

GraphProperties dimensionPreset = config.getPresetFor(dimension);

return new MultiGenerator(
dimensionPreset.getGrapher(),
defaultGenerator,
dimensionPreset.getShadedGenerator(),
dimensionPreset.getOutlineGenerator(),
chunk
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class GraphProperties {
private ResourceKey<Level> dimension;

private ChunkGenerator shadedGenerator;
private ChunkGenerator outlineGenerator;
private ChunkGenerator outlinesGenerator;

private ChunkGrapher grapher;

Expand All @@ -24,14 +24,14 @@ public class GraphProperties {
ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(GraphProperties::getDimension),
ConfiguredGrapherSettings.CODEC.fieldOf("function_to_graph").forGetter(GraphProperties::getSettings),
ChunkGenerator.CODEC.fieldOf("shaded_in_generator").forGetter(GraphProperties::getShadedGenerator),
ChunkGenerator.CODEC.fieldOf("outlines_generator").forGetter(GraphProperties::getOutlineGenerator)
ChunkGenerator.CODEC.fieldOf("outlines_generator").forGetter(GraphProperties::getOutlinesGenerator)
).apply(instance, GraphProperties::new)
);

public GraphProperties(ResourceKey<Level> dimension, ConfiguredGrapherSettings grapherSettings, ChunkGenerator shadedGenerator, ChunkGenerator outlineGenerator) {
public GraphProperties(ResourceKey<Level> dimension, ConfiguredGrapherSettings grapherSettings, ChunkGenerator shadedGenerator, ChunkGenerator outlinesGenerator) {
this.dimension = dimension;

this.outlineGenerator = outlineGenerator;
this.outlinesGenerator = outlinesGenerator;
this.shadedGenerator = shadedGenerator;

this.grapher = new ChunkGrapher(grapherSettings);
Expand All @@ -53,7 +53,7 @@ public ChunkGenerator getShadedGenerator() {
return this.shadedGenerator;
}

public ChunkGenerator getOutlineGenerator() {
return this.outlineGenerator;
public ChunkGenerator getOutlinesGenerator() {
return this.outlinesGenerator;
}
}
34 changes: 31 additions & 3 deletions src/main/java/net/pixaurora/janerator/config/JaneratorConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.pixaurora.janerator.worldgen.generator.MultiGenerator;

public class JaneratorConfig {
public static Codec<JaneratorConfig> CODEC =
Expand Down Expand Up @@ -39,19 +41,19 @@ public static void destroy() {
}

private Map<ResourceKey<Level>, GraphProperties> presets;
private Map<ResourceKey<Level>, MultiGenerator> generators;

public JaneratorConfig(List<GraphProperties> presets) {
this.presets = new HashMap<>(presets.size());
this.generators = new HashMap<>(presets.size());

for (GraphProperties preset : presets) {
this.presets.put(preset.getDimension(), preset);
}
}

public List<GraphProperties> getAllPresets() {
return this.presets
.values()
.stream()
return this.presets.values().stream()
.toList();
}

Expand All @@ -62,4 +64,30 @@ public GraphProperties getPresetFor(ResourceKey<Level> dimension) {
public boolean missingPresetFor(ResourceKey<Level> dimension) {
return ! this.presets.containsKey(dimension);
}

public synchronized ChunkGenerator createGenerator(ResourceKey<Level> dimension, ChunkGenerator defaultGenerator) {
GraphProperties preset = this.presets.get(dimension);

return this.generators.computeIfAbsent(
dimension,
(dim) -> new MultiGenerator(
preset.getGrapher(),
defaultGenerator,
preset.getShadedGenerator(),
preset.getOutlinesGenerator()
)
);
}

public ChunkGenerator getIntendedGenerator(ResourceKey<Level> dimension, ChunkGenerator defaultGenerator) {
if (this.missingPresetFor(dimension)) {
return defaultGenerator;
}

if (! this.generators.containsKey(dimension)) {
return this.createGenerator(dimension, defaultGenerator);
} else {
return this.generators.get(dimension);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;

public class ChunkGrapher extends CacheLoader<ChunkPos, GraphedChunk> {
public class ChunkGrapher {
private ConfiguredGrapherSettings settings;
private ThreadLocal<PointGrapher> localPointGrapher;

Expand All @@ -24,7 +24,7 @@ public ChunkGrapher(ConfiguredGrapherSettings settings) {
this.cache = CacheBuilder.newBuilder()
.expireAfterWrite(60, TimeUnit.SECONDS)
.maximumSize(1024)
.build(this);
.build(CacheLoader.from(this::graphChunk));
}

public ConfiguredGrapherSettings getSettings() {
Expand All @@ -43,9 +43,8 @@ public CompletableFuture<Boolean> schedulePointGraphing(int x, int z) {
return CompletableFuture.supplyAsync(() -> this.isPointShaded(x, z), GraphingUtils.threadPool);
}

@Override
public GraphedChunk load(ChunkPos pos) {
return new GraphedChunk(this, pos);
private GraphedChunk graphChunk(ChunkPos pos) {
return GraphedChunk.fromGraphing(this, pos);
}

public GraphedChunk getChunkGraph(ChunkPos pos) {
Expand Down
44 changes: 33 additions & 11 deletions src/main/java/net/pixaurora/janerator/graphing/GraphedChunk.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.pixaurora.janerator.graphing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -10,6 +11,8 @@

import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.pixaurora.janerator.worldgen.FullGeneratorLookup;
import net.pixaurora.janerator.worldgen.generator.MultiGenerator;

public class GraphedChunk {
public static boolean SHADED = true;
Expand All @@ -20,10 +23,13 @@ public class GraphedChunk {

private ChunkGrapher grapher;

public GraphedChunk(ChunkGrapher grapher, ChunkPos pos) {
private GraphedChunk(ChunkGrapher grapher, ChunkPos pos, List<Boolean> shading) {
this.grapher = grapher;
this.pos = pos;
this.shading = shading;
}

public static GraphedChunk fromGraphing(ChunkGrapher grapher, ChunkPos pos) {
List<CompletableFuture<Boolean>> graphingFutures = new ArrayList<>();

int startX = pos.getMinBlockX();
Expand All @@ -38,31 +44,43 @@ public GraphedChunk(ChunkGrapher grapher, ChunkPos pos) {
}
}

this.shading = graphingFutures
.stream()
.map(future -> GraphingUtils.completeFuture(future))
.toList();
return new GraphedChunk(
grapher,
pos,
graphingFutures
.stream()
.map(future -> GraphingUtils.completeFuture(future))
.toList()
);
}

public List<ChunkGenerator> getGeneratorMap(ChunkGenerator defaultGenerator, ChunkGenerator modifiedGenerator, ChunkGenerator outlineGenerator) {
public static GraphedChunk allUnshaded(ChunkGrapher grapher, ChunkPos pos) {
return new GraphedChunk(
grapher,
pos,
Collections.nCopies(256, GraphedChunk.UNSHADED)
);
}

private List<ChunkGenerator> getBlockScaleMap(MultiGenerator multiGenerator) {
List<ChunkGenerator> generatorMap = new ArrayList<>(
IntStream.range(0, 256)
.boxed()
.map(value -> defaultGenerator)
.map(value -> multiGenerator.getDefaultGenerator())
.toList()
);

GraphingUtils.getIndices(this.shading, GraphedChunk.SHADED)
.stream()
.forEach(coord -> generatorMap.set(coord.toListIndex(), modifiedGenerator));
.forEach(coord -> generatorMap.set(coord.toListIndex(), multiGenerator.getShadedGenerator()));
this.findOutlinedPortion()
.stream()
.forEach(coord -> generatorMap.set(coord.toListIndex(), outlineGenerator));
.forEach(coord -> generatorMap.set(coord.toListIndex(), multiGenerator.getOutlinesGenerator()));

return generatorMap;
}

public List<ChunkGenerator> sampleBiomeGeneratorMap(ChunkGenerator defaultGenerator, ChunkGenerator modifiedGenerator) {
private List<ChunkGenerator> getBiomeScaleMap(MultiGenerator multiGenerator) {
List<ChunkGenerator> biomeGeneratorMap = new ArrayList<>();

// Because biomes are placed per every 4 blocks, we sample
Expand All @@ -86,14 +104,18 @@ public List<ChunkGenerator> sampleBiomeGeneratorMap(ChunkGenerator defaultGenera
.get().getKey();

biomeGeneratorMap.add(
sampledShade ? modifiedGenerator : defaultGenerator
sampledShade ? multiGenerator.getShadedGenerator() : multiGenerator.getDefaultGenerator()
);
}
}

return biomeGeneratorMap;
}

public FullGeneratorLookup toLookup(MultiGenerator generator) {
return new FullGeneratorLookup(this.getBlockScaleMap(generator), this.getBiomeScaleMap(generator));
}

private List<Coordinate> findOutlinedPortion() {
List<Coordinate> outlinedPortion = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.pixaurora.janerator.Janerator;
import net.pixaurora.janerator.config.JaneratorConfig;

@Mixin(ChunkStatus.class)
public class ChunkStatusMixin {
Expand All @@ -25,10 +24,9 @@ public class ChunkStatusMixin {
public void janerator$overrideGeneratorType(
Args args
) {
ChunkAccess chunk = args.get(8);
ResourceKey<Level> dimension = ((ServerLevel) args.get(2)).dimension();
ChunkGenerator normalGenerator = args.get(3);

args.set(3, Janerator.getGeneratorAt(dimension, normalGenerator, chunk));
args.set(3, JaneratorConfig.getInstance().getIntendedGenerator(dimension, normalGenerator));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.pixaurora.janerator.worldgen;

import java.util.List;

import net.minecraft.world.level.chunk.ChunkGenerator;

public class FullGeneratorLookup extends GeneratorLookup {
private GeneratorLookup biomeScale;

public FullGeneratorLookup(List<ChunkGenerator> blockLevelMapping, List<ChunkGenerator> biomeLevel) {
super(blockLevelMapping);
this.biomeScale = new GeneratorLookup(biomeLevel);
}

public GeneratorLookup atBiomeScale() {
return this.biomeScale;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import net.pixaurora.janerator.graphing.Coordinate;
import net.pixaurora.janerator.graphing.GraphingUtils;

public class GeneratorFinder {
public class GeneratorLookup {
private List<ChunkGenerator> generatorMap;

private List<PlacementSelection> selections;
private ChunkGenerator fallbackGenerator;

public GeneratorFinder(
public GeneratorLookup(
List<ChunkGenerator> generatorMap
) {
this.generatorMap = generatorMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
import net.pixaurora.janerator.mixin.NoiseChunkAccessor;

public class WrappedBiomeResolver implements BiomeResolver {
GeneratorFinder generators;
GeneratorLookup generators;
Map<ChunkGenerator, BiomeResolver> biomeResolvers;
Map<ChunkGenerator, Sampler> samplers;

public WrappedBiomeResolver(
GeneratorFinder generators,
GeneratorLookup generators,
Blender blender,
ChunkAccess chunk,
StructureManager structureManager,
Expand Down
Loading

0 comments on commit 92aacd1

Please sign in to comment.