<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://twmh.fyi/feed.xml" rel="self" type="application/atom+xml" /><link href="http://twmh.fyi/" rel="alternate" type="text/html" /><updated>2026-06-08T00:37:48+00:00</updated><id>http://twmh.fyi/feed.xml</id><title type="html">The Bug Report</title><subtitle>I make things that do things.</subtitle><author><name>Toby</name></author><entry><title type="html">Infinite worlds with procedural generation!</title><link href="http://twmh.fyi/2023/06/20/infinite-worlds.html" rel="alternate" type="text/html" title="Infinite worlds with procedural generation!" /><published>2023-06-20T23:42:26+00:00</published><updated>2023-06-20T23:42:26+00:00</updated><id>http://twmh.fyi/2023/06/20/infinite-worlds</id><content type="html" xml:base="http://twmh.fyi/2023/06/20/infinite-worlds.html"><![CDATA[<p>Ever wonder how games like <em>Minecraft</em>, <em>Astroneer</em> or <em>No Man’s Sky</em> create those incredible open-world settings? Entire solar systems yet to be explored, resources just waiting to be utilized! Undoubtedly it wouldn’t be very practical to store all of that data on disk, so how do they do it? The answer, as you might have guessed by the title - <strong>procedural generation</strong>!</p>

<p>Now that probably sounds a little daunting to some of you, but really its super simple, and in this post we’re going to explore some working examples that you can play around with yourself.</p>

<p>I will be using the <a href="https://godotengine.org/">Godot game engine</a> and C# for the following examples, but please note that these concepts can be implemented in any engine of your choosing.</p>

<h1 id="where-do-we-even-begin">Where do we even begin?</h1>

<p>The first step towards creating our terrain is to figure out how we’re going to represent it in space. Taking some inspiration from <em>Minecraft</em>, lets make a grid of uniformly-spaced cubes and build a blocky landscape!</p>

<p>Since we’re going to be using cubes for our terrain, we’ll first need some a way to create them! In this case, I created <code>MeshInstance3D</code> with the default <code>BoxMesh</code>, and saved it in its own scene.</p>

<p>This lets us to load it wherever we want like so:</p>

<pre><code class="language-c#">using Godot;
using System;

public partial class world : Node3D {
    public PackedScene BlockMesh = ResourceLoader.Load&lt;PackedScene&gt;("res://block.tscn");
    ...
}
</code></pre>

<p>And then to actually instantiate the block, we can do:</p>

<pre><code class="language-c#">MeshInstance3D block = BlockMesh.Instantiate() as MeshInstance3D;
</code></pre>

<p>Great! We now have a way to create blocks and add them to our scene, the next step is to create a grid of these blocks on the XZ plane. To do this, we can use nested for loops to iterate over all the possible grid coordinates:</p>

<blockquote>
  <p>Note: In most game engines the Y axis represents the vertical coordinate, which is why we use X and Z instead.</p>
</blockquote>

<pre><code class="language-c#">for (float x = -20; x &lt; 20; x++) {
    for (float z = -20; z &lt; 20; z++) {
        MeshInstance3D block = BlockMesh.Instantiate() as MeshInstance3D;
        block.Position = new Vector3(x, 0, z);
        AddChild(block);
    }
}
</code></pre>

<p align="center"><img src="/assets/images/img-002.png" width="70%" height="70%" /></p>

<p>Which should generate something that looks like this, albeit is a little underwhelming - but we’re just getting started!</p>

<h1 id="bring-on-the-curves">Bring on the curves!</h1>

<p>In order to see anything even remotely interesting, we’re going to create a function that’ll calculate a new Y coordinate, given X and Z as inputs. For example:</p>

<pre><code class="language-c#">float GetHeightAtPosition(float x, float z) {
    return (
        MathF.Sin(0.5f * x) + 
        MathF.Sin(0.5f * z)
    );
}
</code></pre>

<p>And then if we extend our previous code like so:</p>

<pre><code class="language-c#">float y = GetHeightAtPosition(x, z);
block.Position = new Vector3(x, y, z);
</code></pre>

<p align="center">
<img src="/assets/images/img-003.png" width="70%" height="70%" />
</p>

<p>We end up with something that somewhat resembles bumpy terrain. Progress!
If you want, you can experiment with different height functions and see what happens. Here are a couple more examples:</p>

<pre><code class="language-c#">// left image:
y = 0.1 * (x * x + z * z);
// right image:
y = 0.1 * (x - z) * (x + z);
</code></pre>

<p align="center">
<img src="/assets/images/img-004.png" width="49%" height="49%" />
<img src="/assets/images/img-005.png" width="49%" height="49%" />
</p>

<p>Notice how in both of these examples there are gaps between the blocks, which isn’t very natural looking. To fix this, we can manipulate the size of each block, such that we form a solid chunk:</p>

<blockquote>
  <p>Note: Since our function can generate negative values, we add an offset height in order to avoid funky behavior when setting the block scale.</p>
</blockquote>

<pre><code class="language-c#">float y = GetNoiseAtPosition(x, z); 
float offset = 50;

MeshInstance3D block = BlockMesh.Instantiate() as MeshInstance3D;
block.Position = new Vector3(x, offset + y / 2, z);
block.Scale = new Vector3(1, offset + y, 1);

AddChild(block);
</code></pre>

<p align="center">
<img src="/assets/images/img-006.png" width="70%" height="70%" />
</p>

<p>Which should look something like this - resulting in a smoother, solid chunk.</p>

<h1 id="okay-but-how-to-terrain">Okay, but how to terrain?</h1>

<p>Everything we’ve done so far has been setting up for what’s about to come. We’re ready to finally tackle <em>procedural terrain</em>.</p>

<p>While there are a variety of methods that could be used, one of the most prominent is called <a href="https://en.wikipedia.org/wiki/Simplex_noise/">simplex noise</a>. Simplex noise can be used to generate a smooth 2D heightmap, given our coordinates (X, Z) which sounds awfully like something we’ve already implemented, <strong>GetHeightAtPosition()</strong>.</p>

<p>Most game engines come with noise libraries pre-installed, but there are open-source implementations should you find yourself unlucky.</p>

<p>In Godot, we can use the <a href="https://docs.godotengine.org/en/stable/classes/class_fastnoiselite.html">FastNoiseLite</a> library, like so:</p>

<pre><code class="language-c#">public partial class world : Node3D {
    public FastNoiseLite Noise = new FastNoiseLite();
    ...
}
</code></pre>

<p>And then if we modify our height function:</p>

<pre><code class="language-c#">float GetHeightAtPosition(float x, float z) {
    return 50 * Noise.GetNoise2D(x * .4f, z * .4f);
}
</code></pre>

<p align="center">
<img src="/assets/images/img-007.png" width="70%" height="70%" />
</p>

<p>It gives us something that looks like this. Fantastic!</p>

<blockquote>
  <p>Note: the generated chunk might not look the exact same, depending on the noise library that you use.</p>
</blockquote>

<p>If you would like more information on noise and how it can be used to generate more complex terrain, I highly recommend you visit this <a href="https://www.redblobgames.com/maps/terrain-from-noise/">amazing website</a>.</p>

<h1 id="neat-so-whats-next">Neat, so what’s next?</h1>

<p>In this post we went over a quick and dirty way to create convincing terrain! In the next one we’ll go deeper into how we can refine our code, and how we can generate our terrain chunks at a time!</p>

<p>Until then, stay tuned!</p>]]></content><author><name>Toby</name></author><category term="Other" /><summary type="html"><![CDATA[Ever wonder how games like Minecraft, Astroneer or No Man’s Sky create those incredible open-world settings? Entire solar systems yet to be explored, resources just waiting to be utilized! Undoubtedly it wouldn’t be very practical to store all of that data on disk, so how do they do it? The answer, as you might have guessed by the title - procedural generation!]]></summary></entry><entry><title type="html">Opening statement</title><link href="http://twmh.fyi/2022/09/10/presentation.html" rel="alternate" type="text/html" title="Opening statement" /><published>2022-09-10T23:42:26+00:00</published><updated>2022-09-10T23:42:26+00:00</updated><id>http://twmh.fyi/2022/09/10/presentation</id><content type="html" xml:base="http://twmh.fyi/2022/09/10/presentation.html"><![CDATA[<p>Have you seen him?</p>

<p><img src="/assets/images/back.jpg" width="100" height="100" /></p>]]></content><author><name>Toby</name></author><category term="Other" /><summary type="html"><![CDATA[Have you seen him?]]></summary></entry></feed>