Zones - ToCraft/CraftedTerrainGeneration GitHub Wiki
Zones are intended to tell CTGen, what specifications and biomes are mapped to what color on the map image. Here's the general file structure for a Zone:
{
"biome": "minecraft:deep_ocean",
"color": "#002355",
"terrain_modifier": 6.0,
"pixel_weight": 1
}
Here's a detailed explanation of each parameter:
Parameter | Description |
---|---|
color |
required, color on the biome map in hex decimal layout (RGB) |
biome |
required, the biome the color is mapped to |
terrain_modifier |
optional (default: 4), in addition to the height on the heightmap, a noise value is added. This defines how strongly the noise can swing -> 6 means, hills are up to 6 blocks high, thales can be up to 6 blocks deep. Will be modified by transition |
pixel_weight |
optional (default: 1), this is only used for preprocessing. A higher weight causes the zone to more aggressively spread |
You can view all Zones that are shipped with CTGen in the source code. Those zones are used by Elarth. They are also listed here:
-
ctgen:lake
-- lake at the sea level
-
ctgen:river
-- river at the sea level
-
ctgen:ocean
-- ocean at the sea level
-
ctgen:deep_ocean
-- deep ocean at the sea level
-
ctgen:frozen_river
-- frozen river at the sea level
-
ctgen:frozen_lake
-- frozen lake at the sea level
-
ctgen:stony_flats
-- flat stony area
-
ctgen:snowy_flats
-- flat snowy area
-
ctgen:snowy_slopes
-- similar to plains but with snow
-
ctgen:snowy_mountains
-- big mountains that are snowed in
-
ctgen:plains
-- plains biome
-
ctgen:forest
-- forest biome
-
ctgen:hills
-- transition between normal terrain (as taiga, plains, forest, ...) and
ctgen:mountains
-
ctgen:mountains
-- big stony mountains
-
ctgen:desert
-- desert biome
-
ctgen:badlands
-- custom badlands biome
-
ctgen:badlands_mountains
-- mountains with custom badlands biome
If you want to use any of these Zones in java, use the Zones
class:
public final class Zones {
// Northern Continent
public static final ResourceKey<Zone> STONY_FLATS = getKey("stony_flats");
public static final ResourceKey<Zone> SNOWY_FLATS = getKey("snowy_flats");
public static final ResourceKey<Zone> SNOWY_SLOPES = getKey("snowy_slopes");
public static final ResourceKey<Zone> SNOWY_MOUNTAINS = getKey("snowy_mountains");
public static final ResourceKey<Zone> FROZEN_LAKE = getKey("frozen_lake");
public static final ResourceKey<Zone> FROZEN_RIVER = getKey("frozen_river");
// Eastern Continent
public static final ResourceKey<Zone> PLAINS = getKey("plains");
public static final ResourceKey<Zone> FOREST = getKey("forest");
public static final ResourceKey<Zone> HILLS = getKey("hills");
public static final ResourceKey<Zone> MOUNTAINS = getKey("mountains");
public static final ResourceKey<Zone> LAKE = getKey("lake");
// Western Continent
public static final ResourceKey<Zone> DESERT = getKey("desert");
public static final ResourceKey<Zone> BADLANDS = getKey("badlands");
public static final ResourceKey<Zone> BADLANDS_MOUNTAINS = getKey("badlands_mountains");
// General Water Biomes
public static final ResourceKey<Zone> RIVER = getKey("river");
public static final ResourceKey<Zone> OCEAN = getKey("ocean");
public static final ResourceKey<Zone> DEEP_OCEAN = getKey("deep_ocean");
}
To create a custom zone in java, use code, similar to the following:
new ZoneBuilder().setBiome(getBiome(context, Biomes.STONY_SHORE)).setColor(new Color(130, 140, 130)).build();
Zones created in Java must be registered by bootstrapping them in to CTRegistries.ZONES_KEY
during the runData
task.
No matter if running on Forge, Fabric or NeoForge, code similar to this one will be required:
public final class Zones {
public static final ResourceKey<Zone> OCEAN = getKey("ocean");
public static final ResourceKey<Zone> DEEP_OCEAN = getKey("deep_ocean");
public static void bootstrap(@NotNull BootstapContext<Zone> context) {
context.register(OCEAN, new ZoneBuilder().setBiome(getBiome(context, Biomes.OCEAN)).setColor(new Color(0, 42, 103)).setHeight(-35).setTerrainModifier(16).build());
context.register(DEEP_OCEAN, new ZoneBuilder().setBiome(getBiome(context, Biomes.DEEP_OCEAN)).setColor(new Color(0, 35, 85)).setHeight(-60).setTerrainModifier(33).build());
}
private static @NotNull Holder<Biome> getBiome(@NotNull BootstapContext<?> context, ResourceKey<Biome> biome) {
return context.lookup(Registries.BIOME).getOrThrow(biome);
}
private static @NotNull ResourceKey<Zone> getKey(String name) {
return ResourceKey.create(CTRegistries.ZONES_KEY, new ResourceLocation(YourMod.MODID, name));
}
}
For Fabric, this code snippet is used in CTGen:
public final class CTGDataGen implements DataGeneratorEntrypoint {
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder().add(CTRegistries.ZONES_KEY, Zones::bootstrap);
@Override
public void onInitializeDataGenerator(@NotNull FabricDataGenerator generator) {
FabricDataGenerator.Pack pack = generator.createPack();
// generate zones
pack.addProvider((FabricDataGenerator.Pack.RegistryDependentFactory<DataProvider>) (output, registriesFuture) ->
new RegistriesDatapackGenerator(output, registriesFuture.thenComposeAsync(registries -> CompletableFuture.supplyAsync(() -> {
RegistryAccess.Frozen frozen = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
return BUILDER.buildPatch(frozen, registries);
}))));
}
}
For Forge, it would look like the following code:
@Mod.EventBusSubscriber(modid = MyMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class DataGenerators {
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
PackOutput packOutput = generator.getPackOutput();
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
generator.addProvider(event.includeServer(), new MyRegistryDataProvider(packOutput, lookupProvider));
}
}
public class MyRegistryDataProvider extends DatapackBuiltinEntriesProvider {
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder().add(CTRegistries.ZONES_KEY, Zones::bootstrap);
public ModWorldGenProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
super(output, registries, BUILDER, Set.of(AGoTMod.MOD_ID));
}
}