This tutorial is set by the author to use the CC By-NC-SA protocol.
Zero, write in front
Agreement and Declaration
Note that the content of this article uses the CC: by-NC-SA protocol. Most of the code in this article is cut from the emerald process and uses the MIT protocol; the other specially explained code is mainly based on the Minecraft source code compiled by FORGE, all functions, classes, and classes, classes, and classesThe name of the member variables uses an official anti -confusion table. Function parameters and local area variables are named after learning according to the author's personal understanding.
Because of the expansion of this MOD, the author did not find the works of other people, and the official did not make good documents or Wiki instructions on APIs.Therefore, the author wrote the Chinese tutorial in this article for developers to communicate and learn and save reading code. I hope that the excellent group MOD in China to stagnate because of caves and cliffs can rejuvenate.
This tutorial uses the default readers to have the basic understanding of Java code ability and MOD development.
Configure build.gradle
First of all, you have to find the right TerraBlender version here, such as the TerraBlender V2.0.1.128 of 1.19.2.
Then, you have to add the corresponding Maven to download the URL to the Build.gradle. In addition to MinecraftForge, you also need to join SPONGEPOWERED MIXIN:
Buildscript {Repositories {
Maven {url = 'https://maven.minecraftForge.net'}
Jcenter ()
Mavencentral ()
Maven {name = "sponge"; url 'https://repo.spongepowered.org/repository/maven-public/'}
}
Dependencies {
Classpath group: 'net.minecraftForge.Gradle', name: 'forgegradle', version: '5.1.+', Change: true: true
Classpath 'org.spongepowered: mixingradle: 0.7.32'
}
}
apply plugin: 'org.spongepowered.mixin'
Then, add SpongepPowered Mixin and TerraBlender to DEPENDENCIES:
Dependencies {Minecraft 'net.minecraftForge: Forge: 1.19.2-43.2.0'
// Compileonly fg.deobf ("Mezz.jei: Jei-1.19.2-Forge: 11.5.0.297")
AnnotationProcessor 'ORG.SPONGEPORED: mixin: 0.8.5: Processor'
Implementation fg.Deobf ("com.github.glityFiend: TerraBlender-Forge: 1.19.2-2.0.1.128")) // TerrablenderEnterer
}
Executive construction, Gradle will help you download TerraBlender for you to call your API.
Configure mods.toml
The front module information also needs to be added in the MODS.TOML, which is convenient for players who do not install the front to run the module to report an error to report the problem.Of course, even so, there will always be a picture of a picture that comes up and upload the wrong report.Module developers should have a big heart, and they must not be surprised when anyone meets.
There are two types of front, one is the necessary front, such as TerraBlender is a necessary prefix for Byg and BOP.The other is the optional front, such as TerraBlender is the available prefix of Quark.The difference is that when the necessary front is not installed, the expansion of the MOD cannot work; but the installation of the optional front will not affect the work of expanding the MOD. The only situation that may affect its work is that the version of the optional MOD is incorrect.
The preceding statement should be written in [[dependencies.modid]], such as the emeblender of the emerald process, the necessary prefix is added to TerraBlender:
[DependenCies.emeraldCraft]]Modid = "TerraBlender"
MANDATORY = TRUE
VersionRange = "[2.0.1.128,)" "
Ordering = "None"
Side = "Both"
You can only change the mandatory to FALSE in front, but the actual project code must also be judged. If the front MOD is not installed, do not load the category of the pre -MOD -related API!
1. The difference between 1.18+and pre1.17.1 group registration
1. PRE1.17 group registration and generation
Friends who are familiar with the low version of MOD know that before 1.17.1 and before, FORGE has provided various interfaces for group registration and generating. The most representative include group dictionary:
biometricTionary $ addtypes (registryKeybiomeKey, biometingary.type ... Types)
For example, we can achieve such a group:
Private Static biome nethergarden () {// The creature in the group
Mobspawninfo mobspawninfo = new mobspawninfo.builder ()
.Addspawn (EntityClassification.Monster, New Mobspawninfo.spawners (EntityType.zombified_piglin, 2, 2, 4). n.Monster, New Mobspawninfo.spawest (EntityType.hoglin, 1, 3, 4)
.Addspawn (EntityClassification.Monster, New Mobspawninfo.spawners (EntityType.piglin, 5, 3, 4))
.Addspawn (EntityClassification.Monster, New Mobspawninfo.spawners (EntityType.engerman, 2, 1, 2))
.Addspawn (EntityClassification.creature, New Mobspawninfo.spawners (EntityType.Strider, 10, 1, 2)). Build ();
// Surface builder and structure generation used by group system
BiomegeenerationSettings.Builder biomegeenerationSettings $ Builder = New BiomegenerationSettings.builder ()
.SurfaceBuilder (ecconfiguredsurfacebuilders.nether_garden)
.AdDRUCTURURESTARTART (StructureFeatures.runed_Portal_Nether))
.Addcarver (GenerationStage.carving.Air, Configuredcarvers.nether_cave)
.AdDRUCTURURESTARTART (StructureFeatures.nether_bridge)
.AddStructureStart (StructureFeatures.bastion_remnant)
//.AddstrusTartArturestAntart_Structurefeatures.stronghold) .addfeature (GenerationStage.Decoration.vegetal_Decoration, Features.spring_lava);
//
DefaultBiomefeatures.adddefaultMushrooms (BiomegenerationSettings $ Builder);
BiomegeenerationSettings $ Builder.addfeature (GenerationStage.Decvice.UnderGround_Decorn, Features.Spring_open)
.Addfeature (generatingStage.Decvice.underground_Decy, Features.patch_fire)
.Addfeature (GenerationStage.Decvice.underground_Decora, Features.glowstone_Extra)
.Addfeature (generatingStage.Decvice.UnderGround_Decoration, Feata.glowstone)
.Addfeature (GeneatureStage.Decvice.underground_Decy, Features.ore_magma)
.Addfeature (GenerationStage.Decvice.UnderGround_Decoration, Features.spring_Closed)
.Addfeature (GenerationStage.Decvice.vegetal_Decoration, Features.weeping_vines)
.Addfeature (GenerationStage.Decvice.vegetal_Decoration, Features.twisting_vines)
.Addfeature (GenerationStage.Decvice.vegetal_Decora, Features.cripson_fungi)
.Addfeature (GenerationStage.Decoration.vegetal_Decoration, Features. Crimson_Forest_vegetation) .addfeature (GenerationStage.DecoTal_Decoration , Features.Warped_fungi)
.Addfeature (GenerationStage.Decvice.vegetal_Decoration, Features.Warped_Forest_vegetation);
DefaultBiomefeatures.addnetherDefaultores (BiomegenerationSettings $ Builder);
// Other instructions in the group
Return new biome.builder (). Precipity (biome.raintype.none) .biomecategory (biome.category.nether))
.Depth (0.1F) .scale (0.2F). Temperature (2.0F) .downFall (0.0F)
.Specialeffects (New BiomeAmbinence.builder ()
.WaterColor (4159204) .waterfogColor (329011) .fogColor (12169636) .skycolor (Calculaterskycolor (2.0F))
.AmbientParticle (New ParticleEffectAmbinence (ParticleTypes. Crimson_spore, 0.025F))
.AmbientLoopSound (soundEvents.ambient_crimson_Forest_loop)
.AmbientmoodSoundd (New MoodSoundAmbinence (Soundevents.Ambient_Crimson_forest_mood, 6000, 8, 2.0d))
.ambientAdditionsSound(new SoundAdditionsAmbience(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS, 0.0111D)) .backgroundMusic(BackgroundMusicTracks.createGameMusic(SoundEvents.MUSIC_BIOME_CRIMSON_FOREST)).build())
.MobspaWNSettings (mobspawninfo) .GenerationSettings (biomegenlantSettings $ Builder.build ()). Build ();
}
Briefly explain the various parameters in Biome.builder:
Precipition is precipitation, which means whether the rainy group system is snowy (snow -threaded leaf forest, snowfield, etc.) or rain (plain, deep sea, etc.) or drought (desert, tropical grassland).None.
Biomecategory represents the type of group system. All the lower -bounds group shares the Nether type.The ocean is Ocean and so on.
DEPTH indicates that the height of the group is relatively sea level. The DEPTH value of the alpine group system is large, the general principle is close to 0, and the ocean is negative.Of course, this attribute is removed in 1.18+.
SCALE means the degree of ups and downs of the group, pay attention to distinguish between high degree. For example, although the DEPTH value is large, the SCALE value is close to 0.Therefore, the evil plateau is high and flat, while the wind attacks the evil land like hills.Like DEPTH, this value was later removed.
WaterColor, WaterfogColor, FogColor, and Skycolor represent the color of the water in the group, the color of the fog in the water, the color of the fog in the distance, and the color of the sky. This is an RGB value. The converting into the form of 0XRRGGBB is the form of 0xrrggbb -The water of the warm sea is green, and the water of the cold water ocean is the role of the first two values, while the background of the soul sand canyon is blue and the crimson forest background is red and is the role of FogColor.
AmbientParticle, AmbientLoopsound, AmbientmoodSound, AmbientAditionSlet, respectively represent groups, group environmental sound effects, group atmosphere sound effects, and group -based random sound effects.Backgroundmusic is a background music that will be played randomly in the group.
Mobspawnsettings is a biological generation registered earlier. GenerationSettings is a world generation registered in the previous article, including group surfaces, structures and grounds.
Call this factory function to generate a lower -bound garden group. By subscribe to registryevent.register
After registering, use the following interface to register the group to the main world:
biomemanager $ addbiome (biometype type, biomentry entry)
Registering to the lower boundary requires Mixin injection to modify NetherbiomeProvider $ Parameters member variables.
In addition, it is best to register your group's group dictionary mentioned earlier, so that the content added by other modules can work normally in your group.
In addition, Surface Builder. This thing is like its name, which realizes the surface structure of the group.Taowa Mountain, these are the credit of Surface Builder.The Surface Builder source code of the above group is as follows:
Public Class NETHERGARFARFARFARFAILEDER Extends NETHERFARFARFARFARFARDERDER {Public NethergardensurfaceBuilder (Codec
Codec) Super (codec);
}
@Override
Public Void Apply (@NONNULL RANDOM RANDOM, @NONNULL Ichunk Chunk, @NONNULL BIOME BIOME, INT X, INT Z, Int Startheight, Double Noise
@Nonnull blockstate defaultBlock, @nonnull blockstate defaultfluid, int SurfaceLevel, long seed, @Nonnull SurfaceBuilderConfig Config) {
Double noise2 = biome.biome_info_noise.getValue ((double) x*0.03125d, (double) z*0.03125d, false);
If (noise2> 0.0d) {
Super.Apply (Random, Chunk, Biome, X, Z, Startheight, Noise, DefaultBlock, DefaultFLUID, SurfaceLevel, SurfaceBuilder.config_Crimson_For ESt);
} Else {
Super.apply (Random, Chunk, Biome, X, Z, Startheight, Noise, DefaultBlock, DefaultFLUID, SurfaceLevel, SurfaceBuilder.config_Warped_For ESt);}
}
}
It's very simple. Use a noise to determine the surface of the current position. Half of the scarlet bacteria and the other half are strange fungus rocks.
The group system of Pre1.17.1 is very simple to generate underlying logic. Through the rough noise of Berlin, after a series of enlargement, Rolling and adjacent effects, the characteristics of temperature, humidity, sea and land are smooth and controllable. Finally, according to the Surface BuilderGenerate height diagram, add ground objects and structure-remember this order, rough generation-amplification-filling group system-interaction-(several cycles) -On the height diagram.Interested friends can search for more detailed introductions on station B.
2. 1.18+ group generation mechanism
The 1.18+ generation mechanism is the opposite of Pre1.17.1 -the world generates five Berlin noise with temperature, humidity, land, erosion, and strangeness, which corresponds to the T, T, and T, and T, T, T, T, and Display DEBUG information in the single -player world.V, C, E, and W value; then generate the basic height chart of the world according to terrestrial and erosion, and then put the group into the corresponding area-unlike the previous method, this is a noise generation-generating height chart map-Crill generation-amplification-filling group.
The terrestrial nature is actually the evolution of the previous DEPTH. It is lower than -1.05 is Mushroom Island, from -1.05 to -0.455 is the deep sea, -0.455 to -0.19 is the ocean, -0.19 to -0.11 is beaches (beaches, stone shores, etc.).-0.11 to 0.3 is a variety of inland groups, while higher than 0.3 is a mountain.Extracting is the evolution of Scale. The greater the value of this value, the more rugged the terrain.At this time, the boundary of different groups, plateau, or equality is meaningless, so the original version deleted dozens of groups that are no longer used.
Overworkdbiomebuilder gives the group that is "posted" into the world. Overworldbiomebuilder $ Middle_biomes:
Private Final ResourceKeke[] [] middle_biomes = new resourceKey [] [] {{{] {{{] { Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_TAIGA, Biomes.TAIGA },
{Biomes.plains, biomes.plains, biomes.forest, biomes.taiga, biomes.old_growh_spruce_taiga},,},,
{Biomes.flower_Forest, biomes.plains, biomes.Forest, biomes.birch_Forest, biomes.dark_forest}, {biomes.savanna, biomes.savanna, biomes, biomes .Forest, biomes.jungle, biomes.jungle},
{Biomes.Desert, biomes.Desert, biomes.desrt, biomes.desrt, biomes.desrt}
};
In the Pickmiddlebiome function, the meaning of this two -dimensional array is given:
Private ResourceKekeyPickmidDlebiome (INT TEMPERATURE, INT HUMIDITY, CLIMATE.PARAMETER Weirdness)) If (werydness.max () <0L) {{
Return this.middle_biomes [temperator] [humidity];
}
ResourceKey
ResourceKekey = this.middle_biomes_variant [tempicular] [humidity]; Return ResourceKeke == NULL? This.middle_biomes [Temperature] [Humidity]: ResourceKey;
}
Obviously, each line of the array represents a temperature value, from top to bottom from cold to hot; and each column represents a humidity value from left to right from dry to humidity.When the strange value is greater than 0, the group will tend to become its variants, such as bamboo forests, sparse jungles, and sunflowers plains.Of course, in addition to these three values that affect the generation of group systems, terrestrial properties will affect the choice of sea and land group pools, while rivers and other are related to erosive and strange values.The overworldbiomebuilder did not give other MOD APIs, so TerraBlender came into being. Through various code injection, developers provided the developers with interfaces to achieve related operations.
Then the first problem is solved, but the second problem has appeared again. The surface of the group is very different. How to achieve this difference?
We know that the low version can achieve the surface structure of the group through the Surface Builder, and the high version has become a Surface Rule. The Surface Rule of the main world is in the SurfaceRuledata $ OverworldLike function.Various If-Else, I sorted out and shared it in the attitude of a wonderful text: the original moderator World Surface Rule finishing version.
Suddenly understood that General Fan Da scolded his national football, and the Surface Builder, which was implemented by multiple files, did well. Why did you replace it?
So if we want to generate our own group, in addition to solving the group system into the world, we also need to solve the problem of the injection of Surface Rule -TerraBlender also provides a new API to help you realize and modify you to realize and modify youSurface Rule adds to the world generation stage.
Let's introduce the use of these two APIs.
2. Region (BiomeProvider)
1.18.2+ This interface is TerraBlender.api.region, while 1.18.1 is TerraBlender.api.biomeProvider.The two are slightly different. BiomeProvider needs to register the main world and the lower boundary system at the same time, and Region can select Regionspe.overWorld and RegionType.nether in the constructor.The following uses Region to explain. BiomeProvider is not much different from region, so the authors of the 1.18.1 module can analyze themselves.
1. Construction function
The constructor of region is
Region (ResourceLocation name, regionspe type, int weight)
Name is the registration name for TerraBlender managed. It is recommended to implement it in the form of Modid: name; Type represents the main world or the lower bound; weight is the weight of the region. TerraBlender's config can adjust the weight of the original and lower world.
2. Direct load function
The prototype of the member function that you must re -loaded is as follows:
Public void addbiomes (registryregistry, consumer >> MAPP ER)
TerraBlender will call this function, and what you have to do is to register each parameter (temperature, humidity, terrestrial, erosion, strangeness, and depth) generated by the group system.
The 1.18.1 BiomeProvider writing is special. You need to obtain the independent digital ID of the region through BiomeProvider $ getuniquesSparameter (), and register it as a parameter.This step is obviously not perfectly encapsulated, and the follow -up code has been fixed.
你可以自行实现你的OverworldBiomeBuilder,或是和BYG一样通过继承OverworldBiomeBuilder实现自己的主世界群系生成器——毕竟写法与原版相似,这种做法鲁棒性高一些,而且需要mixin,不过与其他群The effect of generating the world together may be worse, please weigh it yourself.
3. Inheritance example of Region
The source code of the emerald craft has adopted two different practices to achieve the inheritance of the region for the main world and the lower boundary.Three.Main world:
Public Class EcoverworldBiomeregy Extends Region {Public Static Final ResourceLocation Location = New ResourceLocation (Modid, "Overworld_biome_provider");
Public ecoverworkdbiomeregy (int weight) {{
Super (local (local, regionspe.overWorld, weight);
}
@Override
Public void addbiomes (registry
registry, consumer >> Mapper) { (New Ecoverworldbiomebuilder ()). Addbiomes (registry, mapper);
}
}
Boundary:
Public Class Ecnetherbiomeregy Extends Region {Public Static Final ResourceLocation Location = New ResourceLocation (Modid, "Nether_biome_provider");
Public Ecnetherbiomeregy (int weight) {{
Super (local (local, regionspe.nether, weight);
}
@Override
Public void addbiomes (registry
registry, consumer >> Mapper) { this.addbiome (Mapper, Climate.parameter.point (0.0F), Climate.parameter.point (0.0F), Climate.parameter.point (0.0F), climate.parameter.point (0.0F) (0.0F) Climate.parameter.Point (0.0F), climate.parameter.point (0.0F), 0.0F, biomes.nether_wastes); this.addbiome (mapper, climate.parameter.point (0.0F), climate.parameter. Point (-0.5F), Climate.parame.point (0.0F), Climate.parameter.point (0.0F), Climate.parameter.point (0.0F), Climate.parameter.point (0.0F), 0.0F, Biomes.soul_s And_valley);
This.addbiome (Mapper, Climate.parameter.point (0.4F), Climate.parameter.point (0.0F), Climate.parameter.point (0.0F), climate.parameter.point (0.0F) (0.0F) Climate.parameter.Point (0.0F), climate.parameter.point (0.0F), 0.0F, biomes.crimson_Forest);
This.addbiome (Mapper, Climate.parameter.point (0.0F), Climate.parameter.point (0.5F), Climate.parameter.point (0.0F), climate.parameter.point (0.0F) (0.0F) Climate.parameter.Point (0.0F), climate.parameter.point (0.0F), 0.375F, biomes.warped_Forest);
this.addbiome (mapper, climate.parameter.point (-0.5F), climate.parameter.point (0.0F), climate.parameter.point (0.0F), climate.parameter.point (0.0FFINT (0.0F) ), Climate.parameter.point (0.0F), climate.parameter.point (0.0F), 0.175F, biomes.basalt_deltas);
If (biomeutil.iskeyregisterEd (registry, ecbiomekeys.emery_desert)) {
this.addbiome (mapper, climate.parameter.point (-0.8F), climate.parameter.point (-0.8F), climate.parameter.point (0.0F), Parameter.point (0.000.00) F), climate.Parameter.point (0.0F), Climate.parameter.point (0.0F), 0.0F, ECBIOMEKEYS.EMERY_DESERT.KEY ());};};};};};};};};};};};};
If (biomeutil.iskeyregisterEd (registry, ecbiomekeys.purpuraceus_swamp)) {
This.addbiome (Mapper, Climate.parameter.point (0.7F), Climate.parameter.point (0.7F), Climate.parameter.point (0.0F), climate.parameter.point (0.0F) Climate.parameter.Point (0.0F), climate.parameter.point (0.0F), 0.125F, ECBIOMEKEYS.PURPURACEUS_SWAMP.KEY ());););
}
If (biomeutil.iskeyregisterEd (registry, ecbiomekeys.quartz_desrt)) {
this.addbiome (mapper, climate.parameter.point (0.75F), climate.parameter.point (-0.7F), climate.parameter.point (0.0F), Parameter.point (0.000.000) F), climate.parameter.point (0.0F), climate.parameter.point (0.0F), 0.0F, ECBIOMEKEYS.quartz_desrt.key ()););););););););););
}
}
}
Deeply, the difference is not large as a whole, but the former was packaged into another object, and the latter directly completed the group addition in the function body.
4. Register to regions
You need to register your region to regions in a function (that is, Pre-Init) to subscribe to the FMLCOMMONSETUPEVENT event. You need to pack it with the event.enqueuework () to prevent multi-threaded conflicts.Example writing is:
regions.register (new ecoverworldbiomeregyThe weight of the config control area is used here. Of course The value of the configuration is obviously easierUser acceptance.Regions.register (New Ecnetherbiomeregy (eccommonconfig.eMerald_Craft_nether_Biomes_weight.get ()));
In this way, the group can be added to the world.1.18.1 only needs to change regions to BiomeProviders.
5. Registration and construction of the group
The previous article briefly introduced the original OverWorldBiomebuilder. It is necessary to introduce a detailed introduction to how module developers write their own OverworldBiomebuilder.
The second parameter of the addbiomes function is to add a group consumption function. The method is added:
Mapper.Accept (pair.of (parameters, biome));
Parameters is a climate.parameterpoint type. There are two most commonly used factory functions in the Climate class:
Public Static Climate.parameterpoint Parameters (Float Temperature, Float Humidity, Float Continentalness,Float Eross, Float DEPTH, Float Weirdness, Float Offset) {
Return New Climate.parameterpoint (
Climate.parameter.point (temporarative),
Climate.parameter.point (humidity),
Climate.parameter.point (continentalness),
Climate.parameter.point (erosion),
Climate.parameter.point (depth),
Climate.parameter.point (weirdness),
Quantizecoord (Offset)
);
}
Public Static Climate.parameterpoint Parameters (Climate.parameter Temperature, CLIMATE.PARAMETER HUMIDITY, C LIMATE.PARAMETER Continentalness, Climate.parameter Eross,
Climate.parameter depth, climate.parameter weirdness, float offset) {
Return New Climate.parameterpoint (
Temperanture, Humidity, Continentalness, Erity, DEPTH, Weirdness, QuantizeCoord (Office)
);
}
It is recommended to use the following, and the passing parameters can be selected from TerraBlender.api.parameterutils, such as::
Mapper.Accept (pair.of (climate.parametersParameterutils.temperature.full_range.parameter (),
Parameterutils.Humidity.humid.parameter (),
Parameterutils.continentalness.far_inland.parameter (),
Parameterutils.erOSION.SPAN (Parameterutils.erOSION_5, Parameterutils.erOSION.EROSION_6),),), Parameterutils.erOSION_6),),),),
Parameterutils.Depth.underground.parameter (),
Parameterutils.weirdness.full_range.parameter (), 0.5F
), CustomBiomekeys.mossy_caves.key ());
The above approach can add a group named "Cave Cave Cave" to the generation of the world. Under any temperature and strangeness, the erosion is high and the very moist inland areas are generated.In addition, the value of the offset is 0.5. This value is 0 default.
Of course, it is very recommended that developers follow the logical adding group of the original OverworkDbiomebuilder.
Third, the registration and implementation of Surfaceerule
1. SurfaceRule registration
The registration of SurfaceRule provided by TerraBlender is very simple. 1.18.1 needs to use the following two member functions of generatingSettings to register the main world and the lower boundary group:
Public Static Void AddBeForebedrockoverWorldSurfaceres (SurfaceRules.rulesource Rules)Public Static Void AddBeForebedrockNethersurfaceres (Int Priority, Surfaceres.rulesource Rules)
1.18.2+ changed the function name, using the Surfaceremanager $ AddSurfaceRules function to register, such as::
Surfaceremanager.addsurfaceres (SurfaceRuleManager.ruCategory.overWorld, Modid, ECSURFACERULELD ());SurfaceRuleManager.Addsurfaceres (SurfaceRuleManager.ruCategory.nether, Modid, ECSURFACERULES.NETHER ());
This process also needs to be written in functions that subscribe to FMLCOMMONSETUPEVENT event. In order to prevent thread conflict, it is necessary to be carried out in the task queue provided by the incident.It is recommended to write directly in front of the two sections of registered to regions.
2. The implementation of SurfaceRule
The only thing that is uncomfortable is the implementation of Surfaceres. Here is an idea. First, copy the factory function in the original SurfaceRuledata, and then compare the groups you want to achieve with the original group system. Choose the most similar realization of the surface.One, use Ctrl+F to mark the group, and then add modification directly behind it -this tests the development level of the developer's understanding of the original group of the high version.
For the simplest example, the emerald craft adds the ginkgo forest group. The surface is mainly based on the grass squares, with the generation of fern and ginkgo trees. At the same time, part of the surface is covered with gray soil.For this demand, we must first distinguish what is the surface and what is the ground.Obviously, both ferns and ginkgo trees are ground, but the grass and gray soil are surface.
Furthermore, what other groups have added gray soil?The original knowledge tells us that the giant coniferous forest/primitive pine wooden coniferous forest system, giant spruce coniferous forest/primitive spruce coniferous forest system and bamboo forest group have added gray -mounted soil.However, the slightly antipity is that the gray and soil of the bamboo forest is actually a ground matter instead of the surface (after all, the original new group system is a shit mountain), but the gray soil of the other two groups is indeed true that it is indeed true that it is indeed true that it is indeed true that it is indeed true.On the surface, we can search biomes.old_growth_pine_taiga and biomes.old_growth_sprure_taiga:
On the surface, there is a group of gray -based soil, and it is only necessary to add it directly to the back:
// ......Surfaceerules.IFTRUE (
Surfacerules.isbiome (biomes.windswept_gravelly_hills), SurfaceRules.Sequence (
Surfaceerules.IFTRUE (Surfacenoiseabove (2.0D), StonelINEDGEL), StonelINEDGEL), Stone
Surfaceerules.IFTRUE (Surfacenoiseabove (1.0d), Stone), Stone, Stone), Stone, Stone), Stone,
SurfaceRules.IFTRUE (Surfacenoiseabove (-1.0D), Grasssurface), Grasssurface,
StoneEdgravel
Cure
),,
Surfaceerules.IFTRUE (
Surfaceres.isbiome (biomes.old_growth_pine_taiga, biomes.old_growth_spruce_taiga),),,),,),,),,),
Surfaceres.sequare (
SurfaceRules.IFTRUE (Surfacenoiseabove (1.75D), Coarse_dirt), Coarse_dirt),
Surfaceerules.IFTRUE (Surfacenoiseabove (-0.95D), Podzol)
Cure
),,
Surfaceres.IFRUE (SurfaceRules.isbiome (biomes.ice_spikes), SurfaceRules.IFTRUE (isabovewaterlevel, snow_block)))), Snow_block)
Surfaceres.IFTRUE (Surfacereules.isbiome (biomes.mushroom_fields), Mycelium), Mycelium), Mycelium), mycelium)
Surfaceerules.IFTRUE (
Surfaceerules.isbiome (ecbiomekeys.ginkgo_Forest.key ()),),),),
Surfaceerules.IFTRUE (SurfaceRules.noiseCondition (Noises.Surface, 0.6D), Podzol)
),,
grassurface
//...... pre>
Surfaceerule is actually trying to match the process of constantly Fall BACK. For only part of the section (the wind raid tropical grassland and various mountain groups).Code, the meaning is: If the current group is a wind-raid hill, the STONELINEDGEL is preset at the STONELINEDGEL presets when the Surface noise is greater than 2.0.StonelineDGravel is preset for production; if the current group is not a wind-raid hill, but two primitive coniferous forests, it is still based on the selection of the Surface noise.It is temporarily put on hold (how to deal with it in the end); if the current group is the ice thorn plain, and the altitude is higher than the sea level, then the surface is generated on the surface, otherwise it will be cut;If the current group is ginkgo forest, and the noise noise is greater than 0.6, then the surface is gray -produced soil, otherwise it will be put on hold; in the end, the unprecedented group (plain, forest, tropical grasslands, snowfields, etc.), and all shelved conditions, pressGrassurface is preset -therefore, the surface of most groups is grass squares (desert, evil land and other groups do not take this preset, which are considered separately).The Surface Berlin noise generator is used here. In fact, the original version has several auxiliary tables to generate realized Berlin noise. It is located in net.minecraft.World.Levelgen.noises. Of course, you can also achieve Berlin noise independent of them.These noise can be used for strip -shaped production (such as the square -breed stone band of the naked rock peak), dot -shaped generating (such as frozen ice and ice cubes), blocking (such as large stones that strike the hills), and so on.The difference is that strip -shaped production usually only accepts a large range of noise, and dot -shaped generation is only accepted the range of extreme values or smaller noise, while block shape is acceptable to all noise from or less than a certain value.value.
Fourth, summary
The above is the author's clumsy opinion on the use of TerraBlender modules and tutorials. If there is no perfect or unknown, please point out.If there are other content that needs to be updated, the author will also modify it as soon as possible!