2024-12-10 17:52:42|Myriagame |source:minecraft skins
This tutorial is set by the author to use the CC by-NC protocol.
sequence
This tutorial is the TerraBlender development tutorial, with the purpose of helping readers to increase their understanding of this MOD and provide a clearer custom group production method.This tutorial is based on Minecraft FORGE1.20 MOJMAP version, TerraBlender3+as a sample. The use of this MOD in other versions is similar in principle.The overall logic has changed significantly, so there will be certain differences in the parts provided by the MOD (such as the SurfaceBuilder).
The content in this tutorial only represents the understanding of the interface provided by the game body and the MOD.It can be applied for each version and corresponding special conditions.Due to the interface characteristics provided by the module, this tutorial needs to depend on MOD without using data packets. This tutorial will master the basic content of Java and MOD development by default readers.
You can view the source code provided by this MOD on this page, where the MOD author provides samples, and you can find them under the corresponding version of the Example folder.
Preparation
TerraBlender's purpose (selected)
Before the Minecraft 1.18 version, the contents of the group generation, such as the ups and downs of the terrain, the structure contained or the features, and the surface generation (SurfaceBuilder).In the 1.18 version, in order to adapt to the cave update, Mojang modified the production logic of MINECRAFT and generated the attributes of the terrain and the surface from the group.The former is configured by the dimension itself, and is generated by the corresponding noise setting. This part has lower controllability.The latter is also provided by the overall storage as a surface rule resource (SurfaceRules.rulesource) and provided by the OverworldLike method under the SurfaceRuledata.But this kind of change is difficult to say. Here is an important part of the original version of the main world SurfaceRules:
Surfacereules.Conditionsource SurfaceRules $ Conditionsource = Surfaceres.yblockcheck (Verticalanchor.absolute (9 7), 2);[Create the creation of some conditional variables of some conditions]
SurfaceRules.ConditionSource SurfaceRules $ ConditionSource17 = SurfaceRules.noiseCondition (Noises.Surface, 0.5454D, 0.909D)
Surfaceerules.rulesource Surfaceerules $ Rulesource8 =
Surfacers.rulesource Surfaceerules $ Rulesource8 = Surfacereules.Sequence (
Surfacerules.IFTRUE (Surfacereules.on_floor, SurfaceRules.Sequence (
Surfacerules.IFTRUE (Surfacereules.isbiome (biomes.wooded_badlands), Surfaceres.IFTRUE (Surfaceres $ Conditionsource, Surfacereusers.Sequence ( Surfaceerules.IFTRUE (SurfaceRules $ ConditionSource15, Coarse_dirt),
Surfaceerules.IFTRUE (SurfaceRules $ Conditionsource16, Coarse_dirt),
Surfaceerules.IFTRUE (SurfaceRules $ ConditionSource17, Coarse_dirt),
Surfaceerules $ RuleSource
))),,,
Surfacerules.IFTRUE (Surfacereules.isbiome (biomes.swamp), SurfaceRules.i Ftrue (SurfaceRules $ CONDITIONSOURCE5, SurfaceRules.IFTRUE (SurfaceRules.n.n.n OT (SurfaceRules $ ConditionSource6), SurfaceRules.IFTRUE (SurfaceRules.noiseCondition (Noises.swamp, 0.0D),Water))),,,
SurfaceRules.IFTRUE (SurfaceRules.isbiome (biomes.mangrove_swamp), Surfaceres.IFTRUE (SurfaceRules $ Conditionsource4, Surfacereusers.IFTRUE (SUR Facerules.not (Surfaceres $ ConditionSource6), SurfaceRules.IFTRUE (Surfaceres.NoiseCondition (Noises.swamp, 0.0D)Water))))
)),
Surfaceres.IFTRUE (Surfacereules.isbiome (biomes.badlands, biomes.eroded_badlands, biomes.wooded_badlands), SurfaceErules. Sequence RFACERULES.IFTRU (Surfaceres.on_floor, Surfaceres.Sequence (
Surfaceerules.IFTRUE (SurfaceRules $ Conditionsource1, Orange_terracotta), orange_terracotta),
Surfaceerules.IFTRUE (SurfaceRules $ ConditionSource3, Surfacereules.Sequence (
Surfaceerules.IFTRUE (SurfaceRules $ Conditionsource15, Terracotta),
Surfaceerules.IFTRUE (SurfaceRules $ ConditionSource16, Terracotta),
Surfaceerules.IFTRUE (SurfaceRules $ Conditionsource17, Terracotta),
Surfaceerules.bandlands ()
)),
Surfaceerules.IFTRUE (SurfaceRules $ Conditionsource7, Surfacereules.Sequence (
Surfaceerules.IFTRUE (SurfaceRules.on_ceILING, Red_SANDSTONE),
Red_sand
)),
Surfacerules.IFTRUE (Surfacereules.not (SurfaceRules $ ConditionSource10), Orange_terracotta), SurfaceRules.IFTRUE (SurfaceRules $ COND iTionSource9, White_terracotta),
Surfaceres $ RuleSource2
)),
Surfacerules.IFTRUE (SurfaceRules $ Conditionsource2, Surfacereules.Sequence (
SurfaceRules.ifTrue(surfacerules$conditionsource6, SurfaceRules.ifTrue(SurfaceRules.not(surfacerules$conditionsource3), ORANGE_TERRACOTTA)),
Surfaceerules.bandlands ()
)),
Surfacerules.IFTRUE (Surfacereules.under_floor, Surfacereusers.IFTRUE (Surfaceres $ Conditionsource9, White_Terracotta))))))))))))), white_terracotta))
) ... [omit a lot of content]
ImmutableList.builder
Builder = ImmutableList.builder (); if (p_198382_) {
Builder.add (Surfaceerules.IFTRUE (SurfaceRules.not (SurfaceRules.VerticalGradient ("BEDROCK_ROOF", VerticalCalanchor.belowtop (5), Verticalanchor.to p ()), bedrock));
}
if (p_198383_) {
Builder.add (Surfaceerules.IFTRUE (SurfaceRules.VerticalGradient ("Bedrolk_floor", Verticalanchor.bottom (), Verticalanchor.abovebottom (5)), BEDR OCK);}
Surfacers.rulesource Surfaceerules $ Rulesource9 = SurfaceRules.IFTRUE (SurfaceRules.abovePreliminarySurface (), Surfacereules $ Rulesource8);
Builder.add (P_198381_? Surfacerers $ RuleSource9: Surfaceerules $ Rulesource8);
Builder.add (Surfaceerules.IFTRUE (SurfaceRules.VerticalGradient ("Deepslate", verticalanchor.absolute (0), verticalanchor.absolute (8)), Deepsla Te);
Return Surfacerules.Sequence (Builder.build (). Toarray ((p_198379_)-> {{{
Return New Surfacerules.rulesource [p_198379 _];
This process makes its readability extremely reduced, which greatly increases development difficulty. At the same time, the interface that does not provide group generation also makes it difficult for developers to add new groups to existing dimensions and make them generate in a certain style.And TerraBlender provided us to add a new group to the existing dimension (as of the 3.0.0.x version support the main world and the next session), and add to the original RuleSourceBelow, but the basic height judgment method cannot distinguish the huge caves and surfaces of the ground, that is to say, the mistakes in this process often lead to the same surface as the surface in the giant cave underground).These two contents are enough to help us achieve most of the effects.Specific comparisons before and after this change, the predecessors of another tutorial produced under the MOD have already shown it, and I won't go into details here.Interested friends can move here to understand.
Gradle and Mods.toml configuration
Open the build.gradle, find the dependencies part, and add such a line of content:
Implementation fg.deobf ("com.github.glityFiend: TerraBlender-Forge: 1.20.1-3.0.0.167" ")
Among them, the com.github.glitchFiend: TerraBlender-FORGE: 1.20.1-3.0.0.167 is used to specify the source of the library we downloaded. This is a Maven URL. If you want to get a source of MOD, you can refer to this website.EssenceAfter adding the default built.gradle files provided by a development package downloaded by Forge, the DependenCies part should be like this:
Dependencies {Minecraft "net.minecraftforge: Forge: $ {Minecraft_version}-$ {Forge_version}" "
Implementation fg.deobf ("com.github.glityFiend: TerraBlender-Forge: 1.20.1-3.0.0.167")}
Some notes are omitted here.It should be noted that in principle, when adding this dependency library, you do n’t need to add an additional Mixin library. I do n’t affect the startup of the game after annotating the related content of the Mixin library during testing.It is not possible to run the TerraBlender module without adding Mixin library dependencies for the time being.Just in case, posting mixin here requires additional sentences, and the content may be cumbersome, but it can be used after being tested:
Buildscript {Repositories {
Maven {url = "https://maven.aliyun.com/repository/public"}
Maven {url = 'https://maven.minecraftForge.net/'}
Maven {url = 'https://repo.spongepowered.org/repository/maven-public/'}
Mavencentral ()
}
Dependencies {
Classpath group: 'net.minecraftForge.Gradle', name: 'forgegradle', version: '6.+', change: true
Classpath 'org.spongepowered: mixingradle: 0.7-snapshot'
}
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'IDEA'
Apply plugin: 'org.spongepowered.mixin'
// (these contents are added at the beginning of Build.gradle)
Next, we configure the MODS.TOML part, we need to declare the MOD dependencies in the game here.You can find the MODS.TOML file under Resources.meta_inf. We need to add the following content to it:
Modid = "TerraBlender" // This is the library mandatory = true we depend on
VersionRange = "[3.0.0.167,)" //
Ordering = "None"
Side = "Both"
After completing these, you can reload the Gradle project.At this time, Gradle will automatically download the dependent library and build Gradle.This process is recommended to use magic because the process is unstable and most of the cases are slow.Next, perform the Runclient task in Gradle (this process will help us check and make up for the lack of resources, and the Runclient of the Idea (well I only use IDEA) will not go through this step, which may cause MixinFailure to report an error).If the game is successfully started and there is a TerraBlender module in the MOD list, it means that there is no problem with the configuration.
Then enter the topic, let us start adding a new group to the Lord's World.
Biome and Region's creation
Region is a new class provided by TerraBlender for us to coordinate and handle multiple groups that need to be added to the corresponding dimension.Biome is our old friend's biological group.Due to the change of Minecraft, the biological group needs to be added to the packet in the form of JSON.Of course, we can use DataGERATOR to convert a code form into a group of JSON files in the group.
Let's talk about the idea of DataGeneration here:
First create a Biome instance. This part is the same as the old version uses the code to create a group system: a mobspawnsettings.builder is required to configure the creatures generated in the group, and a biomegenrativesettings.builder to configure the characteristics generated in the group.It is worth noting that the configuration of Features must be in accordance with a certain order, that is, the same PlaceDFEature (Note: Configuredfeature of the old version (such as the old version of 1.16.5) was split in the new version as the two parts: ConfigureDfeature and Placedfeature.Configure the configuration of Feature, the latter is responsible for handling the additional Feature under specific conditions, the number and position of the trial generation, similar to the decatured method in the old version of Configuredfeature) can only be used in one STEP, not repeated, and arbitrarily arbitrarily, and arbitrarilyTwo PlacedFeature with Step cannot be replaced, which will cause an error.Therefore, it is recommended to find a similar group that is similar to the group that wants to make and copy the original PlaceDFEATURE sequence that has been maintained, which is stored in the OverworldBiomes class.Finally, create a biome.biomebuilder () to configure special attributes, such as group particles, coloring, sound, etc., and call the build () method to construct a biome.
Next, we should create a ResourceKey
Public Static Final ResourceKeybiome = register ("biome"); Private Static ResourceKey
Register (String name) { Return resourceKey.create (registries.biome, new resourceLocation ("mod_id", "biome");}
Public Static void Bootstrap () {}
This code creates a group named MOD_ID: Biome, and registered it into the registrar of Biome.The bottom Bootstrap method is used to guide Java to loading constant at the right time and register the content. This process should be triggered in the FMLCOMMONSetup event.
在创建BiomeGenerationSettings.Builder时需要传入HolderGetter
Public Static void bootstrap (bootstapcontextcontext) { HOLDERGETER
> c = Context.Lookup (registries.configured_carver); HOLDERGETER
P = Context.Lookup (registries.placed_feature); Context.register (biomeKey.biome, biomemaker.biomeprovider1 (p, c)); // This is the method of your previous registered group ResourceKey and the constructive group examples.
}
Finally, we need to use it in the GatherData incident.This incident will not be triggered at any time after the official startup game. It can only be called in the development environment to call.The code is as follows (assuming the previous method in the Biomeregistry class):
Private Static Final RegistrySetBuilder Builder = New RegistrySetBuilder ().Add (registries.biome, biomeregistry :: bootstrap);
@SubscripeEvent // Note: You need to mark@mod.eventbussubscriber (bus = mod.eventbussubscriber.bus.mod) at the location of the statement.
Public Static Void ONGatherData (GatherDataEvent Event) {
Datagenrator generator = event.getgenrator ();
Packoutput output = generator.getpackoutput ();
CompletableFuture
lookupProvider = event.getLookupProvider(); Generator.addProvider (event.includeserver (), New DataPackBuilTinentriersprovider (output, lookupProvider, Builder, Set.of (Utils.mod_id))
}
Find RUNDATA and run in Gradle's Tasks/Forgegradle Run to generate the corresponding group of JSON files.These files will be generated under the src/generated/resources folder. The position is as shown in the figure:
Let's talk about the use of regions.We need to create a new class and inherit the region class provided by TerraBlender, and then write the adDBiomes method under it.
In terms of structural methods, a resource path needs to be passed as the ID of registered region. A regionType specifies that the region is used in the main world or hell, and a Weight represents the proportion.However, according to the test, Weight does not have a binding range of the group system. It is speculated that the proportion of the proportion of different groups registered by TerraBlender registered.(To be proven)
In the addbiomes method, we need to call the addbiome method under the class (without S, these are two different methods).分别需要提供Consumer
As for what effects these parameters have ... unfortunately, the test found that these values seem to have a little impact on group generation. Therefore, it seems that there is no need to finely control each value.(To be proven)
The example code is given below:
Public Class CommodionRegion Extends Region {Public commonworldRegion (int weight) {{
Super (New ResourceLocation (Utils.mod_id, "CW_Region_Provider"), regionspe.overWerworld, Weight);
}
@Override
Public void addbiomes (registry
registry, consumer >> Mapper) { Super.Addbiomes (registry, mapper); this.addbiome (mapper,
Climate.parameter.span (0.95F, 1.0F), // temperature
Climate.parameter.span (-2.0F, -1.55F), // humidity
Climate.parameter.span (0.165F, 1.8F), // Continental nature
Climate.parameter.span (1.75F, 1.8F), // erosion (ups and downs)
Climate.parameter.span (0.45F, 0.65F), // Strangeness
Climate.parameter.span (0.25F, 0.8F), // depth
0.99f, biomeKey.biome);
}
}
Finally, we need to register region into the corresponding event line:
@mod.eventbussubscriber (bus = mod.eventbussubscriber.bus.mod)Public Class ModbuseventConsumer {
@SubscripeEvent
Public Static Void ONSetup (FMLCOMMONSETUPENT EVENT) {
Event.enqueuework (()-> {{
Regions.register (New CommonworkDregion (4));
BiomeKey.Bootstrap ();});
}
}
Open the game, use/local biome mod_id: biome to find the group we created.
Surfaceerule registered in use
SurfaceRule's basic logic and use
In the high version, SurfaceRule replaces the SurfaceBuilder in the low version.Each block in the world generation phase will be judged by a SurfaceRule to determine what block should be generated by the corresponding position.To put it simply, the basic logic of a long string of unbelievable code we showed above is to enter the next level Surfaceerule for each selected block, first according to the matching of the group.Features generate corresponding squares.If the block is not generated (the back of the back), it is reduced to the default generation rules and generates basic terrain.
Surfacerules This system (hereinafter referred to as a system) consists of the following categories:
RuleSource rules resources are the basic composition of the system.You can store multiple sub -RuleSource under a rulesource that will be executed in order.It does not have the function of determining the formation of the square, which is more like guiding as a registered content.It needs to contain an own decoder Codec <?> It is used to register and implement an apply method to generate the SurfaceRules.Context into the required surface rules.
SurfaceRule's surface rules are truly responsible for implementing the location information into blockState.A TryApply method needs to be implemented here to provide coordinates of the calculation block.But these data may not meet our needs, so if necessary, you can pass the Context in constructing a Surfacererulele.
ConditionSource status resources, analogy of the above -mentioned rules, but this should return a Boolean to indicate whether the corresponding activity should be performed at this position.Correspondingly, it should really determine the coordinates of the Condition class.However, because of its limited effect, the two are often regarded as one.
There are some basic methods in SurfaceRules:
IFTRUE method: This requires a ConditionSource and a RuleSource, and the latter is executed if the former is established.IFTRUE method itself is also a ConditionSource, which can be used for nested.
Sequence method: Multiple RuleSource, multiple RuleSource stored in the pre -pre -conditions will be tried and executed.This can make many RuleSource with the same prerequisites. For example, in the original version, use IFTRUE to determine whether it is a specified group system, and then use Sequence to add all the sub -RuleSource that requires execution in this group.
NOT method: Reverse the result of a ConditionSource.
Makestaterour method: You need to provide a block, which will turn the block into a runsource. You can use it to place the corresponding square when mentioned above.
Some methods or predefined constants are also provided in the SurfaceRules class, such as Isbiome, WaterBlockCheck, YBLOCKCHECK, StoneDepthcheck, etc., used to detect various attributes in a position, you can view it yourself.
This shows an example of code and explain to deepen everyone's understanding of the code:
Public Static Surfaceres.rulesource Build () {Return Surfacereules.IFTRUE (Surfacereules.isbiome (biomekey.biome), // If the group is the custom group system we created earlier
Surfacerules.IFTRUE (Surfacereules.not (Surfacerers.hole ()), // and if the location is not the Surfaceerules.Sequence (
SurfaceRules.IFTRUE (SurfaceRules.stoneDepthcheck (0, TRUE, 3, CAVESURFACE.FLOOR), MakeStaterant (Blocks.dirt)) // Replace the block within 3 grids of the surface to dirt to soil.
Surfaceerules.IFTRUE (SurfaceRules.stoneDepthcheck (0, TRUE, 5, CAVESUR FACE.FLOOR), MakeStateRule (Blocks.coarse_dirt)) // Block, if within five grids from the surface,Then replace it with sand soil
));
}
SurfaceRule registration
TerraBlender provides us with an interface that adds SurfaceRule to the corresponding dimension, and we still need to use it in the FMLCOMMONSETUP event.Change the following on the basis of the previous code:
@mod.eventbussubscriber (bus = mod.eventbussubscriber.bus.mod)Public Class ModbuseventConsumer {
@SubscripeEvent
Public Static Void ONSetup (FMLCOMMONSETUPENT EVENT) {
Event.enqueuework (()-> {{
Regions.register (New CommonworkDregion (4));
SurfaceRuleManager.addsurfaceres (Surfaceremanager.ruleCategory.overgoryd, Utils.mod_id, CommontworkDregion.build ()); // This is the content of the content of registered Surfacerulele. BiomeKey.Bootstrap ();
});
}
}
We can see three parameters here, which are the dimensions you need to add, your Modid, and the RuleSource content you created.
After completing these, open the game and find your group, and you can see the modified surface.
SurfaceRule custom
SurfaceRule's customization is to inherit the self -built category of the original SurfaceRule interface. Here we can use the code to directly perform the behavior of SurfaceBuilder in the old version. It has a high degree of freedom. I personally think that the complex surface requirements are required for complex surface requirementsUsing this feature is more convenient and intuitive than stack IFTRUE and Senquence.
First of all, we need to create a class and implement the Surfaceres.rulesource interface, which requires the CODEC method and Apply method.If you don't need to pass the parameter like if you can see if you see if you can see from the source code that is actually the constructor of the Testrulesource class), you can directly use the Public Static Final Codec
In the codec method, we return the New KeydispatchDataCodec <> (Codec).The Apply method requires us to create and return a SurfaceRule.Here you can work step by step, and the new Surfaceerule method is the next step.
Next we should create a class and implement Surfacereules.surfacereule interface.Because the TryApply method that needs to be implemented only provides the coordinate position and lacks more information, I strongly recommend that when constructing this rule instance, it is introduced to the Surfaceres.Context, as follows: as follows:
Public Record Rule (SurfaceRules.Context Context) Implements Surfaceerules.SurfaceRule {......}
After the creation is completed, we should implement the TRYAPPLY method.According to the previously introduced Context, we can get the various information we need.However, due to the authority settings of the data in the class, you need to use AT to manually add permissions for some unsacuspted values.If the Minecraft Develop plugin is installed, you can select the required method or class or variable, then right -click, and find "AT Entry" under "Copy/Paste Special".Then enter the public in your AccessStransFormer.cfg file and paste the content that is just automatically copied and reload the Gradle project.
As for how to write the code here, you can check the original SurfaceRule writing.Only one reference code is given here to help you understand the basic logic:
Public Record Rule (SurfaceRules.Context Context) Implements Surfaceerules.SurfaceRule {Public BlockState Tryapply (int x, int y, int z) {// Turn the position of y greater than 100 into air. Since the additional use of SurfaceRules.stoneDepthcheck (0, TRUE, 3, CAVESURFAROOR), which restricts the surface range, these contents only take effect on the top 3 blocks on the ground.However, this process can easily cause problems with the connection of the group.
If (context.blocky> = 100) Return blocks.air.defaultBlockstate ();
// For blocks with a height of 99 or 98, randomly become sand or wire
If (context.blocky> = 98) Return New Random (context.pos.aslong ()). NextFloat ()> = 0.3F? Blocks.mycelium.defaultBlockState (): Blocks.coars E_dirt.defaultBlockstate ();
If (context.blocky> = 95) Return blocks.coarse_dirtfaultBlockState (); // The height of 97 to 95 is replaced with sand soil
// Use from NoiseThresholdConditionSource to create noise function and get the noise value of the position.This value is generally between+-0.75, and different noise may be different.
Double noise = context.randomState.getorCreatenoise (noises.pillar) .GetValue (context.blockx, 0, context.blockz); if (noise> 0.6d) {// Different blocks generate different range according to the different range of noise value
// We created the getState method to help us judge that the target block is at the top or above
Return GetState (blocks.mycelium.defaultBlockstate (), blocks.coarse_dirtfaultBlockstate ());
} Else if (noise> 0.3d) {
// Randomly in a specific range, which makes the transition effect between the two generations.
Return New Random (context.pos.aslong ()). NextFloat ()*0.3F
} Else if (noise> 0.2d) {
Return GetState (blocks.gravel.defaultBlockstate (), blocks.andesite.defaultBlockstate ());} else if (noise> -0.2d) {
Return New Random (context.pos.aslong ()). NextFloat ()*0.4F
} Else if (noise> -0.6d) {{
Return New Random (context.pos.aslong ()). NextFloat ()*0.5F
} Else {
return new Random(context.pos.asLong()).nextFloat() < 0.1F ? getState(Blocks.ANDESITE.defaultBlockState(),Blocks.DIRT.defaultBlockState()) : null;
}}
Private Blockstate GetState (Blockstate SurfaceState, BlockState Group) {{
If (context.StoneDepthabove> 3 || Context.blocky <= 56) {// If the position depth is greater than 3 or the position is lower than y = 56, it will return NULL, which will cause it to be generated by default generation.
Return null;
} Else if (context.stoneDepthabove <= 1) {// If it is a surface block, return the first
Return SurfaceState;
} Else {// If it is a secondary square block, return the second
Return groupstate;
}
}
}
Finally, we need to register the newly created Rulesource CODEC.Create the following methods and call it in FMLCOMMONSETUP:
Public Static void RulesourceregBootstrap () {Registry.register (Builtinregistries.Material_rule, New ResourceLocation ("mod_id", "biome_surface"), biomesurfaceerule.Codec);}
In this way, our registration is completed.In the process of creating the RuleSource group earlier mentioned before, we call it in the corresponding group and start the game. At this time, you can see the group system generated according to the new Surfacerer created by us.
I don’t understand why I can upload the picture quality so low.
end
Finally, we will summarize everything we do here:
To create a biological group, we use DataGENATOR. We need to create monster data, create characteristic data that cannot be wrong in order, create group examples, create resource keys, register group system to generator, listen to incidents and generate in Gradle tasks.
Create Region, configure the region parameter, add a group and configure the group system related parameters, and register the region instance.
Create the RuleSource group, complete the internal content and register into the corresponding dimension.
Create custom RuleSource, make corresponding CODEC, create custom SurfaceRule, modify the AT that needs to be used, and customize the effect to generate on the surface, register CODEC.
The above is the main content of the basic use of TerraBlender and helping developers to achieve the generation of group surface generation. The content is individual's shallow understanding of MOD. If you have any mistakes, you can get your containment and correctness. Thank you for watching.
In addition, it provides some convenient links or tutorials for group development:
https://misode.github.io/worldGen/biome/ You can quickly generate the need for group data packets on this website without having to use data generator or manual configuration JSON file.
https://www.youtube.com/watch?v=enzkjwq0vni&list=plkgarocxce1H9Y21-PXJT5PT8BW14twa- &NDex=13 You can find a detailed method of use Data Generator on this website.
https://github.com/glitchFiend/terraBlender/tree/tb-1.20.2-3.1.x/example/Forge You can see the 1.20 version for development samples provided by the TerraBlender author on this website.Similarly, you can find other versions or Fabric versions in other branches or folders under this project.
National Service DNF Dark Ni
2025-01-28 09:19:27The new screenshot of the be
2025-01-28 09:18:57The 15th anniversary wallpap
2025-01-28 09:18:273DM Xuanyuan Sinicization Gr
2025-01-28 09:17:57French magazine is the first
2025-01-28 09:17:27The sneak game "Republic" wi
2025-01-28 09:16:57The story between humans and
2025-01-28 09:16:27Capture "Trinity 3: Artifact
2025-01-28 09:15:27Wind direction change "Myste
2025-01-28 09:14:57DICE's new project "Dream" w
2025-01-28 09:14:27Pirate Minecraft Skins
Minecraft Skins
2024-12-10 04:11:27Pirate Minecraft Skins
Minecraft Skins
2024-12-10 04:11:26Master Minecraft Skins
Minecraft Skins
2024-12-10 04:11:25King Minecraft Skins
Minecraft Skins
2024-12-10 04:11:25Guide Minecraft Skins
Minecraft Skins
2024-12-10 04:11:24Dark Knight Minecraft Skins
Minecraft Skins
2024-12-10 04:11:23Sparta Minecraft Skins
Minecraft Skins
2024-12-10 04:11:23Moncraft Skins of the War
Minecraft Skins
2024-12-10 04:11:22Red Witch Minecraft Skins
Minecraft Skins
2024-12-10 04:11:22Golden Cavaliers Minecraft S
Minecraft Skins
2024-12-10 04:11:22