Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e831f85
Partial layered generator implementation
astrsh Jul 11, 2022
2a9d940
Finish initial layered generator implementation
astrsh Jul 12, 2022
11044b6
Store palettes and predicates in registries
astrsh Jul 16, 2022
809a642
Rename some keys
astrsh Jul 16, 2022
698725c
Implement layer samplers
astrsh Jul 16, 2022
b57b71b
Replace BLOCK layer palette with PALETTE
astrsh Jul 16, 2022
edcba97
Implement biome defined layer palettes
astrsh Jul 16, 2022
4d31fda
Implement layer palette groups
astrsh Jul 16, 2022
fea7d7a
Implement sampler operators + sampler list predicate
astrsh Jul 17, 2022
0b057c5
Add platform air layer palette
astrsh Jul 17, 2022
237b897
Rename predicates key to tests
astrsh Jul 17, 2022
7baace0
Change layer class method signatures
astrsh Jul 18, 2022
c733c21
Implement biome defined layer samplers
astrsh Jul 18, 2022
55e024d
Change layer signatures
astrsh Jul 30, 2022
50397a4
Add loaders for vector classes
astrsh Jul 30, 2022
d9bd913
Add point sets to layered gen
astrsh Jul 30, 2022
596c84a
Forgot signature change in chunk generator
astrsh Jul 30, 2022
9a171b0
Implement dot product layer palette
astrsh Jul 30, 2022
c2902cc
Add paralithic as layered gen dependency
astrsh Jul 30, 2022
bd139a8
BooleanOperator -> RelationalOperator
astrsh Jul 30, 2022
e51fb9c
Merge branch 'ver/6.4.0' into dev/layered-generator
astrsh Oct 1, 2023
3eb6f89
Merge remote-tracking branch 'origin/master' into dev/layered-generator
duplexsystem Oct 14, 2024
35bd33e
Merge branch 'dev/7.0-2' into dev/layered-generator
duplexsystem Jun 3, 2025
e079cdf
Merge branch 'dev/7.0-2' into dev/layered-generator
duplexsystem Jun 6, 2025
f04c9b3
Fix build
duplexsystem Jun 6, 2025
bc1213b
Use Seismic function for perf
duplexsystem Jun 6, 2025
0e21106
Fix build again
duplexsystem Jun 6, 2025
619c215
Use seismic func for perf 2
duplexsystem Jun 6, 2025
3269f9e
Initial work on supporting chunk based bending and interpolation in L…
duplexsystem Jun 7, 2025
c9d7af5
fix padding
duplexsystem Jun 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ public Biome getBiome(int x, int y, int z, long seed) {

public Biome getBiome(int x, int z, long seed) {

x += mutator.getSample(seed + 1, x, z) * noiseAmp;
z += mutator.getSample(seed + 2, x, z) * noiseAmp;
x += (int) (mutator.getSample(seed + 1, x, z) * noiseAmp);
z += (int) (mutator.getSample(seed + 2, x, z) * noiseAmp);

x /= resolution;
z /= resolution;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;

import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;

import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
Expand Down Expand Up @@ -98,7 +100,7 @@ protected static int calculateChunkOriginArrayIndex(int totalExpanderCount, List
// chunk samples points on the same overall grid.
// Without this, shared chunk borders (required because of adjacent cell reads) will not be identical
// because points would be sampled on grids at different offsets, resulting in artifacts at borders.
return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
return FloatingPointFunctions.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
}

private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
Expand Down
11 changes: 11 additions & 0 deletions common/addons/chunk-generator-layered/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version = version("0.1.0")

dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
api("com.dfsek", "paralithic", Versions.Libraries.paralithic)
}

tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.chunkgenerator.lib.jafama")
relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.chunkgenerator.lib.paralithic")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package com.dfsek.terra.addons.chunkgenerator;

import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;

import com.dfsek.terra.addons.chunkgenerator.config.sampler.ElevationLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Supplier;

import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPalettePackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPredicatePackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerResolverPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerSamplerPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomeDefinedLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.DotProductLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PlatformAirLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.SimpleLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.AdjacentPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.SimplePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CubePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CuboidPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.SphericalPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.DifferencePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.ExpressionFilterPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.IntersectionPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.UnionPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.BelowLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.RangeLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerListLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.resolve.PaletteLayerResolverTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.resolve.PredicateLayerResolverTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.sampler.BiomeDefinedLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.sampler.DensityLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.generation.LayeredChunkGenerator;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;


public class LayeredChunkGeneratorAddon implements AddonInitializer {

private static final Logger logger = LoggerFactory.getLogger( LayeredChunkGeneratorAddon.class);

public static final TypeKey<Supplier<ObjectTemplate<PointSet>>> POINT_SET_TYPE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<Supplier<ObjectTemplate<LayerSampler>>> LAYER_SAMPLER_TYPE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<InstanceWrapper<LayerSampler>> LAYER_SAMPLER_TOKEN = new TypeKey<>() {
};

public static final TypeKey<Supplier<ObjectTemplate<LayerPalette>>> LAYER_PALETTE_TYPE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<InstanceWrapper<LayerPalette>> LAYER_PALETTE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<Supplier<ObjectTemplate<LayerPredicate>>> LAYER_PREDICATE_TYPE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<InstanceWrapper<LayerPredicate>> LAYER_PREDICATE_TOKEN = new TypeKey<>() {
};

public static final TypeKey<Supplier<ObjectTemplate<LayerResolver>>> LAYER_RESOLVER_TYPE_TOKEN = new TypeKey<>() {
};

@Inject
private Platform platform;

@Inject
private BaseAddon addon;

@Override
public void initialize() {

platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.priority(1000)
.then(event -> {
event.getPack().applyLoader(RelationalOperator.class,
(type, o, loader, depthTracker) -> RelationalOperator.valueOf((String) o));

CheckedRegistry<Supplier<ObjectTemplate<PointSet>>> pointSetTypeRegistry = event.getPack().getOrCreateRegistry(
POINT_SET_TYPE_TOKEN);
pointSetTypeRegistry.register(addon.key("LIST"), SimplePointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("ADJACENT"), AdjacentPointSetTemplate::new);

pointSetTypeRegistry.register(addon.key("SPHERE"), SphericalPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("CUBOID"), CuboidPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("CUBE"), CubePointSetTemplate::new);

pointSetTypeRegistry.register(addon.key("UNION"), UnionPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("INTERSECTION"), IntersectionPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("DIFFERENCE"), DifferencePointSetTemplate::new);

pointSetTypeRegistry.register(addon.key("EXPRESSION"), ExpressionFilterPointSetTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerSampler>>> samplerTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TYPE_TOKEN);
CheckedRegistry<InstanceWrapper<LayerSampler>> samplerRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TOKEN);
samplerTypeRegistry.register(addon.key("DENSITY"), DensityLayerSamplerTemplate::new);
samplerTypeRegistry.register(addon.key("ELEVATION"), ElevationLayerSamplerTemplate::new);
samplerTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerSamplerTemplate::new);

event.loadTemplate(new LayerSamplerPackConfigTemplate()).getSamplers().forEach((key, sampler) -> {
samplerRegistry.register(addon.key(key), new InstanceWrapper<>(sampler));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPredicate>>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN);
predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER_POINTS"), SamplerListLayerPredicateTemplate::new);

CheckedRegistry<InstanceWrapper<LayerPredicate>> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN);
event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> {
predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPalette>>> paletteTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TYPE_TOKEN);
paletteTypeRegistry.register(addon.key("PALETTE"), SimpleLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("AIR"), () -> new PlatformAirLayerPaletteTemplate(platform));
paletteTypeRegistry.register(addon.key("SURFACE_NORMAL"), DotProductLayerPaletteTemplate::new);

event.getPack().applyLoader(LayerPalette.Group.class, new LayerPalette.Group.Loader(event.getPack()));

CheckedRegistry<InstanceWrapper<LayerPalette>> paletteRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TOKEN);
event.loadTemplate(new LayerPalettePackConfigTemplate()).getPalettes().forEach((key, palette) -> {
paletteRegistry.register(addon.key(key), new InstanceWrapper<>(palette));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerResolver>>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN);
resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new);
resolverTypeRegistry.register(addon.key("LAYER"), PaletteLayerResolverTemplate::new);
LayerResolver resolver = event.loadTemplate(new LayerResolverPackConfigTemplate()).getResolver();

event.getPack()
.getOrCreateRegistry(ChunkGeneratorProvider.class)
.register(addon.key("LAYERED"),
pack -> new LayeredChunkGenerator(platform, resolver));
})
.failThrough();

platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigurationLoadEvent.class)
.priority(1000)
.then(BiomeDefinedLayerPalette.injectLayerPalettes)
.then(BiomeDefinedLayerSampler.injectLayerSamplers);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.dfsek.terra.addons.chunkgenerator.api;

import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.AnnotatedType;
import java.util.HashMap;
import java.util.Map;

import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.properties.Properties;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;


public abstract class LayerPalette {

private final Group group;

private final boolean resetsGroup;

protected LayerPalette(Group group, boolean resetsGroup) {
this.group = group;
this.resetsGroup = resetsGroup;
}

public abstract Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);

public final Group getGroup() {
return group;
}

public final boolean resetsGroup() {
return resetsGroup;
}

public static class Group {

public static Group NO_GROUP = new Group();

private Group() {}

public static Group get(String string, ConfigPack pack) {
if (!pack.getContext().has(Holder.class)) {
pack.getContext().put(new Holder(new HashMap<>()));
}
return pack.getContext().get(Holder.class).groups.computeIfAbsent(string, s -> new Group());
}

private record Holder(Map<String, Group> groups) implements Properties {}

public static class Loader implements TypeLoader<Group> {

private final ConfigPack pack;

public Loader(ConfigPack pack) {
this.pack = pack;
}

@Override
public Group load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
String groupName = (String) o;
return Group.get(groupName, pack);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api;

import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;


public interface LayerPredicate {
boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api;

import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;


public interface LayerResolver {
LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dfsek.terra.addons.chunkgenerator.api;

import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;


public interface LayerSampler {
double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);
ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider);
double getBlendWeight();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api.chunk;

import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;


public interface ChunkLayerSampler {
double sample(int fmX, int y, int fmZ);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;

import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Value;

import java.util.Map;

import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.api.config.meta.Meta;


public class LayerPalettePackConfigTemplate implements ConfigTemplate {

@Value("generation.layers")
private @Meta Map<String, LayerPalette> palettes;

public Map<String, LayerPalette> getPalettes() {
return palettes;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;

import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;

import java.util.LinkedHashMap;
import java.util.Map;

import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.api.config.meta.Meta;


public class LayerPredicatePackConfigTemplate implements ConfigTemplate {

@Value("generation.tests")
@Default
private @Meta Map<String, LayerPredicate> predicates = new LinkedHashMap<>();

public Map<String, LayerPredicate> getPredicates() {
return predicates;
}

}
Loading