Modificando la Generación Mundial
Advertencia
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!
Modificando la Generación Vainilla
Creando Terreno de Base Personalizada
Creando GenerationPopulators Personalizados
Creando Populadores Personalizados
Creando Biomas Personalizados
Modificando la Generación Vainilla
Nota
Esta página asume que está familiarizado con la configuración de su WorldGeneratorModifier. De lo contrario, lea el artículo sobre cómo configurar su modificador en WorldGeneratorModifiers.
Sponge expone una gran cantidad de generación de mundo vainilla, que puede ser manipulada a través de las diversas interfaces. Actualmente, los únicos elementos del proceso de generación fácilmente expuestos a la manipulación son los pobladores.
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);
}
}
Comience obteniendo el BiomeGenerationSettings para el bioma del desierto. Este objeto es un contenedor para todas las configuraciones de generación relacionadas con ese bioma. A continuación, recorra la lista de todos los Cactus populadores y establezca la altura en 5, lo que significa que solo puede generar cactus de 5 bloques de altura.
Nota
El Cactus#setHeight(int), y muchos otros métodos similares en otras poblaciones, también toma un VariableAmount que se puede usar para especificar la altura como un rango u otro valor personalizado.
Este ha sido un ejemplo simple de cómo modificar un populador existente. Vamos a ver cómo podemos agregar una nueva instancia de un populador vainilla. Esta vez, el populador se agregará globalmente, lo que significa que se aplicará a todos los fragmentos, independientemente del bioma. Agreguemos un populador de Calabaza globalmente, lo que provoca que las calabazas se dispersen por todo el mundo.
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);
}
Al contrario del ejemplo anterior, esta vez usted está creando un populador completamente nuevo. Para hacer esto, primero necesita obtener un constructor para ese populador. Luego configure las configuraciones deseadas para el populador dentro de este - en este caso, queremos una docena de calabazas para engendrar por parche. Finalmente, agregue su nuevo populador a la lista de populadores que se aplican globalmente al mundo.
Voila, ahora tenemos calabazas en todos lados.
Nota
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.
Estos dos ejemplos deberían servir para ayudarlo a familiarizarse con el ámbito del trabajo con populadores vainilla. Esto solo toca la superficie de lo que es posible. Consulte los javadocs para obtener una lista completa de los populadores disponibles y sus propiedades.
Creando Terreno de Base Personalizada
Cambiar la base GenerationPopulator de un generador mundial le permite cambiar la forma de la generación del terreno base del mundo. Un populador generador seguirá aproximadamente el procedimiento de usar la información semilla y la información de la bioma para sembrar y modificar una serie de mapas, a partir de los cuales se forma el terreno. El terreno creado en un populador generador modificado debe consistir solo en bloques de piedra, para permitir que los biomas reemplacen adecuadamente los bloques para una cobertura del suelo específica del bioma.
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);
}
}
Este es un ejemplo bastante simple de un populador de generación de terreno base (al menos, si mira más allá de las matemáticas para calcular la altura). Para cada columna en el área amortiguada queremos calcular un valor de altura, y luego rellenar todo lo que está debajo con piedra y dejar todo sobre él como aire (o agua si aún estamos debajo del nivel del mar).
Creando GenerationPopulators Personalizados
Nota
La API para GenerationPopulators personalizados aún no está terminada. Esta sección se ampliará en el futuro.
Creando Populadores Personalizados
Los populadores personalizados pueden ser usados para agregar una gran variedad de características personalizadas. Para crear un populator personalizado, usted solo necesita crear una clase que implemente la interfaz de Populator y agregarla a la lista de populadores adjuntos a un bioma, o a un generador mundial si desea que se aplique globalmente.
Su populator personalizado recibirá un Extent
que es una vista del mundo que cubre el área donde debería aplicar su populador. Se recomienda que no haga ninguna suposición sobre el tamaño o la posición esperada de este alcance, ya que puede ser mayor o menor para operaciones tales como la regeneración de un fragmento.
Nota
Para permitir que su populator se superponga con los límites de los fragmentos, su populador puede extenderse hasta 8 bloques por fuera de los límites del alcance.
Creando Biomas Personalizados
Si bien actualmente no es posible crear biomas completamente nuevos dentro de Sponge, puede reemplazar el sistema por el que están organizados en el mundo implementando la interfaz BiomeGenerator y configurando su generador de bioma personalizado en un WorldGenerator.
A continuación se muestra un ejemplo de un generador de bioma que crea una gran isla centrada alrededor de (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);
}
}
}
}
}