Memodifikasi Generasi Dunia

Peringatan

These docs were written for SpongeAPI 7 and are likely out of date. If you feel like you can help update them, please submit a PR!

  • Mengubah Generasi Vanila

  • Menciptakan dasar Daerah buatan

  • Menciptakan GenerationPopulators buatan

  • Menciptakan Populators buatan

  • Menciptakan Biomes buatan

Mengubah Generasi Vanila

Catatan

Laman ini menduga anda akrab dengan pengaturan WorldGeneratorModifier anda, jika tidak, maka tolong baca artikel tentang perubahan pengaturan anda di WorldGeneratorModifiers.

Sponge membeberkan sebuah perjanjian yang baik dari generasi dunia vanilla, yang bisa diubah melalui berbagai penghubung. Saat ini, satu-satunya elemen dari proses pembangkitan yang dengan mudah dibongkar untuk penyalahgunaan adalah populators.

For a quick example, let's look at how we would change the cacti that spawn in deserts to be taller.

import org.spongepowered.api.world.biome.BiomeGenerationSettings;
import org.spongepowered.api.world.biome.BiomeTypes;
import org.spongepowered.api.world.gen.Populator;
import org.spongepowered.api.world.gen.populator.Cactus;

@Override
public void modifyWorldGenerator(WorldProperties world, DataContainer settings, WorldGenerator worldGenerator) {
    BiomeGenerationSettings desertSettings = worldGenerator.getBiomeSettings(BiomeTypes.DESERT);
    for (Cactus populator : desertSettings.getPopulators(Cactus.class)) {
        populator.setHeight(5);
    }
}

Dimulai dengan memperoleh BiomeGenerationSettings untuk desert biome. Obyek ini adalah sebuah penampung untuk semua pengaturan turunan terkait dengan biome tersebut. Selanjutnya, terus ulangi semua daftar Cactus poplulators dan ubah tingginya menjadi 5, yang berarti hal itu hanya dapat menghasilkan cactii sepanjang 5 blok.

Catatan

Cactus#setHeight(int), dan banyak methods lain yang mirip di populators lain, juga memerlukan sebuah VariableAmount yang dapat digunakan untuk menentukan tinggi jangkauannya atau nilai perubahan yang lain.

Hal ini telah menjadi contoh mudah dari bagaimana mengubah sebuah populator yang ada. Mari lihat bagaimana kita menambahkan sebuah hal baru dari populator vanilla. Sekarang ini populator akan ditambahkan secara menyeluruh, yang artinya hal itu akan diterapkan ke semua bongkahan tanpa menghiraukan biome nya. Mari tambahkan sebuah populator Labu secara menyeluruh, yang menyebabkan labu berserakan dimana-mana diseluruh dunia.

import org.spongepowered.api.world.gen.populator.Pumpkin;

@Override
public void modifyWorldGenerator(WorldProperties world, DataContainer settings, WorldGenerator worldGenerator) {
    Pumpkin pumpkinPopulator = Pumpkin.builder().perChunk(12).build();
    worldGenerator.getPopulators().add(pumpkinPopulator);
}

Kebalikan dari contoh sebelumnya, kali ini anda menciptakan populator baru sepenuhnya. Untuk melakukan hal ini, pertama-tama anda harus mendapatkan pembentuk dari populator tersebut. Kemudian tentukan pengaturan populator sesuai dengan keinginan anda kedalamnya - dalam hal ini, kita menginginkan lusinan labu untuk tumbuh setiap bidang. Akhirnya, tambahkan populator baru anda kedalam daftar dari populator yang diterapkan secara menyeluruh kedunia.

Voila, sekarang kita memiliki labu dimana-mana.

Catatan

In this example we added the pumpkin populator to the end of the populators list, but it should be noted that this list is order dependent. So, if you would like your populator to be called earlier than other populators, as is usually a good idea with Forest populators, then you should add your populator to the start of the list.

Kedua contoh ini seharusnya dipakai untuk membantu anda akrab dengan dunia pekerjaan dari populator vanilla. Hal ini hanya menyentuh permukaan dari apa yang memungkinkan. Lihatlah javadocs untuk daftar lengkap dari populator yang tersedia dan peroperti mereka.

Menciptakan dasar Daerah buatan

Mengubah dasar GenerationPopulator dari pembuat dunia memungkinkan anda untuk mengubah bentuk daerah buatan dari dunia itu. Sebuah pembuat populator kira-kira akan mengikuti tata cara menggunakan informasi benih dan biome untuk menanam dan mengubah rangkaian dari noise maps, dari mana daerah tersebut dibentuk. Daerah yang diciptakan didalam sebuah modifikasi pembuat dasar populator seharusnya hanya terdiri dari blok batu, yang mengizinkan biome untuk mengganti blok secara tepat meliputi tanah biome yang spesifik.

public class SinusoidalGenerator implements GenerationPopulator {

    @Override
    public void populate(World world, MutableBlockVolume buffer, ImmutableBiomeVolume biomes) {
        for(int x = buffer.getBlockMin().getX(); x < buffer.getBlockMax().getX(); x++) {
            for(int z = buffer.getBlockMin().getZ(); z < buffer.getBlockMax().getZ(); z++) {
                BiomeType biome = biomes.getBiome(x, 64, z);
                int height = getHeight(x, z, world.getWorldGenerator().getBiomeSettings(biome));
                for(int y = 0; y < height || y < 64; y++) {
                    if(y < height) {
                        buffer.setBlockType(x, y, z, BlockTypes.STONE);
                    } else {
                        buffer.setBlockType(x, y, z, BlockTypes.WATER);
                    }
                }
            }
        }
    }

    private int getHeight(int x, int z, BiomeGenerationSettings biome) {
        double sx = Math.sin(x / 64d) + 1;
        double sz = Math.sin(z / 64d) + 1;
        double value = (sx + sz) / 4d;
        double heightRange = biome.getMaxHeight() - biome.getMinHeight();
        double height = heightRange * value / biome.getMinHeight();
        return GenericMath.floor(height * 256);
    }
}

Hal ini merupakan contoh yang cukup sederhana dari sebuah dasar daerah generasi populator (setidaknya, jika anda melihat kedalam perhitungan yang lalu untuk menghitung tingginya). Untuk setiap kolom didalam daerah penyangga kita ingin menghitung nilai tingginya, dan kemudian memasukkan semua yang dibawahnya dengan batu dan meninggalkan semua yang diatasnya sebagai udara (atau air jika kita masih dibawah laut).

Menciptakan GenerationPopulators buatan

Catatan

API untuk GenerationPopulators buatan sendiri belum diselesaikan. Bagian ini akan dikembangkan dimasa depan.

Menciptakan Populators buatan

Populator buatan dapat digunakan untuk menambahkan variasi yang baik dari fitur buatan. Untuk menciptakan sebuah populator buatan anda hanya harus membuat class yang menjalankan bagian penghubung Populator dan menambahkannya kedalam daftar dari populator yang terpasang kedalam biome, atau kedalam pembuat dunia jika anda ingin menerapkannya secara menyeluruh.

Populator buatan anda akan dilewatkan sebuah Extent yang merupakan sebuah pandangan keatas dunia yang meliputi daerah yang seharusnya anda terapkan kedalam populator anda. Sangat disarankan bahwa anda jangan membuat dugaan apapun atas ukuran yang diharapkan atau posisi luasnya, karena mungkin akan lebih besar atau kecil untuk operasi memperbaharui bongkahan.

Catatan

Untuk mengizinkan populator anda untuk melengkapi batas wilayah bongkahan, populator anda diizinkan untuk memperluasnya sampai 8 blok diluar sebagian batas wilayah.

Menciptakan Biomes buatan

Selagi sedang tidak memungkinkan untuk menciptakan seluruh biome baru dari dalam sponge, anda dapat mengubah sistemnya dimana mereka disusun kedalam dunia yang menjalankan penghubung BiomeGenerator dan atur biome generator buatan anda kedalam sebuah Worldgenerator.

Berikut adalah contoh pembuat biome yang menciptakan satu pulau besar yang berpusat di sekitar (0, 0).

public class IslandBiomeGen implements BiomeGenerator {

    private static final double ISLAND_SIZE = 200f;
    private static final double BEACH_RADIUS = ISLAND_SIZE * ISLAND_SIZE;
    private static final double FOREST_SIZE = ISLAND_SIZE - 7;
    private static final double FOREST_RADIUS = FOREST_SIZE * FOREST_SIZE;
    private static final double HILLS_SIZE = FOREST_SIZE - 120;
    private static final double HILLS_RADIUS = HILLS_SIZE * HILLS_SIZE;

    @Override
    public void generateBiomes(MutableBiomeVolume buffer) {
        Vector3i min = buffer.getBiomeMin();
        Vector3i max = buffer.getBiomeMax();

        for (int x = min.getX(); x <= max.getX(); x++) {
            for (int z = min.getZ(); z <= max.getZ(); z++) {
                if (x * x + z * z < HILLS_RADIUS) {
                    buffer.setBiome(x, 64, z, BiomeTypes.EXTREME_HILLS);
                } else if (x * x + z * z < FOREST_RADIUS) {
                    buffer.setBiome(x, 64, z, BiomeTypes.FOREST);
                } else if (x * x + z * z < BEACH_RADIUS) {
                    buffer.setBiome(x, 64, z, BiomeTypes.BEACH);
                } else {
                    buffer.setBiome(x, 64, z, BiomeTypes.OCEAN);
                }
            }
        }
    }
}