mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-01 23:47:50 +00:00
begin work on janky pregenerator
This commit is contained in:
parent
3c12a98ef3
commit
ee093397d3
1
.gitignore
vendored
1
.gitignore
vendored
@ -142,3 +142,4 @@ build
|
||||
/lang/
|
||||
/packs/
|
||||
/config.yml
|
||||
/region/
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items.state;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedItem;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class BufferedStateManipulator<T extends BlockState> implements BufferedItem {
|
||||
private final TerraPlugin main;
|
||||
|
||||
protected BufferedStateManipulator(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
BlockState state = origin.getBlock().getState();
|
||||
try {
|
||||
apply((T) state);
|
||||
} catch(ClassCastException e) {
|
||||
main.getLogger().warning("Could not find expected BlockState at " + origin + "; found " + origin.getBlock().getBlockData().getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void apply(T state);
|
||||
}
|
@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Random;
|
||||
|
||||
public interface TerraChunkGenerator {
|
||||
ChunkGenerator.ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, ChunkGenerator.ChunkData original);
|
||||
ChunkGenerator.ChunkData generateChunkData(@NotNull World world, Random random, int x, int z, ChunkGenerator.ChunkData original);
|
||||
|
||||
void generateBiomes(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome);
|
||||
|
||||
|
@ -86,7 +86,7 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"try"})
|
||||
public ChunkGenerator.ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, ChunkGenerator.ChunkData chunk) {
|
||||
public ChunkGenerator.ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkGenerator.ChunkData chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
com.dfsek.terra.api.world.biome.BiomeGrid grid = tw.getGrid();
|
||||
try(ProfileFuture ignore = tw.getProfiler().measure("TotalChunkGenTime")) {
|
||||
|
26
platforms/region/build.gradle.kts
Normal file
26
platforms/region/build.gradle.kts
Normal file
@ -0,0 +1,26 @@
|
||||
import com.dfsek.terra.configureCommon
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
}
|
||||
|
||||
configureCommon()
|
||||
|
||||
group = "com.dfsek.terra"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://jitpack.io/") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"shadedApi"(project(":common"))
|
||||
"shadedImplementation"("com.github.Querz:NBT:5.2") // Standalone NBT API
|
||||
"shadedImplementation"("org.yaml:snakeyaml:1.27")
|
||||
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("net.querz", "com.dfsek.terra.libs.nbt")
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.region.Generator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class RegionGenerator {
|
||||
public static void main(String[] args) throws IOException {
|
||||
long seed;
|
||||
if(args.length == 1) seed = Long.parseLong(args[0]);
|
||||
else seed = ThreadLocalRandom.current().nextLong();
|
||||
|
||||
Generator generator = new Generator(seed);
|
||||
|
||||
generator.generate();
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||
import com.dfsek.terra.api.GenericLoaders;
|
||||
import com.dfsek.terra.api.lang.Language;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.platform.world.Biome;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.platform.RawBiome;
|
||||
import com.dfsek.terra.platform.RawWorldHandle;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class StandalonePlugin implements TerraPlugin {
|
||||
private final ConfigRegistry registry = new ConfigRegistry();
|
||||
private final PluginConfig config = new PluginConfig();
|
||||
private final RawWorldHandle worldHandle = new RawWorldHandle();
|
||||
|
||||
@Override
|
||||
public WorldHandle getWorldHandle() {
|
||||
return worldHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerraWorld getWorld(World world) {
|
||||
return new TerraWorld(world, registry.get("DEFAULT"), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return Logger.getLogger("Terra");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginConfig getTerraConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return new File(".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
try {
|
||||
return new Language(new File(getDataFolder(), "lang/en_us.yml"));
|
||||
} catch(IOException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigRegistry getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemHandle getItemHandle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefaultConfig() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String platformName() {
|
||||
return "Standalone";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
registry
|
||||
.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
|
||||
.registerLoader(Biome.class, (t, o, l) -> new RawBiome(o.toString()))
|
||||
.registerLoader(MaterialData.class, (t, o, l) -> worldHandle.createMaterialData((String) o));
|
||||
new GenericLoaders(this).register(registry);
|
||||
}
|
||||
|
||||
public void load() {
|
||||
LangUtil.load("en_us", this);
|
||||
registry.loadAll(this);
|
||||
config.load(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
|
||||
public class Data implements BlockData, MaterialData {
|
||||
private final CompoundTag data;
|
||||
private final String noProp;
|
||||
|
||||
public Data(String data) {
|
||||
this.data = new CompoundTag();
|
||||
if(data.contains("[")) noProp = data.substring(0, data.indexOf('[')); // Strip properties for now TODO: actually do properties lol
|
||||
else noProp = data;
|
||||
this.data.putString("Name", noProp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialData getMaterial() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MaterialData materialData) {
|
||||
return ((Data) materialData).noProp.equals(noProp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(BlockData other) {
|
||||
return ((Data) other).noProp.equals(noProp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return !isAir(); //TODO: actual implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return noProp.equals("minecraft:air");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxDurability() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData createBlockData() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData clone() {
|
||||
try {
|
||||
return (BlockData) super.clone();
|
||||
} catch(CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return noProp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getHandle() {
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.generator.ChunkGenerator;
|
||||
import net.querz.mca.Chunk;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DirectChunkData implements ChunkGenerator.ChunkData {
|
||||
private final Chunk delegate;
|
||||
private final int offX;
|
||||
private final int offZ;
|
||||
|
||||
public DirectChunkData(Chunk delegate, int offX, int offZ) {
|
||||
this.delegate = delegate;
|
||||
this.offX = offX;
|
||||
this.offZ = offZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull BlockData blockData) {
|
||||
delegate.setBlockStateAt(x, y, z, ((Data) blockData).getHandle(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockData getBlockData(int x, int y, int z) {
|
||||
CompoundTag tag = delegate.getBlockStateAt(x, y, z);
|
||||
if(tag == null) return new Data("minecraft:air");
|
||||
return new Data(tag.getString("Name"));
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.generator.ChunkGenerator;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.platform.world.entity.Entity;
|
||||
import com.dfsek.terra.api.platform.world.entity.EntityType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DirectWorld implements World {
|
||||
private final long seed;
|
||||
private final GenWrapper generator;
|
||||
|
||||
public DirectWorld(long seed, GenWrapper generator) {
|
||||
this.seed = seed;
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUID() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkGenerated(int x, int z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getWorldFolder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(Location l) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateTree(Location l, Tree vanillaTreeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(Location location, EntityType entityType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return generator;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.platform.generator.BlockPopulator;
|
||||
import com.dfsek.terra.api.platform.generator.ChunkGenerator;
|
||||
import com.dfsek.terra.api.platform.world.BiomeGrid;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.generation.MasterChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class GenWrapper implements ChunkGenerator {
|
||||
private final MasterChunkGenerator generator;
|
||||
|
||||
public GenWrapper(MasterChunkGenerator generator) {
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome) {
|
||||
throw new UnsupportedOperationException(); // gen is directly handled by Generator
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TerraChunkGenerator getTerraGenerator() {
|
||||
return generator;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.platform.world.Biome;
|
||||
|
||||
public class RawBiome implements Biome {
|
||||
private final String id;
|
||||
|
||||
public RawBiome(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return id;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class RawTree implements Tree { // TODO: implement
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plant(Location l, Random r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MaterialData> getSpawnable() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.dfsek.terra.platform;
|
||||
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.platform.world.entity.EntityType;
|
||||
|
||||
public class RawWorldHandle implements WorldHandle {
|
||||
@Override
|
||||
public void setBlockData(Block block, BlockData data, boolean physics) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Block block) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialData getType(Block block) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData createBlockData(String data) {
|
||||
return new Data(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialData createMaterialData(String data) {
|
||||
return new Data(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tree getTree(String id) {
|
||||
return new RawTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntity(String id) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.dfsek.terra.region;
|
||||
|
||||
import com.dfsek.terra.StandalonePlugin;
|
||||
import com.dfsek.terra.api.platform.generator.ChunkGenerator;
|
||||
import com.dfsek.terra.api.util.GlueList;
|
||||
import com.dfsek.terra.generation.MasterChunkGenerator;
|
||||
import com.dfsek.terra.generation.math.SamplerCache;
|
||||
import com.dfsek.terra.platform.DirectChunkData;
|
||||
import com.dfsek.terra.platform.DirectWorld;
|
||||
import com.dfsek.terra.platform.GenWrapper;
|
||||
import net.querz.mca.Chunk;
|
||||
import net.querz.mca.MCAFile;
|
||||
import net.querz.mca.MCAUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Generator {
|
||||
private final Map<Long, MCAFile> files = new HashMap<>();
|
||||
|
||||
private final long seed;
|
||||
|
||||
public Generator(long seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public void generate() throws IOException {
|
||||
|
||||
int rad = 50;
|
||||
|
||||
StandalonePlugin plugin = new StandalonePlugin();
|
||||
plugin.load();
|
||||
|
||||
|
||||
MasterChunkGenerator generator = new MasterChunkGenerator(plugin.getRegistry().get("DEFAULT"), plugin, new SamplerCache(plugin));
|
||||
GenWrapper wrapper = new GenWrapper(generator);
|
||||
|
||||
int count = 0;
|
||||
|
||||
List<Double> times = new GlueList<>();
|
||||
|
||||
for(int cx = -rad; cx <= rad; cx++) {
|
||||
for(int cz = -rad; cz <= rad; cz++) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
long key = (((long) MCAUtil.chunkToRegion(cx)) << 32) | (MCAUtil.chunkToRegion(cz) & 0xffffffffL);
|
||||
|
||||
int finalCx = cx;
|
||||
int finalCz = cz;
|
||||
MCAFile file = files.computeIfAbsent(key, k -> new MCAFile(MCAUtil.chunkToRegion(finalCx), MCAUtil.chunkToRegion(finalCz)));
|
||||
|
||||
Chunk chunk = Chunk.newChunk();
|
||||
|
||||
ChunkGenerator.ChunkData chunkData = new DirectChunkData(chunk, cx, cz);
|
||||
generator.generateChunkData(new DirectWorld(seed, wrapper), null, cx, cz, chunkData);
|
||||
|
||||
file.setChunk(cx, cz, chunk);
|
||||
|
||||
long end = System.nanoTime() - start;
|
||||
count++;
|
||||
times.add((double) end / 1000000);
|
||||
|
||||
if(count % 200 == 0) {
|
||||
double total = 0;
|
||||
for(double d : times) total += d;
|
||||
double avg = total / count;
|
||||
|
||||
double pct = ((double) count / (rad * rad * 2 * 2)) * 100D;
|
||||
|
||||
plugin.getLogger().info("Generated " + count + " chunks. " + (1 / avg) * 1000 + "cps; " + pct + "%");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Map.Entry<Long, MCAFile> entry : files.entrySet()) {
|
||||
entry.getValue().cleanupPalettesAndBlockStates();
|
||||
int x = (int) (entry.getKey() >> 32);
|
||||
int z = (int) (long) entry.getKey();
|
||||
File file = new File("region", MCAUtil.createNameFromRegionLocation(x, z));
|
||||
file.getParentFile().mkdirs();
|
||||
MCAUtil.write(entry.getValue(), file);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.dfsek.terra.region;
|
||||
|
||||
public class RegionWriter {
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ rootProject.name = "Terra"
|
||||
include("common")
|
||||
include("platforms:bukkit")
|
||||
include("platforms:fabric")
|
||||
|
||||
include("platforms:region")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
|
Loading…
x
Reference in New Issue
Block a user