• Hey! Register here to create your account, engage with the community, and talk about what is new!

5.2 - Terrain Gen Tutorial

General_Mudkip

Retired Moderator
Overlord
Joined
Sep 6, 2020
Messages
362
Reaction score
95
So what makes generating terrain in 5.2 so much easier? Well it's mainly based on Repeat: On Grid. In simple terms, this just repeats across each block in a grid, setting a variable to the location that it's on each iteration. Now instead of having to use 2 perlin noises, basic terrain gens only require 1! On a lesser note, 5.2 has also introduced Processes. These are like functions, but they run asynchronously. In this case you can use either a process or function, however if you want to generate your terrain and run code at the same time a process is what you need to use.

To start of just place down a Player Event: Join and set their gamemode to creative using Player Action: Set Gamemode. It's also worth setting the player's spawn high up so that they don't suffocate. Then place down a call process and process called "terrainGen". You should have something that looks like this:

Screenshot_97_1593989868.png


Inside your process is where all the terrain generation will happen. Before placing down the repeat, we'll need to generate a seed; simple Set Var and %random(1,9999999) will work. The seed is what determines how the Perlin Noise will generate. You can chose to have this as a set value though if you want to generate the same terrain every time. Next up place down your Repeat: On Grid. Inside the chest you'll need to place a Local Dynamic Variable (I just used currentLoc), and 2 Location Variables. These location variables should be at opposite corners of your plot, at about Y-Level 65. You should have this:
Screenshot_98_1593990200.png


Now inside of your repeat place down a Set Var: Perlin Noise (This is located inside of Advance Actions). So what is a Perlin Noise? A visual representation will probably help the most:
1+vs239SecVBaB4HvLsZ8O5Q_1593990358.png

It's basically a heat map that allows us to simulate different elevation and terrain. The function itself requires quite a bit of parameters that you can tweak if you want, however the default values work fine for a basic terrain gen. Though I'm sure someone else could explain what each individual parameter does better than me.

Screenshot_99_1593990500.png


Variable: Perlin Noise returns a value between 0 and 1 (Regarding the Perlin Noise image, the darker areas are higher numbers and lighter areas lowers numbers. Starting to get it?) This will be the variable that we can use to determine the Y-coordinate of our location.

Location: The location in the Perlin Noise map, for this we will use the dynamic location variable in the Repeat: On Grid (for me it was currentLoc).

Frequency: This is how close together the different "patches" will be. We can leave this as 1.

Octaves: This will affect the amount of layers of Perlin Noises there will be, thereby affective how blurry/fine the final map will be. For this 1 is fine.

Octave Frequency Gain: This is how close together the octave layers will be to each other. The default is fine.

Octave Amplitude Gain: This is how extreme the values will change. 0.75 is fine, however if you want flatter lands then higher numbers are better.

Seed: This is the seed variable that we set beforehand.

Fractal Type (tag): These are just different ways of generating the perlin noise. You can leave these alone for now.

Inside of this you should have this, keep in mind that you need all of the number variables so that the game doesn't think that the seed is the frequency:
Screenshot_101_1593991156.png


Alright nice, next up we need to convert that Perlin variable into something actually usable. Place down a Set Var: Shift Axis, and inside of it place down your "currentLoc" and a number variable. So at the moment our Perlin Noise variable will just be some random number between 0 and 1 (e.g 0.562). If we were to set the block as it is now, DF would just set a line, as it's all on one Y coordinate. All we have to do is just multiply that variable by a number, 18 worked for me, and shift our "currentLoc" by it. So the number variable will be %math(%var(perlinNoise)*18). Make sure that the tag in the bottom right is set to Y and not X.

All that's left to do is just place down a Game Action: Set Block, and inside of it just put a Grass block and your "currentLoc"! And you should be left with this:
Screenshot_103_1593991742.png


Now just run your code there you go! Regarding the wait, at the moment it's quite slow so implementing a ten-tick wait could probably work. Here's an example of a terrain that was generated by this:
Screenshot_102_1593991837.png


Links
In case you want to do some further work, I'll give some links that give you further insight into Minecraft's terrain generation system.
Structures
Complex Overview
Blog Post By Notch (2011)
Biome Borders

Making Maps with Noise Functions

Part 2 Below!
 
Last edited:

General_Mudkip

Retired Moderator
Overlord
Joined
Sep 6, 2020
Messages
362
Reaction score
95
Part 2

This is going to be a followup to my previous post which you can find here. In the last tutorial we made a very simple terrain gen that allowed you to generate 1 layer of grass, which you can't really use in a plot. In this tutorial, I'll show you how to clear the previous generation, aswell as generate dirt and stone below it. Keep in mind that this is aimed at Basic Plots. Large and Massive plots will need other forms of clearing.

So to start of with a recap, you should have this code:
Screenshot_103_1594045272.png



Clearing System
Simple. So I'm going to start off with the clearing system. What we're going to do is clear out an entire X-Axis row, so that on a basic plot it will only require 50 repeats to completely clear your plot. So just place down a Function (It's important that you place down a function, because if you use a process the clearing and generation code will run at the same time) called "clearScan". Inside it we're going to use another Repeat: On Grid. Instead of using the 2 locations that we used in our other Repeat, we're going to use 2 locations at bedrock level, make sure that they are both at the same Z-Coordinate. As a visual aid, it'll be these 2 blocks on a basic plot:

Screenshot_104_1594045290.png


Inside that repeat, we'll also use a variable called "currentLoc". Place down a Set Var: Shift on All Axes and a Set Var: Set Coordinate. Inside the Shift on All axes, put a local variable called "clear1", a "currentLoc" variable, and for a basic plot, the number variables 50, 150, 0. Inside of the Set Coordinate, put a local variable called "clear2", a "currentLoc", and a number variable 1. Also make sure that the tag is set to the Y-Axis. Your clear function should now look like this:

Screenshot_105_1594045915.png


After that, place down a Game Action: Set Block, and inside that place down a text item called "Air", and your 2 clear variables (clear1, clear2). Now all you have to do is place down a Control: Wait set to 5 ticks and it should work! Keep in mind that a custom wait function that changes based on the CPU usage is very important with intensive code. I won't go into detail about it here, though I will include one on my template plot (/join 1471).

Dirt and Stone Generation
This is actually surprisingly simple. In the first repeat, place 2 Set Var: Shift Axis. Inside the first one put a local variable called "stoneTop", your "currentLoc" variable, and a number variable -4. Make sure that the tag is set to the Y-Axis. In the second Shift Axis, just place your "currentLoc" and a number variable -1. After that, place a Set Var: Set Coordinate, inside of which you'll put a local variable called "stoneBottom", your "currentLoc", and a number variable 2. Now your code should look like this:
Screenshot_106_1594046879.png


Alright nice, so what have we just done? These are all the variables that we need to generate that dirt and stone. "stoneTop" is the middle ground between the bottom of the dirt layer and the top of the stone layer. "stoneBottom" is quite obviously the bottom of the stone. And we've shifted "currentLoc" down, so that it serves as the top of the dirt layer. With this can you figure out how to generate the dirt layers?

Place down two Game Action: Set Block's, and inside of the first one put a dirt block, and the two variables "currentLoc" and "stoneTop". Inside of the second set block, place a stone block, and the two variables "stoneTop" and "stoneBottom". And that's it! Now just join and you should be able to generate a basic plains biome.

Screenshot_107_1594048718.png


Conclusion
If you have any questions or corrections please make sure to let me know. I can't stress enough that terrain gens are all about efficiency and optimization. Lagslayer is extremely prone to shutting down anything remotely fast, so creating advanced terrain gens requires a lot of revisions and finicking around (I've spent 2 hours alone today trying to find the best wait settings.). It's likely that my system will become outdated in a few days or weeks, so make sure to try and
Thanks and good luck!
 

Refrizor

Retired Administrator
Retired Admin
Joined
Aug 16, 2020
Messages
513
Reaction score
361
I can see this being super helpful, thanks for a great tutorial!
 

EmeralDev

Forum adept
Joined
Sep 7, 2020
Messages
193
Reaction score
30
epic tutorial - maybe too long for smth that can be done 10 codeblocks lol
 

ACraftingFish

Notorious member
Joined
Sep 6, 2020
Messages
106
Reaction score
21
If you're going for overkill performance changes, Repeat for grid isn't the best option, you could make your own system, but you shouldn't really worry about this unless you're making a LARGE terrain gen. Just wanted to put this out there :D
 

EmeralDev

Forum adept
Joined
Sep 7, 2020
Messages
193
Reaction score
30
yea but dont make a 0 tick massive terrain gen server will kil u
 

K_Sasha

Active member
Joined
Aug 16, 2020
Messages
40
Reaction score
45
Repeat on grid should be faster than repeating through the blocks using your own code.
 

EmeralDev

Forum adept
Joined
Sep 7, 2020
Messages
193
Reaction score
30
With repeat on grid it's also way easier to regulate gen speed
 

DogWithHats

Forum adept
Overlord
Joined
Sep 9, 2020
Messages
335
Reaction score
53
Could this theoretically be used with the "display block" player action to create a client-side terrain gen? Could that work for terrain gens in general?
 

Noah

Forum adept
Joined
Sep 7, 2020
Messages
268
Reaction score
47
you're not going to be able to make client side survival dog
 

Noah

Forum adept
Joined
Sep 7, 2020
Messages
268
Reaction score
47
no like it's literally impossible cause r-click block go bye bye
 
Top Bottom