Terrain Generator written with C (compiled into WebAssembly) and visualized with HTML5/JavaScript. Prototyped in Python using the Noise module.
This terrain generator uses Perlin noise and was built with WebAssembly, C, and JavaScript. My motivation to build this stems from my interest in producing complex behavior from simple systems. While noise generation is not entirely simple, to the perceiver, giving a noisy map even a little bit of context (e.g. letting the values represent depth or height) forms an entirely new perspective. Assigning meaning to numerical values can elevate a noise function to a model resembling the natural world.
Move by ten sudo-pixels (i.e. one coordinate value) using the directional navigation buttons. Alternatively, go to a specific position by entering two non-negative integers and clicking the button. The left plus (+) and minus (-) buttons zoom, in and out respectively, relative to the top left pixel of the map.
The keyboard can also be used to navigate the terrain with the following controls.
W
- Move Up / Increase Y ValueA
- Move Left / Decrease X ValueS
- Move Down / Decrease Y ValueD
- Move Right / Increase X Value
The initial seed is randomized when the document loads, but you can manually enter new seeds or load up previously encountered ones for the same generation.
While any string can be entered as a seed, repeat values may be found as strings, that are not already positive integers, are hashed into an integer value and the safe integer limit can be passed when using extraneous or lengthy strings. When this occurs the seed falls back to the absolute value of the integer wrap-around.
Overriding the integer limit check can be done by simply entering an integer
larger than 253
. At this point significant
stretching and artifacting is noticeable.
You cannot navigate towards or go to negative values using the UI (all there is to see is artifact clutter). Additionally artifacts begin appearing as X and Y approach infinity.
Using a simplified 2D Perlin noise algorithm implemented in C to calculate
depth information for each point value. For speed and simplicity, the
program works optimally when
X, Y ∈ {a | 0 ≤ a ≤ 15000, a ∈ Z}
where X and Y are integers
representing horizontal and vertical position values respectively. The C
algorithm has been compiled into WebAssembly (WASM) to run as a binary
executable in the web browser. The compiled WASM module is able to provide
unmatched speed when compared to JavaScript.
Each coordinate position in the interface represents a 10 by 10 fat pixel chunk which are kept in state to limit the calculations necessary for rendering movements smaller than the viewport. Chunking also reduces the risk of memory leaks in the WebAssembly module resulting in a dead tab.
The last, and arguably most important, part of a terrain generator is
rendering. Graphics are what contextualize a 2D array of integers into a
visual that can be perceived as an aerial view of a landscape. A constant
WATER_LEVEL
is used to find what is present at each height of
the terrain and assign both a color, for material, and an accenting shade
for height or depth. Lastly, some shades are randomly altered to add more
texture to the map.
This process is repeated for every fat pixel on the display and uses
JavaScript to draw each chunk onto an HTML5 canvas. The final fat pixel
density is determined by the RESOLUTION
constant currently
set to 100 for the amount of colored squares of each axis. Increasing this
constant to a high number (e.g. 400) would increase perceived resemblance
to an organic map, but with additional noise values to estimate and an
O2 iteration of the map on render time this process becomes
exponentially complex in both time and space. A better solution to achieve
a more organic shapes would be to estimate interpolated curves between the
points.
Did something go wrong? Make sure you have a compatible browser. This program works with all web browsers supporting WebAssembly and HTML5 Canvas. I have compiled a list of popular browser versions in the table below. If your browser should be compatible and you are still facing errors open an issue on Github or feel free to shoot an email to [email protected].
Browser | Minimum Version |
---|---|
Firefox | 58 |
Chrome | 61 |
Safari | Not Compatible |
Edge | 16 |
Opera | 47 |
- WebAssembly. (2020, April 22). Retrieved May 1, 2020, from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/WebAssembly
- WebAssembly.instantiateStreaming(). (2020, May 7). Retrieved May 7, 2020, from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming
- WebGL API. (2020, March 31). Retrieved May 1, 2020, from https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API