Scrolling 2D Block World
Urho3D Accidental Noise Library Perlin streaming 2D block world
Download (Google Drive)
Execute it by running the sidescroller_demo.bat batch file; or, alternatively, by executing Urho3DANL.exe Scripts/sidescroller_main.lua -w from the command line. The -w switch forces windowed mode; omit for fullscreen.
It's nothing fancy. I haven't really had enough free time in large enough consecutive chunks to do anything significant on Goblinson Crusoe, so I've just been sort of idly watching as the Urho3D team works on the Lua scripting system and goofing off with it in the meantime. This little toy is just one of a number that I have built to test things out. It doesn't do much except show a scrolling view of a block level. You can use the mouse to scroll around by holding the left mouse button; the center of the view will scroll in the direction of the cursor. You can press Esc to exit or 's' to grab a screenshot. The mouse wheel will zoom the camera in and out. Sometimes, depending on the elevation at the starting point, you might see nothing but cloudy skybox; if this is the case, scroll downward.
Here are a few screenshots to tantalize and titillate:
The view begins at column 4096 in the center, meaning it will only scroll so far to the left before it hits 0 and won't generate any further. It will scroll much, much further to the right. The demo works by loading at init a large block of 128 columns, each column being 128 blocks high. These columns are generated directly from a tree of noise functions built using ANL. The function tree outputs a block type for a given coordinate.
As the camera moves, columns are dropped from the back side and generated on the front side, depending on which way the camera is moving, so that there are always 128 columns in the scene. The noise function is set up such that you can generate terrain a column at a time to +infinity (or, at least, the limits of double precision). While the engine build uses double precision base in the noise functions, Urho3D uses single-precision float for node coordinates, so the world is effectively limited by single-precision float size with blocks being sized 1x1 units. Still, even with single-precision, that amounts to a pretty large level.
The demo also demonstrates one of the shortcomings of implicit functional-based procedural generation, ie population of the world with objects that fall outside what can be easily expressed via noise functions. In the GenerateColumn method, the generator uses a couple simple rules to place rocks, trees, grass, mushrooms and treasure chests on top of suitable blocks. Such methods work, albeit in a rather simplistic fashion. For more sophisticated results, it is usually best to generate chunks larger than one column in size, but this demo does not do so.
It also uses a rather simplistic terrain shape function, ie a single FBM fractal for elevation. Thus, the generated terrain is quite homogenous throughout its range, and while some interesting little nooks and crannies result, it might be better in a real application to vary the noise function in creative ways. Additionally, this demo does not do anything in the way of biome differentiation. I wasn't really interested in building a full biome generator, since this sort of foundation really isn't my favorite type of game. It was just a toy experiment.
If you are interested in seeing the guts, peek into the Data/Scripts folder, where the application is implemented as a few Lua scripts. The engine is a custom build of the Urho3D engine, with the ANL library built in. The basic operation of the noise function can be read about here. In essence, however, it operates thusly:
First, constants are assigned to represent block types: Open, OpenCave, Stone, Dirt, Lava, Gold. A gradient that stretches from Z=0 to Z=1 is set up, which is then distorted by a ground shape fractal. The distorted ground is used to select various terrain types using selection functions. A ridged fractal is set up to represent cave systems, and is used to select between cave and solid. Another selection uses the base, un-distorted gradient to select for lava in the lower regions of the caves. A final fractal is used to select between basic stone and gold in small deposits. All of these various module are combined together such that by calling get(x,z) on the final module in the chain, OpenTypeSelect the result is one of the block type constants.
A column is iterated top to bottom, tracking that last two previous blocks generated in order to allow or disallow spawning a doodad under certain conditions. If a block is Dirt, and the previous block is Open then there is a chance of spawning a rock or a grass hat on top of the dirt block. If a block is Dirt and that previous 2 blocks are open, there is a chance of spawning a tree. If a block is Stone and the previous block is CaveOpen, there is a chance of spawning a Mushroom or a Treasure Chest.
Feel free to tweak some of the parameters in the module chain to see what they do. Have fun, and thanks to AgentC and his crew for their work on Urho3D.