• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EST 09:49
CET 15:49
KST 23:49
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
HomeStory Cup 28 - Info & Preview11Rongyi Cup S3 - Preview & Info3herO wins SC2 All-Star Invitational14SC2 All-Star Invitational: Tournament Preview5RSL Revival - 2025 Season Finals Preview8
Community News
Weekly Cups (Jan 19-25): Bunny, Trigger, MaxPax win3Weekly Cups (Jan 12-18): herO, MaxPax, Solar win0BSL Season 2025 - Full Overview and Conclusion8Weekly Cups (Jan 5-11): Clem wins big offline, Trigger upsets4$21,000 Rongyi Cup Season 3 announced (Jan 22-Feb 7)38
StarCraft 2
General
HomeStory Cup 28 - Info & Preview StarCraft 2 Not at the Esports World Cup 2026 Weekly Cups (Jan 19-25): Bunny, Trigger, MaxPax win Oliveira Would Have Returned If EWC Continued herO wins SC2 All-Star Invitational
Tourneys
HomeStory Cup 28 KSL Week 85 $21,000 Rongyi Cup Season 3 announced (Jan 22-Feb 7) OSC Season 13 World Championship $70 Prize Pool Ladder Legends Academy Weekly Open!
Strategy
Simple Questions Simple Answers
Custom Maps
[A] Starcraft Sound Mod
External Content
Mutation # 510 Safety Violation Mutation # 509 Doomsday Report Mutation # 508 Violent Night Mutation # 507 Well Trained
Brood War
General
BGH Auto Balance -> http://bghmmr.eu/ Can someone share very abbreviated BW cliffnotes? BW General Discussion [ASL21] Potential Map Candidates Bleak Future After Failed ProGaming Career
Tourneys
[Megathread] Daily Proleagues Small VOD Thread 2.0 Azhi's Colosseum - Season 2 [BSL21] Non-Korean Championship - Starts Jan 10
Strategy
Zealot bombing is no longer popular? Simple Questions, Simple Answers Current Meta Soma's 9 hatch build from ASL Game 2
Other Games
General Games
Battle Aces/David Kim RTS Megathread Nintendo Switch Thread Path of Exile Mobile Legends: Bang Bang Beyond All Reason
Dota 2
Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug Heroes of StarCraft mini-set
TL Mafia
Mafia Game Mode Feedback/Ideas Vanilla Mini Mafia
Community
General
US Politics Mega-thread Canadian Politics Mega-thread Russo-Ukrainian War Thread European Politico-economics QA Mega-thread Things Aren’t Peaceful in Palestine
Fan Clubs
The herO Fan Club! The IdrA Fan Club
Media & Entertainment
[Manga] One Piece Anime Discussion Thread
Sports
2024 - 2026 Football Thread
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread
TL Community
The Automated Ban List
Blogs
Let's Get Creative–Video Gam…
TrAiDoS
My 2025 Magic: The Gathering…
DARKING
Life Update and thoughts.
FuDDx
How do archons sleep?
8882
Customize Sidebar...

Website Feedback

Closed Threads



Active: 2129 users

Terrain Generation I --- Noise

Blogs > Namrufus
Post a Reply
Namrufus
Profile Blog Joined August 2011
United States396 Posts
Last Edited: 2013-11-12 04:56:15
November 12 2013 04:42 GMT
#1
Introduction


In this series of posts, I'll describe my methods and experience writing a terrain generator for Minecraft using the craftbukkit world generator API -- (the generator itself will be written agnostic of any specific framework or library - so a port to Forge or even to a similar type of game may be possible)

This is the first time I've written anything remotely like this, so, if you'd like, please give feedback on what you liked or didn't, and any thoughts on how you think the post could be better.

edit: 300th post!



Terrain Generation I --- Noise


If you visit any online resource about terrain or world generation, chances are good that it will mention Perlin noise and associated "Coherent Randomness" algorithms. Perlin noise is in fact used in a critical role in MInecraft's native generator, as Notch describes in Terrain Generation, Part 1 (of 1). This project will be no different.

Perlin noise generation is a technique first engineered to reduce the memory requirements of textures in early computer graphics. This - and similar coherent randomness algorithms -- are useful because they allow us to specify things such as the period (the scale of the noise, in the context of a terrain generator, will allow the generated noise form the basis of things of all scales, from tiny hills to entire continents) and the amplitude (the "height" of the noise). By composing multiple noise generators, it will be possible to generate a world.

Because I want this generator to work similarly to Minecraft's world generator, there are a couple of unique requirements:
  • "Infinite" generation: The noise generator should able to generate noise without any built in limits, terrain should not repeat. Technical limits are OK (the same type of limit at the root of Minecraft's fabled "8 times the surface of the earth" claim)
  • Realtime arbitrary generation order: Minecraft terrain is generated on the fly, as the player explores the world, this means that terrain chunks can be generated at any order, at any time, across different play sessions, Minecraft versions, Java versions, generator versions, or even devices.

Makin' some noise


For this project I've implemented a type of closely related algorithm known as value noise (slightly simpler than Perlin noise - in both implementation and efficiency - but sufficient for the purposes of this project)

As decribed on the wiki, value noise works by generating a grid or lattice of randomized value points, then interpolating between the values in order to create a smooth, randomized surface.

[image loading]
Grid points. As you can see, each grid point generates a value and the surface is interpolated between those values

The interpolation is relatively simple, the real trick here is the grid point value generation.


To Infinity...


Perlin noise, in it's original form is slightly unsuited to this task, due to the fact that the values used at the grid points are precomputed. A grid of points are generated, if the noise is sampled outside of the grid, the pattern is simply repeated; this has the advantage of being fast - requiring only an array lookup instead of a random number generation - but has the disadvantage of creating a repeating pattern.

In light of the requirements above, grid values will need to be effectively infinite in number, generated on the fly, have no visible patterns or repeats, and be reproducible across program runs. In short we need a function of the format:

 noise(seed, grid x, grid y, grid z)  ->  value 


the seed will be an integer value that will be stored across program runs.

After some experimentation, my solution is as follows.

noise(seed, x, y, z)
a <- cantor(y, z)
b <- cantor(x, a)
c <- cantor(seed, b)
result <- randomize(c)


randomize(k)
is this 64 bit linear congruential pseudo-random number generator - this algorithm takes an input and multiplies it by a huge number, "shooting" it past the 64 bit overflow value (the largest possible 64 bit value) causing it to "overflow", resulting in a number that (by casual inspection) is unrelated to the original value.This is not the best RNG function, nor is this the intended use case for it, but it is fast and seems to produce good results (visually).

cantor(k1, k2)
is the cantor pairing function. As mentioned in the wikipedia article, this function takes two positive integers and combines them into a single positive integer, with each pair of numbers resulting in a unique result.

The algorithm combines all of the grid coordinates together (with some spicyness from the seed value) into a unique integer using repeated application of the cantor pairing function, that value is then "randomized" using the linear congruential generator to obtain the final randomized value.

My first images using this method looked like this:

[image loading]

Uh-oh, symmetry. I had forgotten that the cantor pairing function was designed for positive integers only. Adding a function to "interleave" the inputs into positive integers fixed the problem.

for the record: the cantor pairing function:


interleave(k) -> -2 * k k < 0
-> 2 * k + 1 k >= 0

cantor(k1, k2)
k1' <- interleave(k1)
k2' <- interleave(k2)
result <- ((k1' + k2') * (k1' + k2' + 1)) / 2 + k2'


The final result? A seeded, infinite, (as far as I can tell) unrepeating noise generator (with basically zero memory imprint)

[image loading]


A bit square looking, mostly because of the way that I am interpolating between the values. I think it compliments Minecraft's blocky aesthetic.


I love it LOUD!


What can be created using noise generators? I won't talk about the main terrain generation yet (mostly because I am still experimenting), however I will describe the "secret sauce" that makes all this worth while.

The secret ingredient? Fractals.

[image loading]
Not quite
source

In my experience, discussion of fractals in relation to terrain generation tends to be slightly mystical: "How do you make realistic looking terrain?" "fractals". The reality is quite simple: real landscapes have varying levels of detail, this detail tends to be self-similar (Hills look like down-scaled mountains, lumpy coastlines resolve into smaller bumps as you zoom in). Self-similarity is the defining feature of a fractal.

In practice this generally means we use an approximation of Fractal brownian motion. A fractal brownian surface has the prominance (amplitude, or strength) of features be inversely proportional to the frequency (or size) of said features - if a feature is twice the frequency (half as large) it will have half the strength, at 3 times the frequency (1 third scale) it will have 1/3 strength, and so on). The general trend that emerges is that the surface as a whole is dominated by the largest features (in the context of a terrain generator, continents) which are in turn "perturbed" by smaller scale features like coastline bumps, inlets, islands, lakes and other interesting features.

First, assemble a couple of generators, double the frequency for each successive generator

[image loading]

Halve the amplitude of each successive generator.

[image loading]

sum them all together and you get this, pretty cool, right? It really masks the "square" appearance of the noise.

[image loading]

Just for fun, add a simple gradient and a "sea level".

[image loading]

Not all that impressive. We're not done yet, of course.


Next Time


Infinite seeded Voronoi cells using the same techniques as used to make the value noise generator. Also: the basic high-level bones of the generator: continents! mountain ranges! climate! I'll explain how my generator will be different from Minecraft's native terrain generator.

I'm also planning on putting the WIP project up on my Github, I'll have a link on a later post.

If you have any questions, ask and I'll answer as well as I can.

Thanks for reading!

*****
This is it... the alpaca lips.
v0rtex
Profile Joined November 2011
123 Posts
November 12 2013 07:57 GMT
#2
Very interested to see where you go with this! Nice work!
JD, Snute, TLO, Soulkey, $o$, HerO, Suppy, Hendralisk, MKP, Maru
jrkirby
Profile Blog Joined August 2010
United States1510 Posts
November 12 2013 09:45 GMT
#3
I implemented perlin noise a couple months ago: http://imgur.com/8DU6vwh

I also recently saw a video on procedural generation that proposed an awesome technique:


Good stuff.
Namrufus
Profile Blog Joined August 2011
United States396 Posts
Last Edited: 2013-11-12 21:34:45
November 12 2013 21:34 GMT
#4
On November 12 2013 16:57 v0rtex wrote:
Very interested to see where you go with this! Nice work!


thanks! To give you an idea of some of the stuff I'm aiming for: + Show Spoiler +
[image loading]
an image from a much older version of the project.


On November 12 2013 18:45 jrkirby wrote:
I implemented perlin noise a couple months ago: http://imgur.com/8DU6vwh

I also recently saw a video on procedural generation that proposed an awesome technique: https://www.youtube.com/watch?v=GJWuVwZO98s

Good stuff.


cool. Nice video, seems like something like that would be good for a game set in sapce, planets connected by warp gates or something.
This is it... the alpaca lips.
Please log in or register to reply.
Live Events Refresh
OSC
13:00
King of the Hill #236
iHatsuTV 12
Liquipedia
HomeStory Cup
12:00
Day 3
Zoun vs HeRoMaRinELIVE!
Clem vs LamboLIVE!
TBD vs ShoWTimE
TBD vs Serral
TaKeTV5342
ComeBackTV 2198
IndyStarCraft 697
TaKeSeN 470
Rex229
3DClanTV 152
Liquipedia
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
IndyStarCraft 697
Rex 229
CosmosSc2 46
StarCraft: Brood War
Calm 4307
Rain 2754
Bisu 2482
Shuttle 1568
EffOrt 1163
Horang2 945
Larva 791
Stork 621
Mini 596
Soma 592
[ Show more ]
Hyuk 565
BeSt 366
actioN 304
firebathero 270
ggaemo 166
Last 114
Hyun 110
Pusan 106
Sharp 93
sorry 74
PianO 69
Free 65
yabsab 61
Mind 59
JYJ 44
Killer 29
ToSsGirL 28
910 27
Shinee 26
GoRush 26
HiyA 25
Barracks 25
soO 25
hero 25
Hm[arnc] 21
Rock 18
Terrorterran 18
zelot 15
SilentControl 15
Sacsri 7
Dota 2
Gorgc4949
qojqva2740
Dendi924
syndereN285
Fuzer 278
XcaliburYe264
Counter-Strike
fl0m2562
edward66
Super Smash Bros
Westballz28
Heroes of the Storm
Khaldor448
Other Games
singsing2027
B2W.Neo1864
Liquid`RaSZi1464
DeMusliM325
crisheroes302
Hui .266
FrodaN142
KnowMe112
QueenE92
Mew2King60
ToD32
Organizations
Other Games
EGCTV13
StarCraft: Brood War
Kim Chul Min (afreeca) 9
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 13 non-featured ]
StarCraft 2
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• FirePhoenix14
• Michael_bg 10
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
League of Legends
• Jankos2806
Upcoming Events
Replay Cast
9h 11m
Replay Cast
1d 9h
Wardi Open
1d 21h
WardiTV Invitational
2 days
Replay Cast
3 days
The PondCast
3 days
WardiTV Invitational
3 days
Replay Cast
4 days
uThermal 2v2 Circuit
6 days
Liquipedia Results

Completed

Proleague 2026-01-31
OSC Championship Season 13
Underdog Cup #3

Ongoing

CSL 2025 WINTER (S19)
KCM Race Survival 2026 Season 1
Acropolis #4 - TS4
Rongyi Cup S3
HSC XXVIII
Nations Cup 2026
IEM Kraków 2026
BLAST Bounty Winter 2026
BLAST Bounty Winter Qual
eXTREMESLAND 2025
SL Budapest Major 2025
ESL Impact League Season 8

Upcoming

Escore Tournament S1: W7
Escore Tournament S1: W8
Acropolis #4
IPSL Spring 2026
uThermal 2v2 2026 Main Event
Bellum Gens Elite Stara Zagora 2026
LiuLi Cup: 2025 Grand Finals
IEM Rio 2026
PGL Bucharest 2026
Stake Ranked Episode 1
BLAST Open Spring 2026
ESL Pro League Season 23
ESL Pro League Season 23
PGL Cluj-Napoca 2026
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2026 TLnet. All Rights Reserved.