<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1667313809239009473</id><updated>2026-05-18T15:21:54.989+02:00</updated><category term="game development"/><category term="video"/><category term="unity"/><category term="POV-Ray"/><category term="procedural"/><category term="game design"/><category term="locomotion"/><category term="TheCluster"/><category term="vr"/><category term="Eye of the Temple"/><category term="demo"/><category term="design"/><category term="eas"/><category term="graphics"/><category term="article"/><category term="gdc"/><category term="carreer"/><category term="ai"/><category term="aichallenge"/><category term="meta"/><category term="press"/><category term="usability"/><category term="LayerProcGen"/><category term="The Big Forest"/><category term="flipside"/><category term="modeling"/><category term="game culture"/><category term="A Study in Composition"/><category term="PuzzleGraph"/><category term="inspiration"/><category term="stereogram"/><title type='text'>runevision blog</title><subtitle type='html'>Posts about game development projects and other thoughts by indie game developer Rune Skovbo Johansen.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://blog.runevision.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default?start-index=26&amp;max-results=25'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>135</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-6814106630667320914</id><published>2026-03-30T15:29:00.012+02:00</published><updated>2026-04-30T23:06:30.186+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="article"/><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>Fast and Gorgeous Erosion Filter</title><content type='html'>&lt;p&gt;This blog post and the &lt;a href=&quot;https://www.youtube.com/watch?v=r4V21_uUK8Y&quot; target=&quot;_blank&quot;&gt;companion video&lt;/a&gt; both explain an erosion technique I’ve worked on over the past eight months. The video has lots of elaborate animated visuals, and is more focused on my process of discovering, refining, and evolving the technique, while this post has a bit more implementation details on the final iteration. I suggest watching the video first, but it’s not required. You can also skip right to the &lt;a href=&quot;#links&quot;&gt;links&lt;/a&gt; at the end.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/r4V21_uUK8Y?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;In the real world, rainfall on mountains tends to converge into water streams and rivers, which carve gullies in the mountain sides. These gullies may form branching patterns, as smaller water streams merge into larger ones. And the gullies often butt up against each other, leaving sharp ridges dividing them.&lt;/p&gt;

&lt;p&gt;But when generating virtual landscapes, the simulation of countless water drops is slow. It’s not very suitable for generation in chunks either, which means it’s not practical to use when generating landscapes that are too large to generate all at once.&lt;/p&gt;

&lt;p&gt;This means techniques are sought after, which can produce the appearance of erosion without having to deal with simulating the process of it. This post is about such a technique.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeWotRn8KxGEbVTCIl1-znAH0ZDNSwFUf7hkp9GrJ4u5jfK8zS8-sA1SHtWyBaHSLx3Lskzcr0z_XzW9y4847lBQo8e_1TIHa49EQXT1XFbv0lui_ZKX-hNlpDChD3Wq3Rz9n4HcB3MwEosYU5Xi_IOTzADWDd18u4joJcgUOF94ZN-HNhLdZ_8tvnBpM/s1600/ErodedTerrain.png&quot;/&gt;
&lt;figcaption&gt;Screenshot of &lt;a href=&quot;https://www.shadertoy.com/view/wXcfWn&quot; target=&quot;_blank&quot;&gt;Advanced Terrain Erosion Filter&lt;/a&gt; Shadertoy by me.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It’s essentially a special kind of noise which produces gorgeous branching gullies and ridges, while still allowing every point to be evaluated in isolation, which means it’s fast, GPU-friendly, and trivial to generate in chunks.&lt;/p&gt;

&lt;p&gt;Furthermore, rather than defining the landscape entirely, it can be applied on top of any height function, essentially applying erosion on top as a filter.&lt;/p&gt;


&lt;h3&gt;Background&lt;/h3&gt;

&lt;p&gt;There’s a website called Shadertoy where people create and share standalone shaders. A shader is a program that runs on the GPU, which can be used to determine what a virtual surface should look like, or for various other effects, or even entire scenes.&lt;/p&gt;

&lt;p&gt;In 2018 a user called Clay John (&lt;a href=&quot;https://bsky.app/profile/clayjohn.bsky.social&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt;) posted a Shadertoy called &lt;a href=&quot;https://www.shadertoy.com/view/MtGcWh&quot; target=&quot;_blank&quot;&gt;Eroded Terrain Noise&lt;/a&gt;. He wrote:&lt;/p&gt;

&lt;blockquote&gt;This shader is the result of a long time dreaming of a noise function that looked like eroded terrain, complete with branching structure, that could be run in a single pass pixel shader. I wanted to avoid anything simulated because then you cannot easily make infinite terrains.&lt;/blockquote&gt;

&lt;p&gt;That dream sounds familiar, but Clay John actually made it work. His Shadertoy is the original version of this technique. Hats off to him.&lt;/p&gt;

&lt;p&gt;Later, in 2023, a user called Fewes, aka Felix Westin (&lt;a href=&quot;https://fewes.se/&quot; target=&quot;_blank&quot;&gt;website&lt;/a&gt;), posted a Shadertoy which built on top of the one by Clay John. &lt;a href=&quot;https://www.shadertoy.com/view/7ljcRW&quot; target=&quot;_blank&quot;&gt;Fewes’ version&lt;/a&gt; slightly tweaked how the erosion effect worked, and presented it in a vastly more polished way.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEFulcsG7Z3hyy8X6ruWkwpE-52GAKg110T7DZvm2FZSfOalDqIsx8PPuqBHtS34rudPGORpXke2cR6FW5rbJkjLeBIWZRzuLtmOpieMlKss-KZE6f3jUqMdUA9AYJGvspk7DGRzZ-75VH4DiVU1r6DXpLYJFveZHKSka58PZB5lyjHW_5vt-OHc_T0qM/s1600/Fewes.png&quot;/&gt;
&lt;figcaption&gt;Screenshot of &lt;a href=&quot;https://www.shadertoy.com/view/7ljcRW&quot; target=&quot;_blank&quot;&gt;Terrain Erosion Noise&lt;/a&gt; Shadertoy by Felix Westin (Fewes).&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In 2025 to 2026 I’ve implemented my own versions of the technique. First I made a version that addresses a few shortcomings of the original technique, and has more intuitive parameters. Eventually I developed a version that works in a completely different way, which produces crisper gullies and ridges and has more expressive parameters. But before going over the differences, let’s start with the basics of the original technique.&lt;/p&gt;


&lt;h3&gt;The basic idea&lt;/h3&gt;

&lt;p&gt;We start with a height function where we know not just the height at each point, but also the gradient, meaning the direction and steepness of the steepest ascent. Water flows in the opposite direction, so you can think of the negative gradient at each point as an arrow showing the direction that water would flow down the slope.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE9RPwClOLDigF9VuMMC2WkSDnNwzZwXTAkcIYHt0n9y2StHZZdgzl-Iv6sFhUZBqeSDqm3eVewJRNmqjCYilkWZHiJ3CiENcbyIdjVEJRIExW-4pdsqFyFZKt155ZHk5jqSQ6O_aZMWx_lj_kyku20fMjicVmpUdxe89Ns0dl8s4vMBJVX-1jsOyvUGA/s1600/Arrows.png&quot;/&gt;
&lt;figcaption&gt;The gradient at each point of the terrain surface is like an arrow showing the direction that water would flow down the slope.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Let’s start simple, with a slanted surface, where the gradient is the same everywhere.&lt;/p&gt;

&lt;p&gt;We use the gradient to add stripes that run along this direction. The stripes produce alternating gullies and ridges, that could plausibly have been created by water eroding the terrain.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYGTBNKViST5MtB1qrllTYySq-7t_XnPyZbOlAryub4xndokcfv2HFc4hbioGk-QzVMYxkNBrlgDIvU94ZCSf3uVUCB13-rkVD-2lpJ36fD3eqI52cV7KsxQXUuplcn8zP7SUdVb9ffPFAPjAK8exFIgUQ76TZ3k-p8R8OPW8XlsKGVta6bvIEDiCkP9k/s1600/Slant1.png&quot;/&gt;
&lt;figcaption&gt;A slanted surface with gullies created from stripes that follow the gradient.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The sides of these gullies and ridges come with their own gradients, which are added to the original to produce new combined gradients.&lt;/p&gt;

&lt;p&gt;We can then repeat the whole thing again at a smaller scale: Add smaller stripes which run along the new slopes. These form new gullies and ridges which naturally branch out at an angle from the first ones.&lt;/p&gt;

&lt;p&gt;By convention, each repetition is called an octave. Add a few more octaves, and we should be done, right?&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw5MZdzbQAU21oFxCH2ywuPP7FdVor4SDHfsaAAy3JIRQUBSa5-J4HnTmjYqfs7zpBhdr7HbcoH18kMA0W3AzKgGlfgog6zLoedJ3zs4ukG-V_sBeEP_XB_VufimUE30WS8ZNYlpj2mLkMr6Xo5vxIVQkU7bKb6F22H0hBeu7pzGkPsHRLZp6jh7neQvA/s1600/Slant3.png&quot;/&gt;
&lt;figcaption&gt;A slanted surface with multiple octaves of gullies, each one taking the changed slope from the previous gullies into account.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Except – it’s not quite as simple as I just made it sound.&lt;/p&gt;

&lt;p&gt;If we apply the erosion to our original height function, where the gradient is &lt;i&gt;not&lt;/i&gt; the same everywhere, we get a chaotic mess. Even if we show it with just a single octave, it’s still full of chaotic gullies that are often not aligned with the slopes at all. What’s going on?&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0pWjWHtAUjTL-Hs78zJkhzIMIKld0JRUhV12OWI8YOzAWB0T1fDUh57Km-L_h9t7j1W5aRFBztCyjDvtgGAtR3TACOZ-Bmaxk89s3YJNP17AGmlEz_Wi5Cm01l0s9BX0zcv9kS4-VaT6pUAt3nCo_8c7oqaqXQ_XfkoDDnZ4ZtoFhIFr4WcCXxxL_A2g/s1600/ChaoticGullies.png&quot;/&gt;
&lt;figcaption&gt;When rotating the stripe pattern to match a variable gradient, it results in chaotic stripes.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Generating stripes&lt;/h3&gt;

&lt;p&gt;To rotate the stripe pattern, we have to choose some pivot point to rotate it around.&lt;/p&gt;

&lt;figure&gt;
&lt;img class=&quot;smallimage&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpdzbfDZ_uJhITtblVwzDZsqF9-IgWC29KN0FT6BdQAb-gJ_1X-wVdejJ6TpUk_7izmVUP2Rfp2eBwiFDc-hM5syCVKVOZgqNANZisf98u5wGmgxSaTCV743zUAwktVB7EETNKl_9hv78nI_A686jHd4Ugmvax-1-RUPEfctQXHPQuoxdRJPJPOcyq6Qg/s1600/Stripes.png&quot;/&gt;
&lt;figcaption&gt;Rotating the stripe pattern requires choosing a pivot point to rotate it around.&lt;/figcaption&gt;
&lt;/figure&gt;  

&lt;p&gt;The problem is the rotation around this pivot point will create increasingly large distortions in the output the further away from the pivot point we are. This is because changes in the rotation angle not only changes the direction of the stripes at a given point, but also shifts &lt;i&gt;which&lt;/i&gt; stripe is under that point.&lt;/p&gt;

&lt;p&gt;The approach used in the erosion implementation is to divide the pattern into cells that each have their own pivot point for the stripes. If you imagine a square grid, there’s one cell per grid square, with its pivot placed randomly inside the square, similar to simple &lt;a href=&quot;https://en.wikipedia.org/wiki/Worley_noise&quot; target=&quot;_Blank&quot;&gt;Worley noise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We still get a bit of distortion, but it’s not too bad, since the pivot point is never too far away. At least as long as the gradient of the height function doesn’t change too drastically within a single cell.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH8BGLKq7TgOxbUDowNwtT7ME3iiRtwyLlx2xcJAdZmChjBvkPxGC0z93MJ5fzOKd2v6xl5inufMGG9uoV-rB8pSp1Krff9GII6xo8iGCSsxaLhLbgv5c3783jpkS57T7ry7BUAsAQNJT0NbEHOyCAUWaVdBeH_-fdJr1tBecrGqg-QL_jjLb-nJYCJ4A/s1600/CellsNonBlended.png&quot;/&gt;
&lt;figcaption&gt;The stripe pattern is divided into cells, and each cell has its own pivot point for rotation of its stripes.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQwr7DRQnO8kz3PsMV45g1x98RXWmgoKr89Iw1uDLGvrrlUkv9evyHPmSOoT5GPlo58OHSAXq39OOtPLcI64dL-3pk2JzbjP1T7rv3_peJknm6gdPg9bHf3U93342kqZ_dycjzvTy-YQS-4iDBPKnlulnb5qIcAGc_r7XZ_UxhjXyrSXi9CLqCIaN0d9I/s1600/CellsBlended.png&quot;/&gt;
&lt;figcaption&gt;The stripes of neighboring cells are blended together to avoid discontinuities between the cells.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To ensure smooth results without discontinuities, we blend the stripes of neighboring cells. The stripes are essentially extruded sine waves, specifically a cosine wave for the height offset and a sine wave for the derivative (slope).&lt;/p&gt;


&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg97QflC8Wkalg91isRBepBulX7Z8ePw3c5HROj-vJ72BhT5jbWNln8j5HfLmf-fSvhaA8TOojcXuTkjluQQSaBtrLFV5zjZofqJypjDWESqahg4DzEDNWeAn-PdraSYy9vf2-8_U5xvRJSE7CfDxfC4jXCy-YPwAO29rY_hVmXS1T3u72SQ1UeyQHgiPo/s1600/DerivativesCos.png&quot;/&gt;
&lt;figcaption&gt;The gully height offset follows a cosine wave, and the slope follows a sine wave.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The reason the stripes blend so nicely together even when not aligned, is that if you blend two unaligned sine waves, you just get a new sine wave with a smaller amplitude.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnIK_x0teY_YrsfiREhj2Jli9NL648INkIDmohj6FSaDfss2AQ1UhDIAm6avvH-pdwLj6k7-yY16gT5To7fXydASMZq4Fdo_4J0GL1dmogLRy9Evl0YHOBgKaVozLuuivzU4fEjXWgrSjibZUwxNJH8wuKylfUVeypuSyX6pDNmuhm7xGEPYbO4wwz5fw/s1600/CellsComparison.png&quot;/&gt;
&lt;figcaption&gt;The blending can transform unaligned stripes from different cells into a long continuous stripe.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The cell size has a big effect. If we choose a cell size that’s large compared to the stripe width, we get significant distortion issues, just like when we used a single pivot point. If we choose a small cell size, there’s barely room for any stripes, and we get a kind of grainy noise instead.&lt;/p&gt;

&lt;p&gt;If we make the cell size even smaller relative to the stripe thickness, the pattern begins to be all white. Or in terms of ridges and gullies, it’s all ridge and no gully. This is because each cell uses a stripe pattern with a white stripe in the center.&lt;/p&gt;


&lt;h3&gt;Preserving peaks&lt;/h3&gt;

&lt;p&gt;When I talk about peaks and valleys, I’m referring to the local maxima and minima of the original height function, whereas when I talk about ridges and gullies, I’m referring to the local maxima and minima of the gully stripes applied in each octave of the erosion filter.&lt;/p&gt;

&lt;p&gt;Now that we can generate stripes aligned with any gradient, we can apply our erosion effect to the height function without getting chaotic distortions.&lt;/p&gt;

&lt;p&gt;However, although we’ve now got nice gullies on the mountain sides, the mountain peaks look wrong. They barely look like peaks at all.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ0uFH8tYU0vc87kDMh5uuOS0FzuLPqV1RNVM3WitvsCxjAMLaNGp7ZEX_8pYC4_FLYh5wM3ojDl-akdyKovGi1JeeyQMoS1bNrrQWzoLfrX2fgA2qxVzU7NV7S3R9f2zCjJoO4WhEa9oNXOirMV9kfFOwHC5EjV_JX8OUJBEzYeZg8URdvB2z43eiSTY/s1600/PeaksLookWrong.png&quot;/&gt;
&lt;figcaption&gt;At peaks and valleys of the original height function, where the slope changes abruptly, the erosion effect creates messy folds.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;That’s because the peaks may be located anywhere in our stripe pattern, and they get arbitrarily lifted or lowered based on that. Furthermore, there’s an issue whenever the surface steepness approaches zero, which happens at peaks and valleys. When the slope is zero, the gradient has no defined direction, so the direction of the gradient changes abruptly around those spots, which creates chaotic stripe patterns in the surrounding area.&lt;/p&gt;

&lt;p&gt;There are two ways we can address this, and both are based on the steepness of the slopes. There’s the original approach used by Clay John and Fewes, which I call &lt;i&gt;the frequency approach&lt;/i&gt;, and there’s an alternative approach I came up with, which I call &lt;i&gt;the fade approach&lt;/i&gt;.&lt;/p&gt;


&lt;h3&gt;The frequency approach&lt;/h3&gt;

&lt;p&gt;The original approach used by Clay John and Fewes is to make the stripe frequency proportional to the slope, so the stripes are thicker, the flatter the terrain is.&lt;/p&gt;

&lt;p&gt;At peaks and valleys, where the steepness is zero, the stripes become infinitely thick. And because each cell has a white stripe in the center, this means mountain peaks and valleys, where the slope is zero, always land on the part of the stripe pattern that corresponds to a ridge, and never a gully.&lt;/p&gt;

&lt;p&gt;This works great for mountain peaks, but I discovered that it unfortunately causes valleys to have bulges at the bottom, since they land on &quot;ridges&quot; in the stripe pattern too. This is not visible in their Shadertoys, because they have faded out the erosion at lower altitudes. And this workaround is great if you want smooth valleys.&lt;/p&gt;

&lt;p&gt;However, if you apply the erosion at equal strength everywhere, the bulges at valleys appear, and it means you can’t get crisp, V-shaped valleys.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPimRfNKgt1L1Ae2rwBHAUbxcYt3wICDiupFgKsnnY7d7hyphenhyphene3jIooaLwZSHr-cPhsHK-STGjZiyez3rhy8mcMgSpoa7adCeLUXbrlGJtUfrD-hh1jEsgnKdD-zBCOP60MoCVpRMQeTAN7rqzbrMnmIFW8DeDkJFT26E1IfAwJBgLzHupCH3tm0_E-JPkc/s1600/Bulges.png&quot;/&gt;
&lt;figcaption&gt;The frequency approach produces bulges at the bottom of valleys if it’s applied at full strength everywhere.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;You can find &lt;a href=&quot;https://www.shadertoy.com/view/33cXW8&quot; target=&quot;_blank&quot;&gt;my Shadertoy here&lt;/a&gt; based on the frequency approach. It’s similar to the one by Fewes, but is refactored to have more intuitive parameters.&lt;p&gt;


&lt;h3&gt;The fade approach&lt;/h3&gt;

&lt;p&gt;I came up with a different approach, which is to keep the stripe widths consistent and instead fade out the stripes where the steepness approaches zero. If we fade towards &quot;white&quot; – the maximum value of the gully octave – we get a similar effect as with the frequency approach, that the shape of peaks is preserved, but there are bulges at the bottom of valleys.&lt;/p&gt;

&lt;p&gt;Now, if we fade towards &quot;black&quot; instead – the minimum value of the gully octave – we don’t get any bulge at the valleys, but instead we get a crease at the peaks. But if we fade towards a value that goes from black at mountain valleys to white at mountain peaks, we can get nice crisp peaks and valleys at the same time.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbpDYExYmgfIJjC4hkA1aCyf46jRpwoF_Thgkqqn5WJAHRpTewY_d5dqQAUa4EVSiuoTCAfvZSUdgqmQD7wyQAOwRNKLEtQiNDY8dBox16HefZtc3XG7HU_VP7YyrXSR67IFaPIjdCDGYAglLt15KWxfjiKFn0yrWC4lFlhMUnumAoZIs3kos0_GOCfSI/s1600/TerrainUniformFreqSmoothingOffWithInvPow5.png&quot;/&gt;
&lt;figcaption&gt;The fade approach can produce nice crisp peaks and valleys at the same time.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In my implementations, I let it be up to the user to supply this &lt;i&gt;fade target&lt;/i&gt; value as an input parameter to the erosion function, for example based on altitude.&lt;/p&gt;

&lt;p&gt;For a height value &lt;var&gt;h&lt;/var&gt; at the current point, it could look like this, if the expected height range goes from &lt;var&gt;valleyAlt&lt;/var&gt; to &lt;var&gt;peakAl&lt;/var&gt;t:&lt;/p&gt;

&lt;pre&gt;
float inverse_lerp(float a, float b, float v) {
    return (v - a) / (b - a);
}
&lt;/pre&gt;

&lt;pre&gt;
// Convert the altitude to a value between -1 and 1.
float fadeTarget =
    inverse_lerp(valleyAlt, peakAlt, h) * 2.0 - 1.0;
&lt;/pre&gt;

&lt;p&gt;The fade approach has a different issue that needs to be carefully handled. It initially seemed to create visible folds – also called discontinuities – caused by abrupt changes in the gradient directions around the peaks and valleys. But I later found out that this can be addressed by using an appropriate shaping function on the slope.&lt;/p&gt;

&lt;p&gt;From early on, I had been raising the steepness of the slope to a power of 0.5, which is equivalent to taking the square root of the slope. This applies erosion more evenly than if we used the slope directly. Unfortunately it produces sharp discontinuities at peaks and valleys. This is because the square root curve starts off vertically, so as the slope increases from zero to even the tiniest slant, the erosion immediately increases drastically.&lt;/p&gt;

&lt;div class=&quot;imagelist sectiongrid&quot;&gt;
  
&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLBGsR-QvsV-P-NNQEVTwW8HfdB74GsIS6WHQCaJvUQioJC7TYcyDPsJYDWi4etlDzjROBAQOxcYNSh-hCc5ACY6aPa0COn9XVXfnHIgO4CK0yXDYg2xKcYDRP_RtENSrOGZ1PrlEIPhZPXb2uepcFHOu5ZuwCi03ObQ9cP-LScr652JagTZh2adW3WXw/s1600/CurveSquareRoot.png&quot;/&gt;
&lt;figcaption&gt;Erosion magnitude based on slope&lt;sup&gt;0.5&lt;/sup&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
  
&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEThgnyBSHlyBxTkxk87xLP4x8WXdpmHOV4DbLlglBCAKhV19IfypyrAxfCG5vXwpaBruZupPdwnWyapQe22ynNnwN9owbCgO8CAA4LrsL_wHr3V4dMTVy50MuLOEuXP3nCzAUvCD4K6Q8UusZDPiFy1vej0YUQa9NGK_j-qQry1Z6sJR0ZlvRudDuo0Q/s1600/CurveInvSquare.png&quot;/&gt;
&lt;figcaption&gt;Erosion magnitude based on 1 - (1 - slope)&lt;sup&gt;2&lt;/sup&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;

&lt;p&gt;But there are many other functions we can use to shape the erosion. The one I ended up using is to flip the curve vertically by subtracting it from one, then raising it to a power of two, and then flipping the result back.&lt;/p&gt;

&lt;pre&gt;
float ease_out(float t) {
    // Flip by subtracting from one.
    // The saturate function clamps between 0 and 1.
    float v = 1.0 - saturate(t);
    // Raise to a power of two and flip back.
    return 1.0 - v * v;
}
&lt;/pre&gt;

&lt;p&gt;This has a somewhat similar shape as the square root – in fact it’s mirrored around the diagonal – but the curve starts off much more moderately. This mostly removes the appearance of discontinuities, especially when we layer multiple octaves of gullies.&lt;/p&gt;

&lt;p&gt;With this tweak, the fade approach works just as well as the frequency approach. And unlike the frequency approach, it works well when applying the erosion at full strength everywhere, which can be used to create sharp V-shaped valleys, if desired.&lt;/p&gt;


&lt;h3&gt;The quest for crisp, branching gullies&lt;/h3&gt;

&lt;p&gt;The erosion we’ve got so far looks nice, but the larger gullies and ridges get a little bit lost in the smaller ones. I’d prefer if the gullies at all scales could have crisper ridges and creases, and more clearly show a branching pattern.&lt;/p&gt;

&lt;p&gt;To address this, I did a lot of experimentation, and developed three techniques that go hand in hand. I call them stacked fading, normalized gullies, and straight gullies, and I’ll go over each of them in the next sections.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfcLRYwoWYbhNCgSZ4TbYH1IwkEJ4oUOdGQGFu__htWTLpOf_7lADrC4kcmCAVwp0c5KEmr60ikv-vk9Dc0aYmdpebZNLjjdR5USixRwwqJi0HId4i4JQ10EuzQDV-HPHIXyf_Z0JS51iBsU4w7FTqvm59TxB4sMVTBgeTP1lIUANBVgtVK0xAryIsrMw/s1600/TerrainCompUniformFreq.png&quot;/&gt;
&lt;figcaption&gt;In the techniques developed so far, the ridges of larger gullies get somewhat broken up and lost in the smaller ones.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTWAmCSo2fZGTn8zAePA6AhsXnctXD3tgV6VbDw01GQTn4KuhfHpd-AXI-4Yh6FcxubeaB1ocRpUglKB0dl8kS327w7zQgJrUq3Wevgs4ptoqfIlqcxnhMPTo30GLzhtRl-sfJFUA0TVicxRhWlkC5WajA32eo4BoQnSVWaGoKnZiSq-CBxga2JYPB-vE/s1600/TerrainCompCrispNorm.png&quot;/&gt;
&lt;figcaption&gt;By using techniques I call stacked fading, normalized gullies, and straight gullies, the ridges of larger gullies remain more crisp and unbroken, and the branching pattern of gullies of different sizes becomes more clear.&lt;/figcaption&gt;
&lt;/figure&gt;

  
&lt;h3&gt;Stacked fading&lt;/h3&gt;

&lt;p&gt;We already fixed a problem with crispness earlier. The mountain peaks and valleys didn’t look crisp until we began fading towards black or white for the valleys and peaks respectively. And it turns out we can do something similar for the gullies and ridges.&lt;/p&gt;

&lt;p&gt;Let’s establish a few terms first.&lt;/p&gt;

&lt;p&gt;I’m calling the value we fade towards the &lt;i&gt;fade target&lt;/i&gt; and it’s generally expressed in a variable that goes from -1 at valleys to 1 at peaks.&lt;/p&gt;

&lt;p&gt;Then there’s the amount we’re fading towards the fade target. We’re doing a weighted average (also known as a lerp or a mix) of the gullies and the fade target, which can be 100% gullies at steep slopes, 100% fade target at flat terrain, or some mix of the two, depending on the slope. We can think of this as a &lt;i&gt;mask&lt;/i&gt; applied to the fade target, before we layer it on top of the gullies.&lt;/p&gt;

&lt;p&gt;When we’ve been talking about &lt;i&gt;the fade approach&lt;/i&gt;, the fade target and mask have been based on the original height function and its slopes. But just like we don’t want gullies right on top of the mountain peaks or valleys, we also don’t want smaller gullies right on top of the ridges or creases of larger gullies. We can achieve this if we conclude each octave by updating the mask and fade target to also be black and white at that octave’s creases and ridges.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI7Jj1UeZKwhulCQLwjAXWxe7peI4JC30OWG5wx-NEsMPIugGyE0TWwiDwZyWt9ua-r540pWdLyOAvigjairB9SocZQFWQKEUAwQF3GcTZYcbRwNPtl5OqW5ydJIJb5CGCwCv4dnqWsSRfLqrwBdqwzUSFzRtNGFTH9ayWQPi4wJfxLzsZ1jkLZ1D7H4U/s1600/FlowChart.png&quot;/&gt;
&lt;figcaption&gt;Flow chart of how the &lt;i&gt;fade target&lt;/i&gt; and &lt;i&gt;masks&lt;/i&gt; affects each octave of gullies.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The diagram above may seem daunting, but here’s the gist of it:&lt;/p&gt;

&lt;ul&gt;
  
&lt;li&gt;The &lt;i&gt;octave 1 raw gullies&lt;/i&gt; are faded towards the &lt;i&gt;input fade target&lt;/i&gt; based on the &lt;i&gt;input mask&lt;/i&gt; to produce the &lt;i&gt;octave 1 faded gullies&lt;/i&gt;. You can think of it as the masked fade target being &quot;overlaid&quot; on top of the octave 1 raw gullies. Nothing new so far.&lt;/li&gt;
  
&lt;li&gt;The &lt;i&gt;octave 1 faded gullies&lt;/i&gt; are then used as the new fade target for the next octave. The mask is also updated: From the &lt;i&gt;octave 1 raw gullies&lt;/i&gt;, a mask contribution is created which is opaque at the creases and ridges, where the slope is zero. The existing mask is layered on top of the new mask contribution to produce the new &lt;i&gt;combi-mask after octave 1&lt;/i&gt;.&lt;/li&gt;
  
&lt;li&gt;The same steps are repeated for each new octave. The &lt;i&gt;octave 2 raw gullies&lt;/i&gt; are faded towards the new &lt;i&gt;fade target&lt;/i&gt; based on the new &lt;i&gt;combi-mask&lt;/i&gt; to produce the &lt;i&gt;octave 2 faded gullies&lt;/i&gt;. These are used as the new fade target, and the mask is updated with a new contribution based on the octave 2 raw gullies. And so on.&lt;/li&gt;
  
&lt;/ul&gt;

&lt;p&gt;In broad terms, each new octave adds more ridges and creases to the terrain surface, which increasingly restricts the surface area where subsequent gullies can have any influence on the surface.&lt;/p&gt;

&lt;p&gt;How are new mask contributions combined with the existing combi-mask? Let me start by saying that it was easiest in the diagram above to conceptualize the mask as being applied to the fade target, but in the code it’s actually a mask applied to the gullies, so 0 means all fade target and 1 means all gully. In this form, the new mask contribution can simply be multiplied onto the combi-mask to produce the new combi-mask.&lt;/p&gt;

&lt;p&gt;We can furthermore implement a useful control here. By raising the inverse of the combi-mask (meaning its complement) to some power before multiplying it with the new contribution, we can control how detailed the erosion looks. Lower values restrict the effect of higher frequency gullies to steeper slopes.&lt;/p&gt;

&lt;pre&gt;
float pow_inv(float t, float power) {
    // Flip, raise to the power, and flip back.
    // The saturate function clamps between 0 and 1.
    return 1.0 - pow(1.0 - saturate(t), power);
}
&lt;/pre&gt;

&lt;pre&gt;
combiMask = pow_inv(combiMask, detail) * newMask;
&lt;/pre&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtOkcWQeY4VcdtEooy2S5zmvRCqBt0KmSSAIL3-_Z28Ico_prAS-ETAKO_XnTPNdoEf1xzYuu70YQ3oz4YYyX4ru70VxUgkytUkN4P18qPG0AwV_3ydHiHNxSTXr7mZEpFNeWIT3CVOJxsNojEO66BiysOpMOPT9-dL99Rlcx46_9Akg1Qq9RK4ORv_7U/s1600/ErosionDetail.png&quot;/&gt;
&lt;figcaption&gt;From left to right, the detail parameter has been set to 0.7, 1.5, and 3.0, respectively.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Normalized gullies&lt;/h3&gt;

&lt;p&gt;One thing that’s holding back crisper ridges and creases is the inconsistent magnitude of the gullies, caused by the interpolation of stripes that may or may not be well aligned.&lt;/p&gt;

&lt;p&gt;At one point I realized that since we interpolate both cosine and sine waves in parallel, we can think of each cosine/sine pair as a point on a unit circle, and the interpolated value as a point on a circle too. The interpolated circle point may have shrunk to a radius smaller than one, but it’s trivial to normalize it back to one. And this in turn means that both the interpolated cosine and sine waves have a consistent magnitude of one.&lt;/p&gt;

&lt;p&gt;Now, in the actual interpolated stripe function we’ve used up until this point, the sines are multiplied with a vector orthogonal to the terrain gradient in order to calculate the gradient of the slope. But since this vector is the same for all contributing samples, the multiplication can be postponed and applied to the interpolated result rather than to each contributing sample, leaving us free to perform the normalization first.&lt;/p&gt;

&lt;p&gt;When straightforward normalization is applied, some curious artifacts appear where ridges and creases join up and form loops. Supposedly, this happens at points where the interpolated waves cancel out completely; something that seems to unavoidably happen with some regularity. On the terrain, this manifests as spiky protrusions (and holes).&lt;/p&gt;

&lt;p&gt;However, the loopy artifacts can be avoided if we only normalize lengths above a certain threshold. To avoid discontinuities between normalized and non-normalized gullies, we can use the following approach:&lt;/p&gt;

&lt;ul&gt;  
  &lt;li&gt;Scale lengths by a factor &lt;var&gt;k&lt;/var&gt; that’s larger than one.&lt;/li&gt;
  &lt;li&gt;Clamp resulting lengths to one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve used a factor &lt;var&gt;k&lt;/var&gt; of 2, such that lengths greater than 0.5 become normalized. This produces a good tradeoff with lots of gullies of consistent magnitude and without loopy artifacts.&lt;/p&gt;
  
&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyuYeEPMbAkYF1LZH7dwCmosEcQp4lAb3bUk8slU1YelMJ_MpiRtNB_UXf88-F9OCaFXkkPZX5JCGgJ89SCDXDDIoIMU_hLUtYikend0stBKkOyaS1TMH7bEN-b-x2v20hsBHbEFKgz1VKsX0Ey6XkTUAT7LpwCydB3e8WT6xTqpOhyaIEhjIjQB3FBNQ/s1600/NormalizedNone.png&quot;/&gt;
&lt;figcaption&gt;Gullies with no normalization have inconsistent magnitudes.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMWR59ybV4x0IYT5qq0rsR0xHfG1e5qPYhRxeTy5PTPTylLaAEuWibEOg5VWouQRWSdCVCGhpw_v-PEAuxwrHu2-MXf6p4owhJtoYLJldPFQgDunwTJly_LB0If18UQT3AzXHeWSvQwftMHAUxGKmHDuS01J2d3se-3leuPbW7n2S6cF70S63615EL-Yc/s1600/NormalizedFull.png&quot;/&gt;
&lt;figcaption&gt;Full normalization of all gullies produces spiky protrusions.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjckxYDDdOnjV28YoZp0f723WtfbBPjWrdqrW1Z3W0RaHE_d1RF3ww80tEUOHk6KR_uGaizum4WdKPrOhJ0TDsetDrdPKxhbCsygN9jjwy2aZSgdFcch-I8QJzvY5Yjd4ZRPhxhQEu593kN_7Kd0WcnjdAWAM8MCuR0LIRRMPueNWrFNa4uHZLTEa9VepQ/s1600/NormalizedHalf.png&quot;/&gt;
&lt;figcaption&gt;Normalizing only gullies of magnitudes 0.5 or greater results in a good tradeoff.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The style of partial normalization I’ve chosen produces second order discontinuities (abrupt changes in slope) in some places, but as it’s not noticeable once multiple octaves are used, I haven’t bothered with a more sophisticated approach.&lt;/p&gt;

&lt;p&gt;I figured that the ability to produce directional noise is useful for many other purposes than erosion, so I’ve released the noise function as &lt;a href=&quot;https://blog.runevision.com/2026/01/phacelle-cheap-directional-noise.html&quot; target=&quot;_blank&quot;&gt;Phacelle Noise, which I’ve written about here&lt;/a&gt;.&lt;/p&gt;


&lt;h3&gt;Straight gullies&lt;/h3&gt;

&lt;p&gt;Once the ridges and creases got more crisp, another issue became apparent. Smaller ridges and creases would often run along larger ones for a little distance before branching out.&lt;/p&gt;

&lt;p&gt;It’s here that the limitations of modeling gullies as extruded sine waves becomes apparent. See, on the side of gullies, the terrain slope is strongly affected by it, pointing sideways away from the ridges. But at the bottom and top of gullies, they have virtually no effect on the terrain slope. So at those points, smaller gullies will simply run parallel to the larger ones.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlQPscH3o0A3fNIU6pl5zgR72t7_8a1FbWJYQeelQjyvnY3WKJOoUpPhU6fS4Z_qlL_XoYf8BTFVQ2z0zkFtmi70f8JxKQpviUwkYIEbG1hQCrYuDxItNRTW6SvgyTvFbYQPbEi_KEq8u1CNqgyBSy4_4TWkqbfC6soYdwYqimVB0oHZDhEJR66zCIIE8/s1600/TerrainSineExtrudeArrows5.png&quot;/&gt;
&lt;figcaption&gt;The terrain slope is not affected by gullies on top of their ridges or at the bottom of their creases.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Since the effect is gradual, smaller gullies tend to curl at the ends, rather than branching off cleanly from the larger gullies. A visualization of the ridges and creases with just two octaves of gullies shows the difference clearly.&lt;/p&gt;

&lt;div class=&quot;imagelist sectiongrid&quot;&gt;
  
&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjlWBWc_OWeyzaMBXBY5ix4Rt-pbW6VGdw-ODq9Mt4EaJAA-xszoWTsHnz04GmAWCYMB55wZY2B7bBej7nKLKwvw19lGxPLvI-OXfNdMrQ53n7pZQBs8qT_GzS3NETyAnhnTfwqDsgXPQBi5TU4LF_LHfft2G5T0L1_AozxnuIqoPcICrMO89CrAMfkJQ/s1600/straight_gullies_off_zoom.png&quot;/&gt;
&lt;figcaption&gt;Ridges and creases with curls at the ends.&lt;/figcaption&gt;
&lt;/figure&gt;
  
&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgd9LALmQf8lR9nHWwWWhFDRdy7aDeYdEcXxhAjwSCo69gbz2nV9_UzdNL3iBwrwo-Zpo5WQVHwNzarezrVu4SZn34p5jY6yHh8aLRSauGeW-tAOMJaBg4SoO4mIbzSEaumiwL64hLXLDT_ugh4BgNOc_tQUdZbPB9lXzC_iLUicoqo63rteJOAatWKOqI/s1600/straight_gullies_on_zoom.png&quot;/&gt;
&lt;figcaption&gt;Ridges and creases that branch out cleanly.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;

&lt;p&gt;The effect of non-straight gullies is more subtle on the actual terrain surface. But when carefully comparing the images below, you may find that the first one, which does not have straight gullies, has more instances of ridges with small grooves on top, less instances of gullies branching out at clean angles rather than curving, and an overall texture which feels a bit more stringy and smushy.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpJfjH7ldJZoWQYJzRISygYuoNE3C__CBAxiXuT7vHfaVh_RROnqMkCPpegKBlQFbidyrGjxv9xhcy6BL0cPFlt25Q07KIRlfH8sU_z8jY6IBvSzQsOYyMG0ib1XTmObvkzgwtq9k-4ZhU6OTPdEwapTpHrsW7xmebUtqjs500wuqG4HuwITHjGU2ZRjA/s1600/TerrainCompCrispNormNonStraight.png&quot;/&gt;
&lt;figcaption&gt;An eroded terrain without the straight gullies technique.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTWAmCSo2fZGTn8zAePA6AhsXnctXD3tgV6VbDw01GQTn4KuhfHpd-AXI-4Yh6FcxubeaB1ocRpUglKB0dl8kS327w7zQgJrUq3Wevgs4ptoqfIlqcxnhMPTo30GLzhtRl-sfJFUA0TVicxRhWlkC5WajA32eo4BoQnSVWaGoKnZiSq-CBxga2JYPB-vE/s1600/TerrainCompCrispNorm.png&quot;/&gt;
&lt;figcaption&gt;An eroded terrain with the straight gullies technique.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I fixed the issue of non-straight gullies by essentially faking consistent slopes when calculating the slopes used for the gully stripe pattern directions.&lt;/p&gt;

&lt;p&gt;We can pretend that the slope of a gully is constant from top to bottom, as if the gullies were extruded triangle waves instead of sine waves. The faked slope is implemented by using the sign of the sine wave that controls the gully slope, rather than using its value directly. That is, if the sine is negative, we use a value of -1, and otherwise a value of 1.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirBmVH69p-r91C0UvSE89EJv23PRx8u2AlEAoelcPjGunMSTQWNNANTg2ZM3hvKPSR5Igxt9kQ7a__9c-pMLWtrFN1LNN8z8xeO016MZ1QppGrzLid1oLRVQGJJ7nRJpfqKdqnYJRQOnkEcXCdM-Zho3wRPJ3ThHE1iAtiWDom1ME-dFejVkLFpSMSZx8/s1600/DerivativesSign.png&quot;/&gt;
&lt;figcaption&gt;The derivatives of the gullies follow the sign of the sine wave, as if the gullies were straight from top to bottom rather than curved.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I also tried making the gullies actually be extruded triangle waves, but due to complex interactions in how the different octaves combine, that just ended up looking worse.&lt;/p&gt;

&lt;p&gt;One aspect of the overall erosion technique I haven’t explicitly covered yet is that it outputs not only the heights of the eroded terrain, but also the analytical derivatives. However, those derivatives were never very accurate, whether in Clay John and Fewes’ implementations or my own. They are used internally to calculate the gully directions, but the output derivatives were never actually used for anything.&lt;/p&gt;

&lt;p&gt;But even if not accurate, they can still come in handy, so I don’t want to remove support for them. (I actually did begin using them to calculate tree coverage.)&lt;/p&gt;

&lt;p&gt;With the &lt;i&gt;fade approach&lt;/i&gt;, the mask is also used on the derivatives of each octave. They are faded towards a slope of zero rather than the &lt;i&gt;fade target&lt;/i&gt; value, which is only relevant for heights. But fading the derivatives towards zero at ridges and creases undermines the straight gullies technique.&lt;/p&gt;

&lt;p&gt;So I began calculating derivatives in two different ways in parallel. The output derivatives are stored as part of a &lt;var&gt;heightAndSlope&lt;/var&gt; variable whereas the internal version is stored in a &lt;var&gt;gullySlope&lt;/var&gt; variable. And while the former is faded towards zero according to the mask, the latter is not.&lt;/p&gt;

&lt;p&gt;The faked gully slope does mean that the new straight gullies created based on it have discontinuities at the creases and ridges of the faked slopes, as stripes going in different directions butt right up against each other. This can be seen in the &lt;i&gt;octave 2 raw gullies&lt;/i&gt; part of the diagram from earlier.&lt;/p&gt;

&lt;p&gt;But these discontinuities are fully faded away in the faded gullies used for the output height offset (and output derivatives), so they’re not a problem.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhofOZ_k_mBqwLHAZKvg3U3PaWap2TPOxr5fI0YB6ANfOTO4bhyphenhyphenZrM3L2iIg2b4wTenhcfVOgP_aMXgv7alYkYkQJrKwXTFflF5wlgAGBoYZYIERkFX0BQ8WE9i0-VPbmKJ3r4XlZ2-nRxbRuimGL66gcmO4eKslZ6S0jAkAUPeokU0vSk-OW63rdzNlTc/s1600/FlowChartMaskFocus.gif&quot;/&gt;
&lt;figcaption&gt;The discontinuities of the raw gullies are faded away when combined with the combi-mask.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;One issue with the slopes remains. For the gullies, we could pretend they’re triangle waves, and calculate the slope of those pretend-triangle-waves according to the frequency and magnitude, but not so with the slopes of the input heights, of which we can assume very little.&lt;/p&gt;
  
&lt;p&gt;If we use the input slope unchanged, the initial gully octave will have a disproportionally large effect near the peaks and valleys, where the input heights are typically rounded and thus have little to no slope contribution. But in the eroded output terrain, the peaks and valleys are typically pointy, with just as steep slopes as elsewhere.&lt;/p&gt;

&lt;p&gt;I’ve experimented with a variety of solutions to this, but in the end what produced the best results was to just pretend that the input heights have a specific slope everywhere. This pretend slope can be tweaked to somewhat match the typical slope the eroded terrain ends up having.&lt;/p&gt;

&lt;p&gt;It’s a bit ironic that my early work on the erosion technique was focused on making the analytical derivatives more accurate, only to end up giving up on that entirely. But that’s just how a labyrinthine process of discovery sometimes goes.&lt;/p&gt;


&lt;h3&gt;New coat of paint&lt;/h3&gt;

&lt;p&gt;The technique has now changed sufficiently that some tweaking of the parameters is in order, to make the most of the new functionality. While at it, I also found a new spot in the heightmap to focus on. Below is the reference terrain I’ll use going forward, which also includes features covered in the remainder of this article.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGk4OSLk1h_gm8yLB6lDj0G3gogXrS7ZO7bSL7MSwMtiW0M9rA-xu8m6er-Qps9NEcftOgVnWcC6sJsTfKup1VHkNG7AWBuVUFvgOUJqANFz_gWBie9b36hKj0E7UUMWRPEqBFdV_a_vg3vnVbOE5g59I9lxIsFcdmdDSbMg-Sij4Mj3w0Qawd_XO1wuk/s1600/NewTerrain.png&quot;/&gt;
&lt;figcaption&gt;A new reference terrain that takes advantage of the new implemented features.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While not part of the erosion technique itself, it’s also fun to dress up the terrain with nice materials. I’ve been tweaking the logic inherited from the Shadertoy by Fewes, and added bumpy parts to it that evokes trees too. Furthermore, I managed to add little streaks that evoke water drainage using a technique I’ll discuss further down.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjG4AJQmogPqsIyvz8oBVdMXKh1dQsFEBspT4ZrlFmnzp7CA76CkjmIii0VYFiR8Vg0jUMNPSjD5yFShb5A9nE9ozgrVN93kgeZdNrsKcJOOIXXNYP_vahPAljaYUBFD3qWvWUrDLi6EmajU6HQc-I7S7FAJzEmWCP7O4xlO4zqVEXKLKMjvqN4rBb02w/s1600/NewTerrainTextured.png&quot;/&gt;
&lt;figcaption&gt;The new terrain with features evoking rock, dirt, grass, trees and water drainage streaks.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Pointy peaks&lt;/h3&gt;

&lt;p&gt;It turns out that normalizing the gullies make the mountains less pointy, keeping more of the rounded shape of the input height function.&lt;/p&gt;

&lt;p&gt;At first, I tried to compensate by applying a special function to the input height that made peaks more pointy, prior to passing them to the erosion function. But I later found that there is a simpler solution that can be trivially implemented in the erosion function itself: Simply scale down the gullies part of the faded gullies by some &lt;i&gt;gully weight&lt;/i&gt; factor (such as 0.5) and compensate by scaling up the erosion strength by the inverse factor (like 2.0).&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD13iIFoeGqvEGJ5JAnDg-llV-ux-lameXd0q_R0UZnD_p5EBewS9lpVkMxm4ywLp4rDITLm0SfHO9U5PQEBu7JkMeEl7aGz-U_jBFdw2Xdnq8jQ08yDYsHKLibksB0W_XpEXGsqYRWNWfVisJM6fYoAUBD55HA_rknYB6fn5136YYC3UQNDA3DUqocHY/s1600/GullyWeight.png&quot;/&gt;
&lt;figcaption&gt;Top left: Original height function with no erosion strength. Top right: Erosion applied, but the mountain peaks are not pointy. Bottom left: Gully weight reduced to zero shows only peaks and no gullies. Bottom right: With double erosion strength and half gully weight, we get erosion with nice pointy peaks.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Pointy peaks are still dependent on the fade target having a value close to 1.0, so in all the example images, the peaks at lower altitudes are less pronounced.&lt;/p&gt;

&lt;p&gt;We can look at what happens when the gully weight is reduced to zero. This preserves the overall shape of the eroded mountains, including crisp peaks and valleys, but without all the gullies.&lt;/p&gt;

&lt;p&gt;There is a subtle kind of ghosting effect of the gullies present, where ridges and creases alike are turned into all ridges where the original fade target is positive, and all creases where it’s negative. This unhelpfully counteracts half of the intended creases and ridges if very low gully weight values are used, but at larger values there are no noticeable issues.&lt;/p&gt;

&lt;p&gt;There are undoubtedly other ways to go around this, but the approach here is simple and works well enough.&lt;/p&gt;


&lt;h3&gt;Rounding of ridges and creases&lt;/h3&gt;

&lt;p&gt;The implemented technique can produce very sharp ridges and creases, but something not quite as sharp is often desired. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Real mountain peaks and ridges tend to not be razor sharp if you zoom in sufficiently.&lt;/li&gt;
  &lt;li&gt;Valleys and the bottom of gullies can get a rounded shape if sediment builds up in them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this reason I implemented &quot;edge rounding&quot; with separate control for creases and ridges. As I’ve previously touched upon, the &lt;i&gt;mask&lt;/i&gt; is based on the slope passed through a shaping function. By chaining a variable-size ease-in function onto this shaping function, rounding of the ridges and creases can be achieved. And by mixing two different rounding values – one for ridges and another for creases – based on the &lt;i&gt;fade target&lt;/i&gt;, the amount of rounding can be controlled separately for those.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-XobwX86_kBgJmU05FWCvD4gPnyaY3xplQqCO52vkIq9gD_nvQ8CMNWc_FSeAQ8fKtQSF6NRxmao4p7-bfUTQM2FMUkYbdMQSrUnwN9LFpXKara16AaWInKg67kMOYzg7s3AVw9EfhEtvbQFRTHyUfK4Yl5FMCz87YemXviVDbqXXZVUWuBI7tr-Pywk/s1600/Rounding.png&quot;/&gt;
&lt;figcaption&gt;Depiction of no rounding, rounded ridges, rounded creases, and both at the same time.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I wanted the rounding to have the same size for gullies of all octaves, so the rounding values are counter-adjusted in accordance with the erosion lacunarity value, which controls how much smaller the gullies are in each octave (typically half the size).&lt;/p&gt;

&lt;p&gt;The rounding also affects peaks and valleys stemming from the original height function (and its slopes), but the erosion function doesn’t know about the sizes of the terrain features coming from those, so an input value is provided for tweaking the rounding of those.&lt;/p&gt;


&lt;h3&gt;Water drainage&lt;/h3&gt;

&lt;p&gt;While getting the erosion increasingly crisp, the idea of a holy grail occurred to me: Could the technique model the branching gullies so crisply that it could render little branching river networks? It turns out: Kind of, with some caveats.&lt;/p&gt;

&lt;p&gt;Side note: I later learned that the branching streaks on mountain sides I had in mind constitute &lt;i&gt;dendritic drainage&lt;/i&gt;, which, apart from rivers and creeks, also include channels of snow, sediment, and debris-flow. The colored streaks are often not the water itself, but the leftover rocks and sediment which is colored differently from the surrounding soil or vegetation. Either way, it tends to look like bright lines.&lt;/p&gt;

&lt;p&gt;If we ignore the recently discussed gully weights and ridge and crease rounding, then the &lt;i&gt;fade target&lt;/i&gt; is practically already a map of the ridges and creases in the eroded terrain, once the technique has gone through all the gully octaves. Only, the last octave appears with much thicker lines than the rest, since it hasn’t been filtered through the &lt;i&gt;mask&lt;/i&gt;. This can be resolved by fading it towards a neutral value of zero / gray based on the mask, resulting in what I call a &lt;i&gt;ridge map&lt;/i&gt;.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaviQSOi_5GI_hzTqBOTSZLj2z5SOwt-nOMTnowdUR1qZud4HArL1gJrZU5xFj9PxqdPAoR7wp6fgxbTL4l6DlSeVYKm2m37HuhRA9XhYn3Bt6W47dGYdtVfmR_dK2HcuP8mN2sfsCi-GxphaBdyJeup9mC5OUbqLLvLQtmfCEaYIFmW3-bZ4kt_MNrV8/s1600/Ridgemap.png&quot;/&gt;
&lt;figcaption&gt;Left: The fade target after 2 octaves. Middle: The ridge map, based on 2 octaves. Right: The ridge map, based on 5 octaves.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Now, those recently discussed features do undermine the ridge map, so in order to avoid having to choose between one and the other, we can keep track of two copies of the &lt;i&gt;fade target&lt;/i&gt; and &lt;i&gt;mask&lt;/i&gt; in parallel, and process the ones for the ridge map without those features.&lt;/p&gt;

&lt;p&gt;Here’s a visualization of the ridge map on the terrain:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbqVIDwCFJy5Z6Vuoj7optmyecG19PwTwdP-PTmGK3pkP57n9vVdsaeXfQRvv4mw9w-gkkeMGrFHXY7aORHqMGuv_UNzkprYVMqj8WU_nTFS5uQLmBl4wm38SLmUaYsyX1mgZX9T6TlTlf9601cu2GZTi9s9WzfG4Q0MlFejJLfBKK_Ecee-9FHo1THA4/s1600/RidgemapTerrain.png&quot;/&gt;
&lt;figcaption&gt;Visualization of the ridge map on the terrain itself, with ridges in white and creases in black.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;With the ridge map, it’s easy to draw little lines at the bottom of all the gullies that resemble dendritic drainage. Here’s the image of the textured terrain again:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjG4AJQmogPqsIyvz8oBVdMXKh1dQsFEBspT4ZrlFmnzp7CA76CkjmIii0VYFiR8Vg0jUMNPSjD5yFShb5A9nE9ozgrVN93kgeZdNrsKcJOOIXXNYP_vahPAljaYUBFD3qWvWUrDLi6EmajU6HQc-I7S7FAJzEmWCP7O4xlO4zqVEXKLKMjvqN4rBb02w/s1600/NewTerrainTextured.png&quot;/&gt;
&lt;figcaption&gt;The terrain with features evoking rock, dirt, grass, trees and water drainage streaks.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It’s not a perfect solution, since the interpolated stripes we use for the gullies cannot consistently produce unbroken lines. So sometimes a gully, and the drawn water drainage at its bottom, just stops halfway down a mountainside rather than following through all the way down to the lowest reachable point. Nevertheless, it looks nice and can be sufficient for use cases that don’t require accuracy in this regard.&lt;/p&gt;


&lt;h3&gt;Future work&lt;/h3&gt;

&lt;p&gt;You can see my final iteration of the technique in my Shadertoys &lt;a href=&quot;https://www.shadertoy.com/view/wXcfWn&quot; target=&quot;_blank&quot;&gt;Advanced Terrain Erosion Filter&lt;/a&gt; and &lt;a href=&quot;https://www.shadertoy.com/view/sf23W1&quot; target=&quot;_blank&quot;&gt;Mouse-Paint Eroded Mountains&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As has hopefully been clear, the erosion technique I’ve described in this post is highly malleable. Compared to the original version by Clay John and Fewes, I’ve modified it to a point where its internal workings, capabilities, and characteristics are entirely different.&lt;/p&gt;

&lt;p&gt;While I don’t have plans to further work on this technique myself, I find it likely that others will, given how open-ended the nature of the technique is, and how ripe it is with potential.&lt;/p&gt;

&lt;p&gt;In my work with the technique, I’ve simply aimed to make the eroded terrain look good to my eyes, loosely using a bunch of reference images for inspiration.&lt;/p&gt;

&lt;p&gt;An interesting jumping off point for future work could be to try to use the technique to emulate a variety of specific eroded terrain types, each based on different references. The input parameters should allow for a wide variety of looks on their own, especially when considering most of them can be varied based on other variables. If the technique then falls short of being able to emulate certain terrain characteristics, that could point the way towards potential future improvements.&lt;/p&gt;

&lt;p&gt;I’ve released my code under the Mozilla Public License v2 in order to encourage further sharing of improvements. I’m looking forward to seeing how the technique evolves in the future!&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Based on feedback after publication I&#39;ve added some &lt;a href=&quot;#notes&quot;&gt;additional notes&lt;/a&gt; after the links section.&lt;/i&gt;&lt;/p&gt;


&lt;h3&gt;&lt;a name=&quot;links&quot;&gt;&lt;/a&gt;Links&lt;/h3&gt;

&lt;h4&gt;YouTube videos&lt;/h4&gt;

&lt;p&gt;Some things are easier to explain in motion.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;My video &lt;a href=&quot;https://www.youtube.com/watch?v=r4V21_uUK8Y&quot; target=&quot;_blank&quot;&gt;Fast &amp;amp; Gorgeous Erosion Filter Explained&lt;/a&gt; has more elaborate visualizations than this blog post, and more details on the initial process I went through.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gsJHzBTPG0Y&quot; target=&quot;_blank&quot;&gt;Better Mountain Generators That Aren’t Perlin Noise or Erosion&lt;/a&gt; on Josh’s Channel is a highly polished and well explained video on two other non-simulated erosion techniques. I reference this video in my own video.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Shadertoys&lt;/h4&gt;

&lt;p&gt;You can run and see these visuals directly in your browser, and easily see and modify the source shader code too.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/MtGcWh&quot; target=&quot;_blank&quot;&gt;Eroded Terrain Noise&lt;/a&gt; by Clay John (&lt;a href=&quot;https://bsky.app/profile/clayjohn.bsky.social&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt;). The original version of the technique.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/7ljcRW&quot; target=&quot;_blank&quot;&gt;Terrain Erosion Noise&lt;/a&gt; by Felix Westin (Fewes) (&lt;a href=&quot;https://fewes.se/&quot; target=&quot;_blank&quot;&gt;website&lt;/a&gt;). Slightly tweaked erosion effect, and presented in a vastly more polished way.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/33cXW8&quot; target=&quot;_blank&quot;&gt;Clean Terrain Erosion Filter&lt;/a&gt; by me. My earlier rewrite of Clay John and Fewes’ technique (based on the frequency approach), with more intuitive parameters.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/wXcfWn&quot; target=&quot;_blank&quot;&gt;Advanced Terrain Erosion Filter&lt;/a&gt; by me. My final iteration of the technique, with animated parameters.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/sf23W1&quot; target=&quot;_blank&quot;&gt;Mouse-Paint Eroded Mountains&lt;/a&gt; by me. My final iteration of the technique, with interactive mouse painting of the terrain.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/t3dyWl&quot; target=&quot;_blank&quot;&gt;Phacelle Noise Animation&lt;/a&gt; by me. A demonstration of the Phacelle Noise I extracted into a self-contained function (&lt;a href=&quot;https://blog.runevision.com/2026/01/phacelle-cheap-directional-noise.html&quot; target=&quot;_blank&quot;&gt;blog post here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;Erosion filters in the wild&lt;/h4&gt;

&lt;p&gt;Let me know if you use the erosion filter technique in your project and have public images or videos to show for it!&lt;/p&gt;

&lt;p&gt;I&#39;m very happy so many people have found the technique useful enough to make their own implementations in a variety of shapes and forms. Some of the ones below are faithful implementations, while others are partial, derived, or based on an earlier version of the technique.&lt;/p&gt;

&lt;p&gt;Implementations in tools and engines&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Implementation in Unity Burst &lt;a href=&quot;https://www.reddit.com/r/Unity3D/comments/1salvh2/i_ported_an_advanced_erosion_terrain_shader_to/&quot; target=&quot;_blank&quot;&gt;posted on Reddit&lt;/a&gt; and &lt;a href=&quot;https://github.com/lpmitchell/AdvancedTerrainErosion&quot; target=&quot;_blank&quot;&gt;released on Github&lt;/a&gt; by Luke Mitchell.&lt;/li&gt;
  &lt;li&gt;Implementation in Unity Shadergraph &lt;a href=&quot;https://bsky.app/profile/jens06409515.bsky.social/post/3mikfzbi2gs24&quot; target=&quot;_blank&quot;&gt;posted on Bluesky&lt;/a&gt; and &lt;a href=&quot;https://github.com/Jens-Maier/erosionFilter&quot; target=&quot;_blank&quot;&gt;released on Github&lt;/a&gt; by Jens Maier.&lt;/li&gt;
  &lt;li&gt;Implementation in Unreal&#39;s landmass plugin &lt;a href=&quot;https://x.com/MichaelKinsey3D/status/2043407307984523608&quot; target=&quot;_blank&quot;&gt;posted on Twitter&lt;/a&gt; by Michael Kinsey.&lt;/li&gt;
  &lt;li&gt;Implementation in Godot &lt;a href=&quot;https://forum.godotengine.org/t/fast-and-gorgeous-erosion-filter/136436&quot; target=&quot;_blank&quot;&gt;posted (with source) on Godot forum&lt;/a&gt; by Henry.&lt;/li&gt;
  &lt;li&gt;Implementation in Blender geometry nodes &lt;a href=&quot;https://kollapse3d.gumroad.com/l/nhrvg&quot; target=&quot;_blank&quot;&gt;Quick Erosion Filter free Gumroad download&lt;/a&gt; by Jérémy Derlande (Kollapse3D).&lt;/li&gt;
  &lt;li&gt;Implementation in Houdini &lt;a href=&quot;https://dailyhip.wordpress.com/2025/07/23/erosion-filter/&quot; target=&quot;_blank&quot;&gt;blog post with source files&lt;/a&gt; by eetu.&lt;/li&gt;
  &lt;li&gt;Implementation in Leveller heightmap modeler tool &lt;a href=&quot;https://www.daylongraphics.com/support/lev44_upgrade.php&quot; target=&quot;_blank&quot;&gt;included in version 4.4 (with source)&lt;/a&gt; by Ray Gardener.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementations in games and private experiments&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Implementation in Hytale&#39;s Worldgen v2 &lt;a href=&quot;https://bsky.app/profile/verday.bsky.social/post/3mijpnoirpc2a&quot; target=&quot;_blank&quot;&gt;posted on Bluesky&lt;/a&gt; and &lt;a href=&quot;https://github.com/ItsVerday/Hytale_Worldgen_Additions&quot; target=&quot;_blank&quot;&gt;released on Github&lt;/a&gt; by Verday.&lt;/li&gt;
  &lt;li&gt;Erosion on a sphere &lt;a href=&quot;https://mastodon.gamedev.place/@metarapi/116205272100793897&quot; target=&quot;_blank&quot;&gt;posted on Mastodon&lt;/a&gt; by metarapi.&lt;/li&gt;
  &lt;li&gt;Terraform Blending Test &lt;a href=&quot;https://www.youtube.com/watch?v=PzJi5l3ujDs&quot; target=&quot;_blank&quot;&gt;YouTube video&lt;/a&gt; by HerrLynnsTube.&lt;/li&gt;
  &lt;li&gt;|peak| implementation in Desmos graphing calculator &lt;a href=&quot;https://www.desmos.com/3d/trzh59qzgq&quot; target=&quot;_blank&quot;&gt;graph&lt;/a&gt; by lemon (and a simpler version &lt;a href=&quot;https://www.desmos.com/3d/wkhxovnz3u&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;Shadertoy video exporters&lt;/h4&gt;

&lt;p&gt;This is not entirely related to erosion techniques, but here are the tools I used to render high quality Shadertoys footage for the video. Okay, I may also be using the links section here to tell a side story about my video production woes.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/KoltesDigital/shadertoy-exporter&quot; target=&quot;_blank&quot;&gt;Shadertoy Exporter (original)&lt;/a&gt; by Jonathan Giroux (Koltes). This tool worked great, until it broke when the Shadertoy website introduced Cloudflare human verification in early October 2025.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/larathedev/shadertoy-exporter&quot; target=&quot;_blank&quot;&gt;Shadertoy Exporter (forked)&lt;/a&gt; by Lara Davidova (larathedev). This fork was made to work with the Cloudflare human verification, and was briefly functional, until the Shadertoy website entirely disallowed being displayed in an iframe later in October 2025.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/NodotProject/shadertoy-exporter&quot; target=&quot;_blank&quot;&gt;Shadertoy Exporter (Godot version)&lt;/a&gt; by krazyjakee (NodotProject). This rewrite based on Godot is partially functional at the time of writing. It’s Windows-only, and (for me) has the following bugs: Does not convert the rendered frames into videos, has to be restarted after each render, and frequently does not register text input until the window focus is switched away and back. I begrudgingly used this for later footage in the video, manually running &lt;a href=&quot;https://www.ffmpeg.org/&quot; target=&quot;_blank&quot;&gt;ffmpeg&lt;/a&gt; on the frames.&lt;/li&gt;
  &lt;li&gt;I’m aware there are also frame exporter browser plugins &lt;a href=&quot;https://chromewebstore.google.com/detail/shadertoy-frame-exporter/bkompdalfpocndfcbcdajnfkjklbecjn&quot; target=&quot;_blank&quot;&gt;for Firefox&lt;/a&gt; and &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/shadertoy-frame-exporter/&quot; target=&quot;_blank&quot;&gt;for Chrome&lt;/a&gt;, but these have even worse usability for me. I have my browser set to display a save dialog when downloading a file, so when I try to render a Shadertoy for 200 frames, it opens 200 save dialogs.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;&lt;a name=&quot;notes&quot;&gt;&lt;/a&gt;Additional notes&lt;/h3&gt;

&lt;h4&gt;On using the second derivatives (curvature) for the fade target&lt;/h4&gt;

&lt;p&gt;Several people have suggested using the second derivatives (curvature) instead of the altitude for the fade target.&lt;/p&gt;

&lt;p&gt;Using altitude is indeed not robust in the general case, since e.g. some valley could be higher up than some mountain peak. I&#39;m not sure there&#39;s a perfect solution, and I kind of let it be up to the user to decide what to base the input fade target parameter on. I just base it on altitude in all my demonstrations.&lt;/p&gt;

&lt;p&gt;I did think about using the second derivatives (curvature), but then every function involved in producing the input heights has to calculate and return those second order derivatives, or alternatively it has to be done numerically which is either slow (via multi-sampling) or rather inaccurate (via shader derivatives).&lt;/p&gt;

&lt;p&gt;On top of that, curvature does not produce a value that&#39;s between -1 and 1 as the fade target needs, so you&#39;d have to combine it with other things (like the first derivatives) to wrangle it into a useful range. That&#39;s absolutely possible, but hand-tweaking the particulars may still be needed.&lt;/p&gt;

&lt;p&gt;So while it&#39;s something I considered, I don&#39;t really have a good solution. I&#39;m curious if others will find a better way to handle this.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/6814106630667320914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/6814106630667320914' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6814106630667320914'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6814106630667320914'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2026/03/fast-and-gorgeous-erosion-filter.html' title='Fast and Gorgeous Erosion Filter'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeWotRn8KxGEbVTCIl1-znAH0ZDNSwFUf7hkp9GrJ4u5jfK8zS8-sA1SHtWyBaHSLx3Lskzcr0z_XzW9y4847lBQo8e_1TIHa49EQXT1XFbv0lui_ZKX-hNlpDChD3Wq3Rz9n4HcB3MwEosYU5Xi_IOTzADWDd18u4joJcgUOF94ZN-HNhLdZ_8tvnBpM/s72-c/ErodedTerrain.png" height="72" width="72"/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-4209808391381786457</id><published>2026-01-22T12:05:00.008+01:00</published><updated>2026-02-25T17:38:42.460+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>Phacelle - Cheap Directional Noise</title><content type='html'>&lt;p&gt;While working on a novel erosion algorithm last fall (which I&#39;ll release at a later time), I developed a directional noise function in the process, which combines various traits of other ones. Since I haven&#39;t come across one quite like this, I&#39;ll share my findings here. I call it Phacelle Noise, a portmanteau of phase and cell.&lt;/p&gt;

&lt;p&gt;Update: After discussing with two of the authors of Phasor Noise, I&#39;ve added a section at the end about the ways in which Phacelle Noise differs from Phasor Noise.&lt;/p&gt;

&lt;figure&gt;
&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20260122_PhacelleNoise.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;
&lt;figcaption&gt;Simple Phacelle Noise animation recorded from &lt;a href=&quot;https://www.shadertoy.com/view/t3dyWl&quot;&gt;this Shadertoy&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;img style=&quot;display: none&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfouoXIOlGGBPHQFJvNitpLd9c_HDLESPNzPOSXVJqN6R1zK-DLSZL3El8Mc70MUclpgdHL5F4fByfH3CfQazxoqnDiPMwfeDDPp0qxut8iSpeiXHj2mlKoRO3_RVxX-n2DInxmvPHcYiBqLyeDKjDVm44TrbSBBDbirDM2hlT5S8VDOYkbgVin8WCiaw/s1600/PhasorNoiseProfile.png&quot;/&gt;

&lt;p&gt;I ended up making two versions, but let&#39;s start with &lt;i&gt;Simple Phacelle Noise&lt;/i&gt;. For each point, it takes a 2D vector as input, which indicates the direction that stripes should be aligned with at that point. As output it produces another 2D vector from which a phase (or angle) can be reconstructed. Based on this phase, a wide variety of stripe shape profiles can be achieved, for example applying a square wave, a triangle wave, a sawtooth wave, or similar.&lt;/p&gt;

&lt;p&gt;It&#39;s also possible to use the X or Y component of the output vector directly. These both produce stripes with a sine wave shape profile, a quarter cycle apart (so essentially a cosine and sine).&lt;/p&gt;

&lt;p&gt;Even for use cases satisfied by sine wave based stripes, interpolating both cosine and sine waves simultaneously has a significant benefit. See, interpolating multiple kernels of sine waves normally produces a result where the amplitude of the output varies greatly depending on how in phase or out of phase the kernels are. However, when both the interpolated cosine and sine are available, the resulting output vector can be normalized, which ensures both the output sine and cosine waves have constant amplitudes of one.&lt;/p&gt;

&lt;p&gt;The other version, &lt;i&gt;Sampled Phacelle Noise&lt;/i&gt;, is very similar to Simple Phacelle Noise, except that instead of taking the input direction as an input parameter, it samples the input pattern once per cell, which amounts to 16 times per pixel. Before I go more into that, let&#39;s look at some pictures.&lt;/p&gt;

&lt;h3&gt;Visual comparison with Phasor Noise&lt;/h3&gt;

&lt;p&gt;With respect to use cases and functionality, the closest other noise function I know of is Phasor Noise (&lt;a href=&quot;http://thibaulttricard.fr/project_page/phasor_noise/phasor.html&quot; target=&quot;_blank&quot;&gt;website&lt;/a&gt;, &lt;a href=&quot;https://inria.hal.science/hal-02118508&quot; target=&quot;_blank&quot;&gt;paper&lt;/a&gt;), itself a reformulation of Gabor Noise. But Phacelle Noise works in quite a different way, which appears to be much simpler and computationally cheaper, and produces a bit different results.&lt;/p&gt;

&lt;p&gt;Here&#39;s a comparison of Phasor Noise (top) with Simple Phacelle Noise (middle) and Sampled Phacelle Noise (bottom):&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfouoXIOlGGBPHQFJvNitpLd9c_HDLESPNzPOSXVJqN6R1zK-DLSZL3El8Mc70MUclpgdHL5F4fByfH3CfQazxoqnDiPMwfeDDPp0qxut8iSpeiXHj2mlKoRO3_RVxX-n2DInxmvPHcYiBqLyeDKjDVm44TrbSBBDbirDM2hlT5S8VDOYkbgVin8WCiaw/s1600/PhasorNoiseProfile.png&quot;/&gt;
&lt;figcaption&gt;Phasor Noise applied to an example pattern by the Phasor Noise authors. From &lt;a href=&quot;https://www.shadertoy.com/view/wlsXWf&quot; target=&quot;_blank&quot;&gt;this Shadertoy&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAKR1Lg7s6IZCoDUNNBM9MbC7zD1wq3WguZk-PJXvqAx2XxWSlvzmlG4vpAS_Tv30rTlWQRv2bQn-tmaVfqcL9lNB11ksaNFh3dLCxDTTQBhdaWGnd1Kt5Vn2Y5BiDcLXxiXsVLVmLcMRmqLwvZp7EGCqObZGQ_NuN1iu_W6fSeaeuGNL-xDlXB7LvBQs/s1600/PhacelleNoiseProfile.png&quot;/&gt;
&lt;figcaption&gt;Simple Phacelle Noise applied to an example pattern by the Phasor Noise authors. From &lt;a href=&quot;https://www.shadertoy.com/view/t3KczR&quot; target=&quot;_blank&quot;&gt;this Shadertoy&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg49sMeYN4E0b-7JJruPZ0mJBKUPZKJbQl6jG1E2YRTuMTpE5oPWlnCLl7BkEmIHeQRRyDgx82E08ysDlwlpV6tLDAjpk1hiicU24BsJN_Ro2bUMFV4YGsw8Wqsvxtt_f8CBMzHRitzb4x3d5_HRiNJZ25rDPDqnqriBMEQu-SW_5d0QAQuRvqEY8_IsMw/s1600/MultiPhacelleNoiseProfile.png&quot;/&gt;
&lt;figcaption&gt;Sampled Phacelle Noise applied to an example pattern by the Phasor Noise authors. From &lt;a href=&quot;https://www.shadertoy.com/view/w3ycRw&quot; target=&quot;_blank&quot;&gt;this Shadertoy&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To me eyes, these images above look remarkably similar, but there are subtle differences if you look closely. Specifically around areas in the pattern where there are discontinuities in the input direction.&lt;/p&gt;

&lt;p&gt;To make the respective handling of discontinuities super obvious, let&#39;s use a different input pattern that alternates between horizontal and vertical directions in a checker pattern:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp8zoTltf8I1TYWn-mD2s5FlMdmYlBe_JQdlm2lhy7QFNg8IdM0aZzSwPeSP0RqdiHcuLdKFqUiaSMeWUmcmMeoWFmwGZTDuCG-PQalN7PEGbFhSQUI2DnSASqM1WvYkeM5deKQeyDsoj4IZSGDRfDCzDSJfuFOtRA8p68aEfRepe3PZZjQ6Cg997UZPY/s1600/PhasorChecker.png&quot;/&gt;
&lt;figcaption&gt;Phasor Noise applied to a checker pattern of vertical and horizontal directions.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhARDWQEOYxEw8dek4kaGmDjjKZ4TBUnhhaPIySYztErOiBd7T67kJhxfaV3iPJyycVBWs288D9NtiAgZXOwOMg0QzJSTqFaI_6r_BrD6UqV74AtPuzckqYQEpK_DOupqtXPhkItLeHFGwdYkEfW7nUhLnjeQxZoAaLm_G3eQehNT3_JijEEbPp3vWSQjI/s1600/PhacelleChecker.png&quot;/&gt;
&lt;figcaption&gt;Simple Phacelle Noise applied to a checker pattern of vertical and horizontal directions.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHIs0S1XTh4iGNtjHdbPDI5dRMmZ3EvYcOBIMX0ZtWHH8i4rssMeDlGhD0TJcUSH5UhADGsxjjdX-Oa-rbzhDbKFjGbxXgViFQw6R6T99eWVQe7Pbzj81frK_r1zfCsUg2gzj5OQDoHWF8LT-OUaSyCLM7Vo2VWPyol_4lwX3-meeT0B7kJFk0GRDt0Yg/s1600/MultiPhacelleChecker.png&quot;/&gt;
&lt;figcaption&gt;Sampled Phacelle Noise applied to a checker pattern of vertical and horizontal directions.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Here you can see that Simple Phacelle Noise has abrupt discontinuities in its generated stripe pattern, while Phasor Noise and Sampled Phacelle Noise do not. Ultimately it&#39;s a matter of personal preference, or use case, which one is preferable. For raw stripey patterns, the discontinuities in Simple Phacelle Noise are probably not desirable. For the erosion use case I worked on, it works well, since the stripe (gully) pattern is masked out in those areas of discontinuities anyway.&lt;/p&gt;

&lt;p&gt;The visual difference between Phasor Noise and Sampled Phacelle Noise is harder to put the finger on. It seems the latter has a bit higher tendency to produce broken lines rather than merged ones?&lt;/p&gt;


&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;Performance-wise, both versions of Phacelle Noise are much simpler and cheaper than Phasor Noise. In Phasor Noise the innermost loop code (in &lt;a href=&quot;https://www.shadertoy.com/view/t3KczR&quot; target=&quot;_blank&quot;&gt;their provided reference code&lt;/a&gt;) runs 5 * 5 * 16 = 400 times per pixel, and the input pattern is sampled in that inner loop, so 400 times per pixel as well. The primary author of the Phasor Noise paper Thibault Tricard pointed me to a &lt;a href=&quot;https://www.shadertoy.com/view/NsdGz2&quot; target=&quot;_blank&quot;&gt;corrected implementation&lt;/a&gt; by his colleague Xavier Chermain, which reduces the innermost loop count to 3 x 3 x 16 = 144 times per pixel.&lt;/p&gt;

&lt;p&gt;On the other hand, the innermost loop code in Phacelle Noise runs 4 * 4 = 16 times per pixel. The input pattern is sampled only once per pixel for Simple Phacelle Noise (where it&#39;s simply passed as an iput parameter) and 16 times per pixel (that is, one sample per loop) for Sampled Phacelle Noise.&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Noise&lt;/th&gt;
    &lt;th&gt;Loops per pixel&lt;/th&gt;
    &lt;th&gt;Samples per pixel&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;Phasor (&lt;a href=&quot;https://www.shadertoy.com/view/wlsXWf&quot; target=&quot;_blank&quot;&gt;Shadertoy by Thibault Tricard&lt;/a&gt;)&lt;/th&gt;
    &lt;td&gt;&lt;b&gt;400&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(5 x 5 x 16)&lt;/span&gt;&lt;/td&gt;
    &lt;td&gt;&lt;b&gt;400&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(one per loop)&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;Phasor (&lt;a href=&quot;https://www.shadertoy.com/view/NsdGz2&quot; target=&quot;_blank&quot;&gt;Shadertoy by Xavier Chermain&lt;/a&gt;)&lt;/th&gt;
    &lt;td&gt;&lt;b&gt;144&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(3 x 3 x 16)&lt;/span&gt;&lt;/td&gt;
    &lt;td&gt;&lt;b&gt;144&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(one per loop)&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;Simple Phacelle (&lt;a href=&quot;https://www.shadertoy.com/view/t3KczR&quot; target=&quot;_blank&quot;&gt;Shadertoy&lt;/a&gt;)&lt;/th&gt;
    &lt;td&gt;&lt;b&gt;16&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(4 x 4)&lt;/span&gt;&lt;/td&gt;
    &lt;td&gt;&lt;b&gt;1&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(input parameter)&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;Sampled Phacelle (&lt;a href=&quot;https://www.shadertoy.com/view/w3ycRw&quot; target=&quot;_blank&quot;&gt;Shadertoy&lt;/a&gt;)&lt;/th&gt;
    &lt;td&gt;&lt;b&gt;16&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(4 x 4)&lt;/span&gt;&lt;/td&gt;
    &lt;td&gt;&lt;b&gt;16&lt;/b&gt; &lt;span class=&quot;avoidwrap&quot;&gt;(one per loop)&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt; 

&lt;p&gt;In practise I can also see that both Phacelle Shadertoys run many times faster than the Phasor Shadertoy (when switching them all to use a sample pattern which is not itself computationally heavy). I haven&#39;t done a more in-depth performance analysis since I don&#39;t have much experience profiling shaders, especially Shadertoys.&lt;/p&gt;

&lt;p&gt;In Simple Phacelle Noise, the fact that the input pattern is sampled only once per pixel means that it can be passed to the Phacelle Noise function as a simple input parameter. With Phasor Noise (and to a lesser extent Sampled Phacelle Noise), storing the calculated input pattern in a buffer to avoid excessive recalculations is more or less a necessity (if it&#39;s not trivial), while no such buffer is needed with Simple Phacelle Noise. This also makes it easier to make the Simple Phacelle Noise implementation fully self-contained and reusable, since it does not need access to evaluate another function or buffer.&lt;/p&gt;


&lt;h3&gt;Function lineage&lt;/h3&gt;

&lt;p&gt;I didn&#39;t actually know of Phasor Noise when I implemented Phacelle Noise (the simple variant), and I felt very clever for coming up with the idea that by interpolating kernels of both cosine and sine waves simultaneously, the interpolated result can be interpreted as a vector that can be normalized, and from which a phase can be reconstructed.&lt;/p&gt;

&lt;p&gt;Phacelle Noise is derived from a function called &lt;var&gt;erosion&lt;/var&gt; in this 2018 &lt;a href=&quot;https://www.shadertoy.com/view/MtGcWh&quot; target=&quot;_blank&quot;&gt;Eroded Terrain Noise Shadertoy&lt;/a&gt; by user &lt;i&gt;clayjohn&lt;/i&gt;. This function interpolates kernels of both cosine and sine waves, but the sine part is multiplied with a vector largely orthogonal to the stripe direction (but slightly different per kernel). Calculating both cosine and sine here has nothing to do with normalization or phase, but is rather done to get both a stripe pattern and its analytical derivative. The stripe pattern is used to carve gullies in a terrain based on the slope of the terrain, and the derivatives (the slope of the gullies) are used to further produce more gullies, branching out in a fractal manner.&lt;/p&gt;

&lt;p&gt;In 2023, user &lt;i&gt;Fewes&lt;/i&gt; made a refined presentation of clayjohn&#39;s erosion technique in this &lt;a href=&quot;https://www.shadertoy.com/view/7ljcRW&quot; target=&quot;_blank&quot;&gt;Terrain Erosion Noise Shadertoy&lt;/a&gt;. While the core technique was kept mostly the same, Fewes did simplify the vector multiplied onto the sine component of each kernel, making it the same for all the kernels.&lt;/p&gt;

&lt;p&gt;My own erosion work in 2025 was based on Fewes&#39; version as a starting point. The sine component being premultiplied with a vector makes normalization and phase extraction less straightforward. It&#39;s nevertheless what I did initially, since my use case was erosion too, and I needed the derivatives. However, I eventually realized that there&#39;s no need for the direction vector to be premultiplied onto each kernel, as multiplying it onto the interpolated result is fully equivalent. This makes it easy to get the best of both worlds, both clean interpolated cosine and sine waves, and a simple way to get the derivatives too.&lt;/p&gt;

&lt;p&gt;Digging further back, clayjohn&#39;s erosion function was derived from a function called &lt;var&gt;gavoronoi4&lt;/var&gt; is this &lt;a href=&quot;https://www.shadertoy.com/view/llsGWl&quot; target=&quot;_blank&quot;&gt;Gavoronoise Shadertoy&lt;/a&gt; by user &lt;i&gt;guil&lt;/i&gt;. This function produces stripes by interpolating kernels of cosine only, and the stripe direction is global rather than variable per pixel.&lt;/p&gt;

&lt;p&gt;In turn, Gavoronoise Noise was inspired by Gabor and Voronoi Noise. Gabor Noise because it interpolates stripes produced by sine waves, and Voronoi Noise – specifically this &lt;a href=&quot;https://www.shadertoy.com/view/Xd23Dh&quot; target=&quot;_blank&quot;&gt;Voronoi Shadertoy&lt;/a&gt; by user &lt;i&gt;iq&lt;/i&gt; is quoted as a source – because it interpolates a &quot;moving window&quot; of cells, such that an infinite pattern of cells can be achieved while sampling only a finite number of cells at a time (typically 3 x 3, 4 x 4, or 5 x 5).&lt;/p&gt;


&lt;h3&gt;Readability&lt;/h3&gt;

&lt;p&gt;Regardless of whether Phacelle Noise is actually anything new (which will be discussed in the section following this one), I bet that my implementation is easier to read and understand.&lt;/p&gt;

&lt;p&gt;See, most Shadertoys read to me as if the authors thought they were in an obfuscation contest. Variables are commonly one or two letters long, and it&#39;s your lucky day if there&#39;s even just a word or two of comments. This makes a lot of this code opaque to me. It&#39;s cumbersome having to reverse engineer what each variable means, and I&#39;ll have forgotten what the first one means once I&#39;m done figuring out the third one.&lt;/p&gt;

&lt;p&gt;It&#39;s here that I&#39;ll admit I don&#39;t actually understand how Phasor Noise works, despite having stared at the code for it for some time. I came away with certain conclusions (like the number of iterations and input pattern samples), but far from a full picture. I don&#39;t know what the innermost loop actually does.&lt;/p&gt;

&lt;p&gt;Some of this culture of compact, non-verbose variable names might inherit from traditions in mathematical notation, where every variable is a single letter or symbol only, which similarly makes mathematical formulas (a frequent occurance in papers about graphics) often appear opaque to me. It&#39;s here that I&#39;ll admit I also read the &lt;a href=&quot;https://inria.hal.science/hal-02118508&quot; target=&quot;_blank&quot;&gt;paper on Phasor Noise&lt;/a&gt;, but that didn&#39;t help me understand it either. I mean, I understand the phase part perfectly, but not the part about how exactly kernels are computed and interpolated, and what those 400 inner loop iterations are needed for.&lt;/p&gt;

&lt;p&gt;Mathematical notation is tricky to reform away from single-letter variables (even if there was willingness), since sequences of letters right after each other are interpreted as variables being multiplied. Except when they&#39;re not, as in &lt;var&gt;sin&lt;/var&gt;, &lt;var&gt;cos&lt;/var&gt;, and a host of other function names that are somehow allowed to be multi-letter by convention.&lt;/p&gt;

&lt;p&gt;But the way I see it, with code there&#39;s no excuse not to make it as readable as possible without the reader having to resort to guesswork and reverse engineering.&lt;/p&gt;

&lt;p&gt;So in my own Shadertoys I try to use as descriptive variable names I can, and I strive to add plenty of comments. And in that way, I hope my implementation of Phacelle Noise will be helpful to some people out there.&lt;/p&gt;


&lt;h3&gt;How Phacelle Noise differs from Phasor Noise&lt;/h3&gt;

&lt;p&gt;Is Phacelle Noise different from Phasor Noise?&lt;/p&gt;

&lt;p&gt;Right after posting the first version of this blog post, I pinged Fabrice Neyret – prolific Shadertoy user and a co-author on the Phasor paper (and many others) – in the Shadertoy Discord server, and said I&#39;d love to hear his input if he got a chance to take a look. Fabrice in turn pinged the first author of the Phasor paper, Thibault Tricard, to bring him into the conversation too.&lt;/p&gt;

&lt;p&gt;I started the conversation this way:&lt;/p&gt;

&lt;blockquote&gt;
  
&lt;p&gt;There&#39;s two things I&#39;m kind of wondering. One is how Phasor noise works, since I can&#39;t quite figure it out based on the Shadertoy code or the paper. There is an inner loop that does something with impulses, but I don&#39;t understand what it is?&lt;/p&gt;

&lt;p&gt;The other is – I&#39;m not in the academic world, nor super aware of all the various noise types that&#39;s been shared on Shadertoy over the years. And I&#39;m wondering whether the Phacelle noise I just shared is functionally identical to some existing approach out there, that I just didn&#39;t happen to come across.&lt;/p&gt;

&lt;/blockquote&gt;

&lt;p&gt;A rather long discussion ensued, where I gradually understood Phasor Noise better, and formed a clearer view about to which degree Phacelle Noise is new.&lt;/p&gt;

&lt;p&gt;In the following, I&#39;ll refer to the &quot;cells&quot; in Phacelle Noise as &quot;splats&quot;, since this seems to be one established terminology. (&quot;Kernel&quot; is another term for the same thing, but it can mean other things in graphics too.) &quot;Cells&quot; instead refers to the square grid cells that the &quot;splats&quot; are randomly placed inside.&lt;/p&gt;

&lt;p&gt;As to my question about impulses, I understood from the conversation that &quot;impulses&quot; simply means the number of splats per square cell, since Phasor Noise places more than one of them per cell.&lt;/p&gt;


&lt;h4&gt;Difference in how kernel orientations are handled (for Simple Phacelle Noise)&lt;/h4&gt;

&lt;p&gt;Some parts of the discussion was specifically about Simple Phacelle Noise, since it&#39;s more different from Phasor Noise than Sampled Phacelle Noise is.&lt;/p&gt;

&lt;p&gt;In the Phasor paper, the description includes &quot;kernels of different frequencies, orientation, bandwidth and amplitudes may be summed&quot;. But in the &#39;one sample per pixel&#39; approach used in Simple Phacelle Noise, the different kernels do not have different orientations. For a given point being evaluated, all kernels have identical orientation, which is the orientation of the input pattern at the currently evaluated point. Rather, the different stripe directions over space come from all the kernel orientations changing &lt;i&gt;in unison&lt;/i&gt; as a function of the input direction at the currently evaluated point.&lt;/p&gt;

&lt;p&gt;Thibault noted that it is indeed different from what the paper describes, although figure 20 in the Phasor paper uses this technique. He said it&#39;s a trick that was given to him by his PhD advisor at the time, and mused that it might be what is sometimes called &quot;ghost knowledge&quot;: Knowledge that is present somewhere in the epistemic community, but is not really written down anywhere. Later he went on to try to find out which paper it was first described in, but it is in any case not described in the Phasor paper, or consistent with how that paper describes Phasor Noise.&lt;/p&gt;

&lt;p&gt;I somewhat disagree with calling it a mere trick, as it makes the whole thing work in a different way, which is in opposition to what the paper describes. It has completely different properties in terms of qualities of the output, and which use cases it&#39;s suitable for.&lt;/p&gt;

&lt;p&gt;Fabrice said that the difference in output is only notable &quot;in the case where the vector field violates the requirement of changing slower than the sine wavelength&quot; and that &quot;In theory you should pre-filter it (which is not easy). After a while there would be little difference between the two approaches.&quot; But this &quot;requirement&quot; makes a lot of assumptions, and I reject it being universally relevant. I pointed out that in use for erosion, it&#39;s actually advantageous that the output changes abruptly around e.g. a mountain peak rather than always changing smoothly. Hence the qualities of the output are just &lt;i&gt;different&lt;/i&gt;. Whether one is better than the other depends on the use case.&lt;/p&gt;

&lt;p&gt;Besides the visual difference in output, it also makes a big difference in which setups are viable. Consider a use case where you need to chain many directional noise invocation after each other, each new one dependent on the output from the last. With an implementation that samples the input pattern per splat, this would require a separate buffer for each invocation, or else each &quot;layer&quot; would contribute to a combinatorial explosion of samples that would be completely infeasible to run.&lt;/p&gt;

&lt;p&gt;Whereas with Simple Phacelle noise it&#39;s trivial. No buffers are needed, and no combinatorial explosion happens. The computational complexity scales simply linearly with the number of invocations.&lt;/p&gt;

&lt;p&gt;In the end I suggested that it may simultaneously be a &quot;trick&quot; to an existing technique in one context, and in another context be the primary technque in its own right, and Thibault said that he was fine with that.&lt;/p&gt;


&lt;h4&gt;Speed optimizations&lt;/h4&gt;

&lt;p&gt;Phacelle Noise is (in its current implementations) hardcoded to sample 4 x 4 splats, randomly placed inside 4 x 4 square cells. It makes the most of those samples, producing results that often look similar to Phasor noise implementations that use an order of magnitude more samples. Furthermore, the fact that Phacelle uses only one splat per square cell differs from the Phasor Noise implementations I&#39;ve seen, which have invariably used multiple splats per cell. Using only one splat per cell produces a distribution that&#39;s more evenly spread out (on average).&lt;/p&gt;

&lt;p&gt;In practise, when I tried to reduce the number of samples in the Phasor implementations I saw, the results got worse than Phacelle Noise long before the number of samples got near to 16.&lt;/p&gt;

&lt;p&gt;Apart from that, in the Phacelle Noise implementations I&#39;ve put some effort into moving as many calculations as possible outside of the loops for performance reasons, while the Phasor implementations I saw repeat a lot of identical calculations for each sample.&lt;/p&gt;


&lt;h4&gt;Avoidance of artifacts caused by discontinuities in the splat weight functions&lt;/h4&gt;

&lt;p&gt;Phasor noise uses Gaussian functions for weighting its splats. And those functions never reach zero at any distance from the splat center. This works well for implementations that always sample all splats. But for implementations that only sample the nearest splats (for example because there are infinite splats), it creates artifacts because of discontinuities in the &lt;i&gt;effective&lt;/i&gt; weight functions.&lt;/p&gt;

&lt;p&gt;In the implementations where splats are divided up into square grid cells, the artefacts appear along the grid lines. It may not be visible in most presentations, but I&#39;ve seen these artefacts clearly in terrain height use cases I&#39;ve worked on.&lt;/p&gt;

&lt;p&gt;This is why I subtract a value from the &lt;var&gt;exp&lt;/var&gt; weight function (&lt;a href=&quot;https://www.desmos.com/calculator/jb2w4dpeo0&quot; target=&quot;_blank&quot;&gt;Desmos demonstration here&lt;/a&gt;), chosen such that it ensures the weight function gradually goes down to zero, and reaches it without discontinuities at the exact minimum distance from the evaluated point where splats may stop being evaluated. Fabrice said this is a common fix to apply to weight functions. Nevertheless it was not described in the Phasor paper or present in Phasor implementations I&#39;ve been pointed towards, so it&#39;s a practial implementation difference between Phasor (as described) and Phacelle.&lt;/p&gt;


&lt;h4&gt;API surface and ease of use&lt;/h4&gt;

&lt;p&gt;I must say that although everyone involved did their best to be helpful and constructive, there was also a lot of friction in the conversation in general. Occasionally I would see comments dropped outside of the Discord conversation on my Shadertoys &lt;a href=&quot;https://www.shadertoy.com/view/tXGcWR&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://www.shadertoy.com/view/t3KczR&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, and they may give a bit of an impression of what I mean.&lt;/p&gt;

&lt;p&gt;I felt that we were often talking past each other. In the Discord conversation, I tried to put that into the following words:&lt;/p&gt;

&lt;blockquote&gt;

&lt;p&gt;It seems you approach the concepts we&#39;re discussing mostly in terms of abstract classification. My own interest however is more rooted in concrete functionality and user experience, and as such is centered around things like ease of use, applicable use cases, API surface design, proper documentation, etc.&lt;/p&gt;

&lt;p&gt;And in a lot of Shadertoy implementations I&#39;ve seen of Phasor noise, the ease of use has been very poor for me. I didn&#39;t understand the code due to few or no comments, and there was often not even a clear seperation between code that&#39;s noise implementation and code that relates to presentation. This makes it very hard for someone who&#39;s not intimately familiar with the technique to just copy the noise function into another Shadertoy and use it there.&lt;/p&gt;

&lt;p&gt;Case in point, I still haven&#39;t seen any Phasor noise function that takes the pattern direction as an input parameter; it always seems to be hardcoded into the function itself in one way or another.&lt;/p&gt;

&lt;p&gt;To me, user experience, API design, etc. matters a lot, and is in itself justification to give things names. As a parallel example, I know of several libraries that does Voronoi tesselation, but they have completely different API design and functionality. Some are useful to me while others are useless. And it&#39;s pracical for me to be able to refer other people to the ones I find useful, and not just tell them to &quot;use Voronoi tesselation&quot;, as there are a lot of details that matter beyond the basic technique.&lt;/p&gt;

&lt;p&gt;As such, since the API design, possible use cases, characteristics and documentation of my Phacelle implementation is quite different from any Phasor noise implementations I&#39;ve seen, I find it useful and practical that I and others can refer directly to this implementation by name.&lt;/p&gt;

&lt;/blockquote&gt;

&lt;p&gt;Thibault replied that he agreed that Phasor implementations that are currently available are not well documented, and that most of them are code from the Siggraph deadline that have barely been cleaned up since. He added that he might create a cleaner example one day when he&#39;ll get some time.&lt;/p&gt;


&lt;h4&gt;Verdict from two of the Phasor authors&lt;/h4&gt;

&lt;p&gt;Thibault&#39;s verdict was that Phacelle Noise gives results visually similar to Phasor in 2D, but cheaper, although it does not provide any of the frequential guarantee given by Phasor, which he said was very important for texture synthesis and for anisotropic filtering. He said it also doesn&#39;t offer control over the isotropy of the generated noise (an aspect of the Phasor Noise paper which is not utilized in the Phasor implementations I compare Phacelle Noise with).&lt;/p&gt;

&lt;p&gt;He concluded that if the question is whether anybody did exactly the same thing, the answer would be no, but that Phacelle did not do anything new that warranted publishing. Which is fine, as I have no intention of publishing.&lt;/p&gt;

&lt;p&gt;Fabrice added that what I propose is a discussion about technical choices, and that while he believed no scientific reviewer would agree it&#39;s a new method, it could totally be accepted as such in practical (and lovely) venues like the JCGT journal (a follow-up to the Graphics Gem book series), which is interested in how to make things usable. (But again, I&#39;m not interested in publishing.)&lt;/p&gt;


&lt;h3&gt;Links&lt;/h3&gt;

&lt;p&gt;Implementations used for reference:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;My &lt;a href=&quot;https://www.shadertoy.com/view/t3KczR&quot; target=&quot;_blank&quot;&gt;Simple Phacelle Noise Profile&lt;/a&gt; Shadertoy.&lt;/li&gt;
  &lt;li&gt;My &lt;a href=&quot;https://www.shadertoy.com/view/w3ycRw&quot; target=&quot;_blank&quot;&gt;Sampled Phacelle Noise Profile&lt;/a&gt; Shadertoy.&lt;/li&gt;
  &lt;li&gt;The original &lt;a href=&quot;https://www.shadertoy.com/view/wlsXWf&quot; target=&quot;_blank&quot;&gt;Procedural Phasor Noise Profile&lt;/a&gt; Shadertoy by Thibault Tricard (Phasor first author).&lt;/li&gt;
  &lt;li&gt;My forked &lt;a href=&quot;https://www.shadertoy.com/view/33yyWR&quot; target=&quot;_blank&quot;&gt;Phasor Noise Profile&lt;/a&gt; Shadertoy, which has additional sample patterns, such as the checker one.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/NsdGz2&quot; target=&quot;_blank&quot;&gt;Phasor noise&lt;/a&gt; Shadertoy by Xavier Chermain (a colleague of Phasor author Thibault Tricard) which corrected some mistakes in the original Phasor Shadertoys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Shadertoys I&#39;m aware of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/3tKGWR&quot; target=&quot;_blank&quot;&gt;Gabor/Phasor flow&lt;/a&gt; Shadertoy by Fabrice Neyret (Phasor co-author).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/XlsGDs&quot; target=&quot;_blank&quot;&gt;Gabor 4: normalized&lt;/a&gt; Shadertoy by Fabrice Neyret (Phasor co-author).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/wtj3RV&quot; target=&quot;_blank&quot;&gt;Textured Torus , phasor example&lt;/a&gt; Shadertoy by Thibault Tricard (Phasor first author).&lt;/li&gt;
&lt;/ul&gt;
  
&lt;p&gt;Presentations and artistic experiments based on Phacelle Noise:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/t3dyWl&quot; target=&quot;_blank&quot;&gt;Phacelle Noise Animation&lt;/a&gt; Shadertoy by me.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/tXGcWR&quot; target=&quot;_blank&quot;&gt;Luminescent Growth&lt;/a&gt; Shadertoy by me.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/3XGyDz&quot; target=&quot;_blank&quot;&gt;Spiked Fire Lines&lt;/a&gt; Shadertoy by me.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/4209808391381786457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/4209808391381786457' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4209808391381786457'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4209808391381786457'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2026/01/phacelle-cheap-directional-noise.html' title='Phacelle - Cheap Directional Noise'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfouoXIOlGGBPHQFJvNitpLd9c_HDLESPNzPOSXVJqN6R1zK-DLSZL3El8Mc70MUclpgdHL5F4fByfH3CfQazxoqnDiPMwfeDDPp0qxut8iSpeiXHj2mlKoRO3_RVxX-n2DInxmvPHcYiBqLyeDKjDVm44TrbSBBDbirDM2hlT5S8VDOYkbgVin8WCiaw/s72-c/PhasorNoiseProfile.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7755733926275947005</id><published>2025-10-23T13:33:00.001+02:00</published><updated>2025-10-23T13:37:23.927+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>I made a hair shader</title><content type='html'>&lt;p&gt;I&#39;ve actually been working on a cool erosion technique I&#39;ll post about later, but during some downtime, I had an impulse to see if I could make a basic hair shader that doesn&#39;t require any specially made meshes or textures. I ended up making &lt;i&gt;three&lt;/i&gt; hair shaders.&lt;/p&gt;

&lt;p&gt;The shapes below are just standard Unity spheres and capsules and only &lt;a href=&quot;https://www.filterforge.com/filters/9157-normal.html&quot; target=&quot;_blank&quot;&gt;a simple normal map&lt;/a&gt; is used; no other textures. The hair strands follow the vertical V direction of the UV map of the mesh.&lt;/p&gt;

&lt;img src=&quot;https://raw.githubusercontent.com/runevision/HairShader/main/Images/HairShaders.png&quot;&gt;

&lt;p&gt;I also found some characters on the Asset Store and tried changing the hair material to use my shader. Luckily they all already had hair aligned vertically in the UV map (although not 100% for wavy/curly hair, which compromises my shader slightly).&lt;/p&gt;

&lt;p&gt;You can see a video here with the shader in action on both basic shapes and characters:&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/K5Xyu1yQfTE?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I ended up making these three hair shader implementations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Full multisample hair shader&lt;/li&gt;
  &lt;li&gt;Specular multisample hair shader&lt;/li&gt;
  &lt;li&gt;Approximation hair shader&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three shaders support a diffuse map, a normal map, and properties for color, smoothness, and normal map strength. The diffuse map alpha is used for cutout transparency.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/runevision/HairShader&quot; target=&quot;_blank&quot;&gt;See the hair shader repository on GitHub&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The strategy was to start with Unity&#39;s Standard shading model (based on BRDF physically based shading), but modify it to simulate anisotropic shading, that is, to simulate that the surface is made from lots of little parallel cylinders rather than a flat surface.&lt;/p&gt;

&lt;p&gt;This approach ensures that the hair shader looks consistent with other materials based on Unity&#39;s Standard shader (and other Surface shaders) under a wide variety of lighting conditions and environments.&lt;/p&gt;


&lt;h3&gt;1) Full Multisample Hair Shader&lt;/h3&gt;

&lt;p&gt;I started out doing brute force anisotropic shading, running the Unity&#39;s physically based BRDF shading function up to 50 times and taking a weighted average of the sample colors.&lt;/p&gt;

&lt;p&gt;The normals in those samples are spread out in a 180 degree fan of directions centered around the original normal, using the hair strand direction as the axis of rotation. The final color is a weighted average of the samples.&lt;/p&gt;
  
&lt;p&gt;Much of the &quot;magic&quot; of the simulated anisotropic shading comes from the way the samples are weighted in the two multisample shaders (and emulated in the third).&lt;/p&gt;

&lt;img src=&quot;https://raw.githubusercontent.com/runevision/HairShader/main/Images/SampleWeights.png&quot;&gt;

&lt;p&gt;The weight of each sample is a product of two functions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The cosine of the angle between the original and modified normal. This is because strands of hair occlude other strands of hair when the hair &quot;surface&quot; is seen from the side, and the parts of strands that face outward tend to be less occluded.&lt;/li&gt;
  &lt;li&gt;The cosine of the angle between the modified normal and the view direction. This is because the part of the strand that&#39;s facing the camera takes up more of the view than parts that are seen at an angle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both cosines are clamped to a zero-to-one range before the two are multiplied.&lt;/p&gt;

&lt;p&gt;With this weight function to base the weighted average on, the results looked surprisingly good. Of course, running the entire shading up to 50 times is not exactly the fastest approach, performance-wise.&lt;/p&gt;


&lt;h3&gt;2) Specular Multisample Hair Shader&lt;/h3&gt;

&lt;p&gt;I made a second implementation that reduces computations somewhat by only multi-sampling certain calculations, namely dot products with the normal, and most of the specular term of the lighting. The diffuse term, fresnel, and other calculations are performed only once. The result is nearly indistinguishable from the full multisample hair shader.&lt;/p&gt;

&lt;p&gt;There is still a significant amount of calculations being performed up to 50 times though.&lt;/p&gt;


&lt;h3&gt;3) Approximation Hair Shader&lt;/h3&gt;
  
&lt;p&gt;Of course, non-brute force approaches to hair shading are possible too, but way harder to make look good. Still, I eventually came up with something fairly decent.&lt;/p&gt;

&lt;p&gt;The third implementation does not perform multisampling but instead emulates the same result. The math formulas required for this were devised by means of a combination of partial understanding, intuition, and trial and error, while carefully comparing the results with the full multisample hair shader. As such, it&#39;s difficult to explain the details of the logic behind it with any exactness, but you can see the details in the shader source code.&lt;/p&gt;


&lt;h3&gt;Closing thoughts&lt;/h3&gt;

&lt;p&gt;This was just a little experiment I did as a random side project. I haven&#39;t looked much at existing research on hair shaders, as I tend to not understand graphics papers very well. My impression is that this has less to do with the subject matter itself, and more to do with the manner in which it&#39;s explained.&lt;/p&gt;

&lt;p&gt;The one research entry I did look at &amp;ndash; &lt;a href=&quot;https://web.engr.oregonstate.edu/~mjb/cs557/Projects/Papers/HairRendering.pdf&quot; target=&quot;_blank&quot;&gt;Hair Rendering and Shading by Thorsten Scheuermann&lt;/a&gt; &amp;ndash; only shows the results on a complex multi-layered haircut model; not simple spheres like I used for testing, which makes it impossible to compare results meaningfully.&lt;/p&gt;

&lt;p&gt;I&#39;m not planning any further work on the hair shaders, but I&#39;ve &lt;a href=&quot;https://github.com/runevision/HairShader&quot; target=&quot;_blank&quot;&gt;released them as open source on GitHub&lt;/a&gt;. If anyone makes changes or improvements to them &amp;ndash; or just use them in a project &amp;ndash; I&#39;d love to hear about it.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7755733926275947005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7755733926275947005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7755733926275947005'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7755733926275947005'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2025/10/i-made-hair-shader.html' title='I made a hair shader'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-5998472106018930994</id><published>2025-06-29T12:56:00.008+02:00</published><updated>2025-07-06T11:46:32.822+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><title type='text'>Notes on atmospheric perspective and distant mountains</title><content type='html'>&lt;p&gt;I don&#39;t know if it&#39;s because I come from a supremely flat country, or in spite of it, but I love terrain with elevation differences. Seeing cliffs or mountains in the distance fills me with a special kind of calm. The game I&#39;m currently working on, The Big Forest, is full of mountain forests too.&lt;/p&gt;

&lt;p&gt;I&#39;ve just returned from three weeks of vacation in Japan, and I had ample opportunities to admire and study views with layers upon layers of mountains in the distance. And while studying these views, something about the shades of mountains at different distances clicked for me that’s now obvious in retrospect. I&#39;ll get back to that.&lt;/p&gt;

&lt;p&gt;Note: No photos here have any post-processing applied, apart from what light processing an iPhone 13 mini does out of the box with default settings. I often looked at the photos right after taking them, and they looked pretty faithful to what I could see with my own eyes.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKNCbGGQzQc3wy-_GHO1eTwJya0Qh7nIUDrLhPsay6M3c_coG8b-mKv2fdkSQhE5N_HvEOXvexm8sklmI687Dt6wHR17TWAvf0YuIuCszh8GbHZiAf2XbJW_u3q8c8xosr90tLaQwkH-K6OhXWjHPkCHv-GY3xNYQsNi3TuZWG6RRLYdq9EGm5LFGxVpU/s1600/2025-06-07%2011.47.10.heic&quot;/&gt;
&lt;figcaption&gt;Increasingly deep blue mountains in the distance, seen from a panoramic spot on the Magome-Tsumago Trail.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhswOEMtjfOsl8YQsZWJf8lLftWOXLubepHmMpn6FuHCBp70ubsLDj9xip0OivNHG2dcaWPGYTjDNHmf8S_Pp4I7mQZjTrkfy34sgLvEtraLcHEHW3uIO5n4l8ZaxAySCNo0II99xU98dGfDSOwsPhY7aPefseGHKWq4IuQMHduc_5mg7V1qdwDogs7AOA/s1600/2025-06-07%2017.36.59.heic&quot;/&gt;
&lt;figcaption&gt;Mountain ridges accentuated by both lighting and the haze of the atmosphere. Seen from a train near Nakatsugawa.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;The blue tint of atmospheric perspective&lt;/h3&gt;

&lt;p&gt;A beautiful thing about mountains in the far distance is how they appear as colored shapes behind each other in various shades of blue. Sometimes it looks distinctly like a watercolor painting.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz08csoGEn5amFweAH79kPM63bPIqGT6Rs1M8enERiYdiO6MNUb7beGuyeAHw0QZnnDhNNkakeJnLX7GmxQScvcJyylFs4sqGVy2wNwXlvjd8cvFLGtO6oOoJNST6zrFRMkPhKBWrqJUp6zRStJe74pj_oyx6-uB7J9a2ny5JaYoByXBBEmhEuqKFdyic/s1600/2025-06-09%2014.39.29.heic&quot;/&gt;
&lt;figcaption&gt;Light blue mountains in the background behind Matsumoto city on a cloudy day.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In an art context, the blue tint that increases with distance is called &lt;i&gt;aerial perspective&lt;/i&gt; or &lt;i&gt;atmospheric perspective&lt;/i&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Aerial_perspective&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I&#39;ve tried to capture this in The Big Forest too by making things more blue tinted in the distance. In terms of 3D graphics techniques, I implemented it by using the simple fog feature which is built into Unity and most other engines. By setting the fog color to blue, everything fades towards blue in the distance. It can produce a more or less convincing aerial perspective effect. Using fog for this purpose is as old as the fog feature itself. The &lt;a href=&quot;https://www.opengl.org/archives/resources/code/samples/advanced/advanced97/notes/node122.html&quot; target=&quot;_blank&quot;&gt;original OpenGL documentation&lt;/a&gt; mentions that the fog feature using the exponential mode &quot;can be used to represent a number of atmospheric effects&quot;, implying it&#39;s not only for simulating fog. For our purposes, let&#39;s call it the &lt;i&gt;fog trick&lt;/i&gt;.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFiLc-vXhdP3-Cf01S4YaZz6OyS5UiYlM1nxdmJJw1AWWuHLYMPFhms6aqn3LU_OcpEarob3xX_jBlo2xkhjMve2jKCG3ydlWUl6z5jnqvk0t3N4OZJmnq0hZY2-JUFzX3c74Fc0l-Eh7gfPl11TyJFd9k9aGY2BpmmYxdA5NPuPT1fkcIvyh7ObFq48E/s1600/Landscape_Blue.png&quot;/&gt;
&lt;figcaption&gt;Work in progress screenshot from The Big Forest, showing blue tinted terrain in the distance.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Which color does things fade towards?&lt;/h3&gt;

&lt;p&gt;I long held a misconception that things in the distance (like mountains) get tinted towards whatever color the sky behind them has. In daytime when the sky is blue, the color of mountains approach the same blue color the further away they are. At sunset where the sky is red, the mountains approach that red color too. A hazy day where the sky is white? The mountains fade towards white too.&lt;/p&gt;

&lt;p&gt;Of course, the sky is not a single color at a time. Even at its blueest, it&#39;s usually more pale at the horizon than straight above.&lt;/p&gt;

&lt;p&gt;This raises a dilemma when using the fog trick. Set the fog color too close to the blue sky above, and the distant mountains appear unnatural near the pale horizon. But set the fog color to the pale color of the sky at the horizon, and the result is even worse: Some mountain peaks may then end up looking paler than the sky right behind them, and that looks very bad, since it never happens in reality.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZnOwQspj0DpIBw3pVLOlBWt7E7qG785K-Q-vl-u20_1ThY0ZY2YvV5jcUdBrSFd5Oy2tFPoa_pf34MMGasI8oShtDUXgUO54jfTuY0xGu4iHUeHQ6LgQ38nQH8SZ7zJHJ7FfGJr2aMPM-3B_yWnK1IVDKJjdTxeM9dscQMegIOQKW39oWsArmit3pC3c/s1600/Landscape_Pale.png&quot;/&gt;
&lt;figcaption&gt;Fading towards a color that matches the horizon can make mountain peaks tinted paler than the sky behind them. This looks bad, and doesn&#39;t occur in reality.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;For a long time I wished Unity had a way to fade towards the skybox color (the color of the sky at a given pixel) rather than a single fixed color.&lt;/p&gt;

&lt;p&gt;In practice, it&#39;s not too difficult to settle on a compromise color which looks mostly fine. It&#39;s just still not ideal, for reasons that will become clear later.&lt;/p&gt;


&lt;h3&gt;Are more distant mountains more pale?&lt;/h3&gt;

&lt;p&gt;Now, while I was tweaking the fog color in my game and in general contemplating atmospheric perspective, I could see from certain reference photos I&#39;d found on the Internet that mountains look paler at great distances. Not just paler than their native color – green if covered in trees – but also paler than the deep blue tint they appear with at less extreme distances.&lt;/p&gt;

&lt;p&gt;This was counter-intuitive. How could the atmosphere tint things increasingly saturated blue up to a certain distance, but less saturated again beyond that point? Now, the thing is, you never know how random reference photos have been processed, and which filters might have been applied. For a while, I thought it simply came down to tone mapping.&lt;/p&gt;

&lt;p&gt;Tone mapping is a technique used in digital photography and computer graphics to map very high contrasts observed in the real world (referred to as high dynamic range) into lower contrasts representable in a regular photograph or image (low dynamic range). For context, the sky can easily be a hundred times brighter than something on the ground that&#39;s in shadow. Our eyes are good at perceiving both despite the extreme difference in brightness, but a photograph or conventional digital image cannot represent one thing that&#39;s a hundred times brighter than another without losing most detail in one or the other.&lt;/p&gt;

&lt;p&gt;If you try to take a picture with both sky and ground, the sky may appear white in the photo even though it looked blue to your eyes. Or if the sky appears as blue in the photo as it did to your eyes, then the ground may appear black. Tone mapping makes it possible to achieve a compromise: The ground can be legible while the sky also appears blue, but it&#39;s a paler blue in the photo than it appeared to your eyes. Tone mapping typically turns non-representable brightness into paleness instead.&lt;/p&gt;

&lt;p&gt;So I thought: Distant mountains approach the color – and brightness – of the sky, so they may appear increasingly pale in photos simply because they&#39;re increasingly bright in reality, and the brightness gets turned into paleness by tone mapping.&lt;/p&gt;

&lt;p&gt;However, while observing distant mountains with my own eyes on the Japan trip, it became clear that this theory just doesn&#39;t hold up.&lt;/p&gt;


&lt;h3&gt;Revised theory&lt;/h3&gt;

&lt;p&gt;Some of my thinking was partially true. Distant mountains do take on the color of the sky, just in a bit different way than I thought. And tone mapping does sometimes affect the paleness of the sky and distant mountains.&lt;/p&gt;

&lt;p&gt;But on this trip I had ample opportunity to study mountains layered at many distances behind each other. I could observe with my own eyes (no tone mapping involved) that they do get paler with distance. (It&#39;s not that I&#39;ve never seen mountains in the distance with my own eyes before, but on previous occasions I guess I didn&#39;t think very analytically about the exact shades.) Furthermore I&#39;ve taken a lot of pictures of it, where (unlike random pictures I find on the Internet) I&#39;ve verified that the colors and shades look about the same in the pictures as they looked to my eyes in real life.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfC10VPvhPAgaNtZDKX2UpFSneOlQx6c6tYLOpi1qtvA29lX8Rb5CgST7y7i91tz2OY78AiI5Hkvx88WlVDCEd052EEQ3t_fkcpXRLi3u0OCnzzBvnMQyTBC8gz5WogBSKolaFB3HvuVAKIG0NZaSDrnwSqTSsDAoZ44HMVwZruew8p2dxm2UHoms3WeM/s1600/2025-06-07%2011.43.47_zoom.png&quot;/&gt;
&lt;figcaption&gt;Photo from the Magome-Tsumago Trail where mid-distant mountains in the left side are a more saturated blue while more distant mountains near the right side (also shown in zoomed-in cutout) are paler. The most distant can only barely be distinguished from the sky.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;So here&#39;s what finally clicked for me:&lt;/p&gt;

&lt;blockquote&gt;Mountains transition from a deep blue tint in the mid-distance to a paler tint in the far distance for the same reason that the sky is paler near the horizon.&lt;/blockquote&gt;

&lt;p&gt;To the best of my current understanding, the complex scientific reason relates to how Rayleigh scattering (&lt;a href=&quot;https://en.wikipedia.org/wiki/Rayleigh_scattering&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;) and possibly Mie scattering (&lt;a href=&quot;https://en.wikipedia.org/wiki/Mie_scattering&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;) interact with sunlight and the human visual system, but the end result is this:&lt;/p&gt;

&lt;p&gt;As you look through an increasing distance of air (in daytime), the appearance of the air changes from transparent, to blue, to nearly white. (Presumably this goes through a curved trajectory in color space).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When you look at the sky, there&#39;s more air to look through near the horizon than when looking straight up, so the horizon is paler.&lt;/li&gt;
  &lt;li&gt;Similarly, there&#39;s also more air to look through when looking at a more distant mountain compared to a less distant one, so the more distant one is paler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small corollary to this is that the atmospheric tint of a mountain can only ever be less pale than the sky immediately behind it, since you&#39;re always looking through a greater distance of air when looking just past the mountain than when looking directly at it.&lt;/p&gt;

&lt;p&gt;This can be generalized, so it doesn&#39;t only work at daytime, but for sunsets too: Closer mountains are tinted similar to the sky further up, while more distant mountains are tinted similar to the sky nearer the horizon. In practice though, it&#39;s hard to find photos showing red-tinted mountains; much more common are blue-tinted mountains flush against the red horizon. Possibly the shadows from the mountains at sunset play a role, or perhaps the distance required for a red tint is so large that mountains are almost never far enough away.&lt;/p&gt;

&lt;p&gt;I sort of knew the part about the horizon being paler due to looking through more air, but for some reason hadn&#39;t connected it to mountains at different distances. In retrospect it&#39;s obvious to me, and I&#39;m sure lots of the readership of this blog were well aware of it, and find it amusing that I only found out about it now. On the other hand, I can also see why it eluded me for a long time:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It&#39;s just not intuitive that a single effect fades things towards one color or another depending on the magnitude.&lt;/li&gt;
  &lt;li&gt;It&#39;s hard to find good and reliable reference photos, and unclear how to interpret them given the existence of filters and tone mapping.&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Aerial_perspective&quot; target=&quot;_blank&quot;&gt;Wikipedia page on aerial perspective&lt;/a&gt; doesn&#39;t mention that the color goes from deeper blue to paler blue with distance. You could read the entire page and just come away with the same idea I had, that aerial perspective simply fades towards one color.&lt;/li&gt;
  &lt;li&gt;If you go deeper and read the Wikipedia pages on &lt;a href=&quot;https://en.wikipedia.org/wiki/Rayleigh_scattering&quot; target=&quot;_blank&quot;&gt;Rayleigh scattering&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Mie_scattering&quot; target=&quot;_blank&quot;&gt;Mie scattering&lt;/a&gt;, they don&#39;t mention it either. The one on Rayleigh scattering has a section about &quot;Cause of the blue color of the sky&quot;, but it doesn&#39;t mention anything about the horizon being paler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, I&#39;ve not yet found any resource that is explicit about the fact that the color of increasingly distant mountains go from deeper blue to paler blue. It&#39;s even hard to find any references that explain why the sky is paler near the horizon, and the random obscure &lt;a href=&quot;https://www.reddit.com/r/askscience/comments/34pvyn/why_is_the_sky_lighter_close_to_the_horizon/&quot; target=&quot;_blank&quot;&gt;Reddit&lt;/a&gt; and &lt;a href=&quot;https://earthscience.stackexchange.com/questions/24623/why-does-earths-atmosphere-have-a-whiter-color-near-the-horizon&quot; target=&quot;_blank&quot;&gt;Stack Exchange&lt;/a&gt; posts I did find did not agree on whether the paleness of the horizon is due to Rayleigh scattering or to Mie scattering.&lt;/p&gt;

&lt;p&gt;I found and tinkered with &lt;a href=&quot;https://www.shadertoy.com/view/wlBXWK&quot; target=&quot;_blank&quot;&gt;this Shadertoy&lt;/a&gt;, and if that&#39;s anything to go by, the pale horizon comes from Rayleigh scattering, while Mie scattering primarily produces a halo around the sun. I don&#39;t know how to add mountains to it though.&lt;/p&gt;

&lt;p&gt;All right, that was a lot of text. Here&#39;s another nice photo to look at:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyJIiejHT39zdRCJlRGEVq5dYosxyHKo55H715jvrPu08BnzPbMTW1ykhq1En3fG6PsVNkvYf3yXXIuXDhBnNml50GghUAjTt-_azrWJl-pW2JpMEkyWB-vaGnwloY-6uwZ4kzKZVdDs1Jf3wekGThpFPw0Xd13NFXauRY4yCZcZTe0H4rN7hekt6scKs/s1600/2025-06-12%2012.58.28.heic&quot;/&gt;
&lt;figcaption&gt;A nice mountain vista seen from the site outside Abukuma Cave.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I&#39;m still not really certain of much, and you should take my conclusions with a grain of salt. I haven&#39;t yet found any definitive validation of my theory that mountains are paler with distance for the same reason the horizon is paler; it&#39;s just my best explanation based on my observations so far. I find it somewhat strange that it&#39;s so difficult to find good and straightforward information on this topic (at least for people who are not expert graphics programmers or academics), but perhaps some knowledgeable readers of this post can shed additional light on things.&lt;/p&gt;

&lt;p&gt;One thing is pretty clear: An accurate rendition of atmospheric perspective (at great distances) cannot be achieved in games and other computer graphics by using the &lt;i&gt;fog trick&lt;/i&gt;, or other approaches that fade towards a single color. I haven&#39;t yet researched alternatives much, but I&#39;m sure there must be a variety of off-the-shelf solutions for Unity and other engines. I&#39;ve learned that Unreal has a powerful and versatile Sky Atmosphere Component built-in, while Unity&#39;s HD render pipeline has a Physically Based Sky feature, which however seems problematic according to various forum threads. If you have experience with any atmospheric scattering solutions, feel free to tell about your experience in the comments below.&lt;/p&gt;

&lt;p&gt;It&#39;s also worth noting though that the distances at which mountains fade from the deepest blue to paler blue colors can be quite extreme, and may not be relevant at all for a lot of games. Plenty of games have shipped and looked great using the &lt;i&gt;fog trick&lt;/i&gt;, despite its limitations.&lt;/p&gt;


&lt;h3&gt;Light and shadow&lt;/h3&gt;

&lt;p&gt;Let&#39;s finally move on from the subject of paleness, and look at how light and shadow interacts with atmospheric perspective.&lt;/p&gt;

&lt;p&gt;Here are two pictures of the same mountains (the big one is the volcano Mount Iwate) from almost the same angle, at two different times. In the first, where the mountain sides facing the camera are in shadow, the mountains appear as flat colors. In the second you can see spots of snow and other details on the volcano, lit by the sun. The color of the atmosphere is also a deeper blue in the second picture, probably due to being closer to midday.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfIi6Sslpcu-OKxC3mndIBp0xWR1CFMspnD6h0U4w9pyftbCyfyGN-h8oAu_zv6rIEcIZ7VcYdBkSJJm02bN0lFISMxuJK8KnxJgPv3JSvfxhzFYotrgE-UWNmZ1JkTzqBInax1W6iriCmL6xBZZj48B8pKDpJLDpNF1JAVehiBcmw2oYPSIG31ozlD-g/s1600/2025-06-13%2017.42.04.heic&quot;/&gt;
&lt;figcaption&gt;A view towards Mount Iwate from Kaiunbashi Bridge in Morioka, taken at 6 p.m. The mountain appears as a shape with a single flat color.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJjiIxcNzazV4LrR2HtUideVrkU4A3SKpnJXIk0i0Mt7C8PhtJpygVWFRaqaPIVjWgRWgkUXBBLSUH3YqLhFTxJucLpPwgeWhtHZ4cc7-gG6FMRIZAVSB3003p0-WqXGAeccR1N-DYcp91nC50FKuwtsA6VzTcR12TEo7HvS9Xii16dhLZHiG2y7Cw1Lc/s1600/2025-06-16%2011.58.39.heic&quot;/&gt;
&lt;figcaption&gt;A view towards Mount Iwate from Kaiunbashi Bridge in Morioka, taken at noon. Spots of snow are visible on the top, and creases in the mountain are faintly visible.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;And here&#39;s a picture from Yama-dera (Risshaku-ji temple), where the partial cloud cover lets us see mountains in both sunlight and shadow simultaneously. This makes it very clear that mountain sides at the same distance appear blue when in shadow and green when in light. The blue color of the atmosphere is of course still there in the sunlit parts of the surface, but it&#39;s owerpowered by the stronger green light from the sunlit trees.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS-rgvixBvVCRUzdCV2bu2iWqd_IS0qOpvFtk3ngpixubDqRb3DMJzv-S8kx4c-0dDBBmzQ_nNVaLXh1s6nYcQcPZIBzIQbw75P_0FgUDLcWPqLpPguargT2ttpriOUeq3QkJJDhyvxZS_sHZvKGPOjg7um6IMABc_8FyW-Adlw9pjvNoAtK3Lvj4mlL0/s1600/2025-06-18%2011.22.10.heic&quot;/&gt;
&lt;figcaption&gt;A view from a wooden pavilion in the Risshaku-ji temple, overlooking the nearby valley. Partial cloud cover leaves the mountains partially lit and partially in shadow, which in the distance makes them look blue with green spots.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;That&#39;s all the observations on atmospheric perspective I made for now. I would love to hear your thoughts and insights! If you&#39;d like to see more inspiring photos from my Japan trip (for example from a mystical forest stairway), I wrote &lt;a href=&quot;https://blog.runevision.com/2025/06/photos-from-inspiring-trip-in-japan.html&quot;&gt;another post about that&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Resources for further study&lt;/h3&gt;

&lt;p&gt;Here are links to some resources I and others have come across while looking into this topic.&lt;/p&gt;

&lt;p&gt;From my perspective, these resources are mostly to get a better understanding of the subject, and the theoretical possibilities. In practice, it&#39;s not straightforward to implement one&#39;s own atmospheric scattering solution in an existing engine. Even in cases where the math itself is simple enough, the graphics pipeline plumbing required to make the effect apply to all materials (opaque and transparent) is often non-trivial or outright prohibitive for people like me, who aren&#39;t expert graphics programmers.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A simple improvement upon single-color fog is to use different exponents for the red, green, and blue channel. This can be used to have the tint of the atmosphere shift from blue to white with distance. There&#39;s example shader code for it in &lt;a href=&quot;https://iquilezles.org/articles/fog/&quot; target=&quot;_blank&quot;&gt;this post by Inigo Quilez&lt;/a&gt;, though unfortunately it lacks images illustrating the effect. The post also covers how to fade towards a different color near the sun, and other effects.&lt;/li&gt;
  &lt;li&gt;Here&#39;s a 2020 &lt;a href=&quot;https://sebh.github.io/publications/egsr2020.pdf&quot; target=&quot;_blank&quot;&gt;academic paper&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=SW30QX1wxTY&quot; target=&quot;_blank&quot;&gt;video&lt;/a&gt; and &lt;a href=&quot;https://github.com/sebh/UnrealEngineSkyAtmosphere&quot; target=&quot;_blank&quot;&gt;code repository&lt;/a&gt; for the atmospheric rendering in Unreal, and here&#39;s the &lt;a href=&quot;https://dev.epicgames.com/documentation/en-us/unreal-engine/sky-atmosphere-component-in-unreal-engine&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Here&#39;s the &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@17.3/manual/physically-based-sky-volume-override-reference.html&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt; for Unity&#39;s Physically Based Sky.&lt;/li&gt;
  &lt;li&gt;A 2008 paper that gets referenced a lot is &lt;a href=&quot;https://inria.hal.science/inria-00288758/en&quot; target=&quot;_blank&quot;&gt;Precomputed Atmospheric Scattering&lt;/a&gt; by Bruneton and Neyret, with &lt;a href=&quot;https://github.com/ebruneton/precomputed_atmospheric_scattering&quot; target=&quot;_blank&quot;&gt;code repository here&lt;/a&gt;. Unity&#39;s solution is based on it, and it&#39;s cited and compared in Unreal&#39;s paper.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/5998472106018930994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/5998472106018930994' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5998472106018930994'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5998472106018930994'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2025/06/notes-on-atmospheric-perspective-and.html' title='Notes on atmospheric perspective and distant mountains'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKNCbGGQzQc3wy-_GHO1eTwJya0Qh7nIUDrLhPsay6M3c_coG8b-mKv2fdkSQhE5N_HvEOXvexm8sklmI687Dt6wHR17TWAvf0YuIuCszh8GbHZiAf2XbJW_u3q8c8xosr90tLaQwkH-K6OhXWjHPkCHv-GY3xNYQsNi3TuZWG6RRLYdq9EGm5LFGxVpU/s72-c/2025-06-07%2011.47.10.heic" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-8291470710422348832</id><published>2025-06-27T16:07:00.014+02:00</published><updated>2025-06-29T17:15:23.897+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="inspiration"/><title type='text'>Photos from an inspiring trip in Japan</title><content type='html'>&lt;p&gt;I&#39;ve just returned from three weeks of vacation in Japan. Besides being great as a vacation – which was the only thing my partner and I planned for, really – it happened to also be inspiring for me as a game developer. I like to make games that take place at least partially in beautiful nature, give a sense of mystery and wonder that invites exploration, and that have environments that incorporate strong verticality. And in all of these respects, Japan delivers in spades.&lt;/p&gt;

&lt;img style=&quot;display:none&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSjW-afFi31bkRb0tXINxy_j9hVf9EqMby3OzGpqAlI3qcGLHRbzYR4Nuzo3ctSMMop9aLgFOGz9j_mr8SpkbSbXrXAZHJ4muaTMFKkOpx3Chs_AhJGKPnF45eDTOrEGD_yCtYYy3d_w5LTs5s3u3nFpX3FT89P79SO0rNLLsb6LzKAH4AjgiGyuiHiU8/s1600/2025-06-18%2011.29.11.heic&quot;/&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;

&lt;p&gt;Of the many hundred photos we took, I&#39;ve selected a few dozen to share here, along three themes.&lt;/p&gt;

&lt;p&gt;I had originally intended to include a section on distant mountains and atmospheric perspective too, but it turned into a larger topic of its own that I&#39;ve written about in &lt;a href=&quot;https://blog.runevision.com/2025/06/notes-on-atmospheric-perspective-and.html&quot; target=&quot;_blank&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;


&lt;h3&gt;Mystical forest stairway&lt;/h3&gt;

&lt;p&gt;One highlight of the vacation was our day trip to the Risshaku-ji temple in Yamadera. It&#39;s a complex of multiple temple buildings stretching up a mountainside with spectacular views, but it&#39;s almost the path up there that I found most inspiring as a game developer – a 1000-step ascent through a mystical cedar forest with shrines and stone lanterns along the way.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7onIKEgk2zG1yuWtljgPrSeWbnvII2qDDdrPQsmFCyJlM_ZWTeJujtaQlSHR5s653hIQvOt_qMHkgfI_01Ac2ptMmGEOnbEqrJ-2hOOQ2KQlmlZDhHlGf_aJqG58aSxvmM24C1HSOj4VhQ8fUREaC3mk0wlMj0oxJjKOkP6Gegyg1kLynfesQcrtzRw/s1600/2025-06-18%2010.57.15.heic&quot;/&gt;
&lt;figcaption&gt;Stairway going up to the Risshaku-ji temple through a cedar forest.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The combination of the winding stairs and the extremely tall cedar trees gave not just a strong sense of verticality, but a weirdly strong sense of three-dimensional depth in general. Weird, because I have two eyes and always see the world in 3D, but this place made me feel the spatiality of my surroundings more strongly than usual.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf-rE77k36C5Glyqm8ICsygTh5MEr4nqZk2I-QVOyy35SIDl6gYuZgTr_z06sRM5KgY4Nc1uXN7KCU9wYCG0By4j7D4oH34-KfUlw_V4ErdgmPuVW045NvC7Wbun3BHbtBOiMfMEeOSqbGEita_wJdYHa7AEdj0BRveQZsyEM_haTfI2vzFbf3JtN5TEk/s1600/2025-06-18%2011.00.23.heic&quot;/&gt;
&lt;figcaption&gt;The sides of the stairway are dotted with stone lamp posts and small shrines.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;On top of that, the sunlight filtered through the trees in that really beautiful way that makes forests look magical. The Japanese even have a word for it, komorebi (木漏れ日).&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzNA8jGPH7Hz8pTQIXiDIVEDQhF3z0jDDPUTCZf1R51NInHBZYWch-6t1pwcRKfRrn_UoiyGNCouiAw1eUZgs9RAfBbpRXA9Bx-l3KOtfRGdA9KWOa_pOgBZ02JPk8mrvnu_3BGnIJmsI2HhVJhj6IVvVlcaQ3AjuorD4RrUUo9cI5PmYgwcoatkE74-o/s1600/2025-06-18%2010.54.35.heic&quot;/&gt;
&lt;figcaption&gt;A little side path goes to a collection of inscribed stones.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;i&gt;Update:&lt;/i&gt; I got a question on Mastodon about the weirdly strong sense of three-dimensional depth I felt, which made me reflect more on the reasons.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;First of all, I think feeling small among huge shapes evoke a strong feeling of depth in general, but it may be diminished in familiar situations, such as being on a street with tall conventionally shaped buildings.&lt;/li&gt;
  &lt;li&gt;Second, distances feel greater when they&#39;re not horizontal. 100 meters down the (flat) street is nothing, but 100 meters up or down a steep incline feels huge.&lt;/li&gt;
  &lt;li&gt;Third, in most environments, you see mostly things close by (ground or wall) or mostly far away (horizon or sky) when looking in a given direction. But in forests, and inside huge buildings with many columns, you see near and far simultaneously, emphasizing depth.&lt;/li&gt;
  &lt;li&gt;Fourth, the cedar trees had huge tall trunks, which made it possible to see both high up in the air and far up the mountain side, without the view being obscured much by the tree canopies.&lt;/li&gt;
  &lt;li&gt;Fifth (and most speculatively), the sunlight being filtered through the trees produced little attention-grabbing highlights everywhere at various depths, which further enhanced the perception of depth.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I think it&#39;s this powerful combination of multiple factors that reinforced each other: Huge uncommon shapes, verticality, seeing things both near and far simultaneously, partially unobstructed far views, and the lighting. &lt;i&gt;End of update.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;The forest path ends at the entrance to the temple area, which is marked with a Niōmon gate. A few red trees adorn the landscape here amid all the green.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG5ldgtC6esZ0b76P1zrpjuHPkXu9wyoHGpQJ2f_Q94ZMDXHREZ2ml4Hvl4Agx0ahsVp-mQZfSzIg8HSKALJH_H_AMrffLfKs7T7mn0MnD2GMwyrGvz9CBtmmgxL2fNr99HUa9rwDbpPy0LnYsQWOgsqW01_2G274yMeDAlVk2q1I1oHMx3XkoyTozxQ8/s1600/2025-06-18%2011.07.00.heic&quot;/&gt;
&lt;figcaption&gt;A view from the forest path up towards the Niōmon gate which marks the entrance to the temple area.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The view at the top, past the forest, did have the advantage of gorgeous mountain views.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs2a2UoHNDBqBkALyaK24rBYuqEYJ5QVAn7vCd9wns-wj1-OEO3ZdzRRP2Z3uGq32RwHDtoOR3Ye_XsHOzx1S4vtJXIJWoBIHhb8sOwD3sy20XsCcYNBJDgMW6s03_tlK3HiiJ6pQbLGtLPkEzfbnf1mFbcpxKGeari3fNkPgLw7mGtI-AMoHcHVQ3YV4/s1600/2025-06-18%2012.09.03.heic&quot;/&gt;
&lt;figcaption&gt;One of the Risshaku-ji temple buildings is perched on the cliff side.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSjW-afFi31bkRb0tXINxy_j9hVf9EqMby3OzGpqAlI3qcGLHRbzYR4Nuzo3ctSMMop9aLgFOGz9j_mr8SpkbSbXrXAZHJ4muaTMFKkOpx3Chs_AhJGKPnF45eDTOrEGD_yCtYYy3d_w5LTs5s3u3nFpX3FT89P79SO0rNLLsb6LzKAH4AjgiGyuiHiU8/s1600/2025-06-18%2011.29.11.heic&quot;/&gt;
&lt;figcaption&gt;One path in the temple area ends at a wooden pavilion overlooking the valley.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Nature and gardens&lt;/h3&gt;

&lt;p&gt;Sometimes, what&#39;s inspiring is the whole arrangement of elements in a place; other times it can be a single magnificent tree. Here&#39;s some more things I thought looked neat.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRCcsdDrjpiBCip3o0pfBgixRJF8xyG5bkkbzNpP4Tis1lSr4QMBI7__PXfZo8JlWVjnYOipGRVUyZhKWLAHollpuXUD1KH4u5qGllYraZgDmpr3k1Tlc16aLiJrHUJmR6TfzPqWcHJMR_S0UY6aW7EWQPWUvLUQ24P16WaDwFt5yn6kKXremDA3YdcQg/s1600/2025-06-07%2015.23.00.heic&quot;/&gt;
&lt;figcaption&gt;Walking the Magome-Tsumago Trail, we saw this beautiful contrast between the shade in the forest and the sunlit mountain view visible outside it.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh2n0PzjZLUK1lhChPVGkprViDjPr7dU56cwp7Quk6TZYCqwUP-cRR8dWacbhFoVW5PrD8a5E3bhU0Lk_Ae42rTDNbjhtziJF3a9tuRp5rU1g6fGqO3E6-bzfaoK13OU81TG-IlY7cCMmFjJMEMX4frvyOnKnONc9ZDf9LPcHcdE39x-ChvX0THhjbyZ0/s1600/2025-06-07%2014.58.56.heic&quot;/&gt;
&lt;figcaption&gt;A tall waterfall near the Magome-Tsumago Trail.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcZfeNOx8uNbzTmDjPdUTijB6FvMnR6qXHkxftw2RFFFKpimiAaDyqFYyKZY1HVDM52o5NvfFcPBoc-6qEiWRd9RG6AhD4nHVPcmHtSBVKzfMT9z8itOwI7Vp6Qw1JmVslE4AMNndHi7laYH3hxAVhoUyPU7m0Pc0D1-iYourTx5Ozm0zS1u89ujbShKU/s1600/2025-06-09%2012.44.42.heic&quot;/&gt;
&lt;figcaption&gt;Beautiful tall trees in a garden at Gofukuji temple.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiunV42AOV0jfi6oZ3qGaT7t3jcM2z8Bc1zhkskXGrEjsPGsIKmke1HBlvOgBZPOrzzGIPSPFj1iCaRCoTcx63Nuicoh5NgQ31mZF7LqM0TEH18xbo88pwC3Z1fjpT9AGFEXWq9ksM43z9TB7oua5VUQXyh1UVKVfoCX42pE2Qc65rXzPmzRTE-aCLvnyA/s1600/2025-06-09%2012.45.09.heic&quot;/&gt;
&lt;figcaption&gt;Beautifully shaped trees in a garden at Gofukuji temple.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDBVMXef2UYYBDPky1f-jFm1smvR9ikVD9GV7G9uokzwggAFxnbnKO09v-J5DTYB-m8Efbkgx8tiD1JNpPMNYWvjdnWqCLcmH7Gj6qXRl72OtZ3q8GzXDPdnPh63XJPsB8uPMEs8TwB21mG5JDV66ZoA-g3jSbdDEdW3JYoMtURntxr_v4JXJZVvEIWRM/s1600/2025-06-14%2011.26.00.heic&quot;/&gt;
&lt;figcaption&gt;Quaint bridge in Morioka Castle Ruins Park.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidhHXpw9m764fXbPR5KMPkPv0EK4_paxXqCWLilhBQ4GPJEL-gcHFCTUn7bCp9ZJJcYeAkCg9Dxp_MBpC-tmcuuyGF4qKBA2tz94p6xOSUc1R4mR4qxsCR33As7RUihzQkNrnBIUk5s1rN0jUOaxxKWc3-gX0d3E-ilhOM6ADw-MRxSGglXcLk5t4c8nk/s1600/2025-06-14%2011.50.34.heic&quot;/&gt;
&lt;figcaption&gt;A magnificent tree in the Morioka Castle Ruins Park. The tree is hollow but still living. You can tell it&#39;s important, as there&#39;s a circle decoration on the ground around it, as well as two layers of fence.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq5yNo_b8jR5OQSfg_o1PwsLHuqY8SqfCLyqQKyBvvZI_l0bjzYFl8LY4Kxg5wnJdfWZ13c0HYrju6oLYV2lzK1uB2MFvMvyHcAprcubBYj-Dtm3ZVOYDs0sEA26TjjDGVbtxoixeXjPf6uT1VMzDj2WpGCHKl1-qSgaZOK5mEWVSbPkB5OQb2GMXF6SI/s1600/2025-06-15%2015.50.13.heic&quot;/&gt;
&lt;figcaption&gt;Beautiful ponds in the Morioka Castle Ruins Park.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjfYs_bE26jBmMpRdfaNdxyftvyLFYPJqHzWNTxPUU5ozB4I3HMVbz0LtBeCPPFEzDRCYRnjy57C2vZQdsRIb2GX0XS2LjSvOUtllQJQUVJkhyDwIIo3bTPK5j6zXuwlvWU9Cdar44xGmnphtR-N9IjSXqFCwtyzw977HSv_sXAzjk3Btcc6A4HxQyXk/s1600/2025-06-15%2015.04.08.heic&quot;/&gt;
&lt;figcaption&gt;Small bridges in the back garden of a tea house in Morioka.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Strolling home from a restaurant in Morioka one night, we saw this lamp post half-embedded in a hedge in a small crater-shaped indentation. The hedge was blooming, and all the flowers were facing the lamp. The other similar lamp posts along the road were not embedded in the hedge this way, so this beautiful little scene probably started as a happy accident rather than being planned for.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLXnL20LvTZbjWiuXebTB-GDokdBXHvuruO59ONKfCPAObQJuIQH6RW4ZJ3uBTMbHuKnsKDcn6OfaXAIRSOHnoWR-LnZI1tldgls4Fdpu1vnfIJIATmnkM-69bYkcplo4jHyCZeSD_ttEJllDtTC-3cvwkmKDPm0ndLnTbGMXWR0r3ugWkm5XYIZ9K_wo/s1600/2025-06-13%2019.50.22.heic&quot;/&gt;
&lt;figcaption&gt;Lamp post embedded in blooming hedge at night.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizVZsru0cga2iBnR15kv808v_dEUfBlxLhSVqR084AQL3Chf7-z9781oaMFuPJG9aitRJ5UK2tjlRMDfww1FrCiAIXYx2PrjZ1YhJlvw01Ao1ebNRf-_NGMBFpcif-2QRB2mcy2IMdDKCUwMKWZIGsOayify9nBPiHRuihA6Fv00LrmKOo1dwYCIf2ir4/s1600/2025-06-18%2011.09.30.heic&quot;/&gt;
&lt;figcaption&gt;A wild cliff side by Risshaku-ji temple, with downward facing holes in the overhangs.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROTr4rvPqjAeECpsuCmQIep02ouMWll9Y_FtaKrO615NV8dfTFc2ZnSoOjqJ4tt7iuth7gf9dAKlHBxXVMEMIVnAQk0Lh_g0yLHqc5I1ekd1glhtlMtP9swSX-ZW6T8BA_Uo5KkzDEIWYiRCCRjt5gIGDuDVyy4VLV81T9FYvwOKPWOSghPho72ur9B0/s1600/2025-06-19%2015.27.46.heic&quot;/&gt;
&lt;figcaption&gt;A faint waterfall streaming into the river at the bottom of Rairaikyo Gorge.&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Lived-in urban vibes&lt;/h3&gt;

&lt;p&gt;This is the one category which isn&#39;t directly relevant to my own games, as they don&#39;t take place in contemporary urban environments. But what can I say. I follow the artist &lt;i&gt;Alariko&lt;/i&gt; (&lt;a href=&quot;https://www.artstation.com/alariko&quot; target=&quot;_blank&quot;&gt;ArtStation&lt;/a&gt;, &lt;a href=&quot;https://bsky.app/profile/alariko.bsky.social&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt;) on social media, and I think his art has stimulated my appreciation for the beauty in the kind of lived-in, worn, quirky, cluttered urban scenes he expertly captures.&lt;/p&gt;

&lt;p&gt;In Japan, these kinds of scenes can be found everywhere. Well, maybe not in posh streets or pristine gardens, but you never have to walk far to encounter it.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8bk2XounWJfdXUu_Yupi3zwTEPVI4o93BRrNV37vMGxLM2kebn6CdMRMuH5nh3D70RpQXwS6iMzaOYabdkcoIXEEQNHj9CxnTKrfNwOhWDSaig0-zd4mrVgOZ9Q-nsAqYjD5L1nePhzSsYEeSMm_C5WWTXh6nhkmPTbylWT3YUaSdgYk2DMeuR1h3YCM/s1600/2025-06-08%2012.11.24.heic&quot;/&gt;
&lt;figcaption&gt;A street in Nakatsugawa. In front of a slightly grimy tan two-storey building, a utility pole carries a web of wires extending out to the nearby buildings, and is adorned with multiple traffic signs and a mirror.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdT6yWxrH8eW2B-LN-GlFXLJv1sw-H0UoHlexmjuydUMnBQyfIf2PenI_kKqAubVM67yEGywo9nTjSn9x-Mj9wmJuY0_T0uz2kS1G9RoFhk8_w330t7mE-VWjvuLpiD9Z-fFvyFCiWbw0T4160pf06A9TT_YE3WL30ZDOb1YrwgQSyZDDetuQ9Fqb-C0s/s1600/2025-06-14%2011.14.26.heic&quot;/&gt;
&lt;figcaption&gt;A heron is scouting by an embankment around Morioka river. Nearby is a bridge overhead, and traffic lights visible above.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1rUTgQFd3eNWwvC-rAWjMZ2Ukaok3Wakg1_xIEueTAUIEmolG0IxUaaSfF74RS_FCwbloLTIXmolN1H00nrjuwRgjN_V1JaRyEpRM8XBBE83pQaIK0HyE7BLl3KhR5JFPV-bwfhPsBznXoNB4CbcKiljHmgG7Mnjg9c4M9haIAnCkk4dKxWaIHkUPIHo/s1600/2025-06-18%2011.58.53.heic&quot;/&gt;
&lt;figcaption&gt;Private staff buildings amid the greenery near the Risshaku-ji temple, with a variety of potted plants, garden utilities, and an outdoor air conditioner unit in front.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH0VjECldzJ_sBiI2vrGfHIfW1enl_G5WN-2L9qzbnimK-zxce_G4MJHnPrnWskVdmcvyPkuXvpKmMU7n8Dyc4zLTI0ZpexHqT28U-4tU8Q07wMl7Po6jbbsC3iEbRy7Mfg9xqHBwu3XtuLcHCcn_fgVnJkR5FkkjYtQeaLOOiE3kkbOU-GnQq54wJJqA/s1600/2025-06-20%2019.23.50.heic&quot;/&gt;
&lt;figcaption&gt;A building in the Asakusa district of Tokyo is surrounded by potted plants, a bike, a blue covering over unknown items, and a red lit paper lantern.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij6T_ADR_ekETNfBNW4QmI8R3g8EPSLEnGHU_HNtw9Uiq5IM1Wbv2TLRWV9TcIdXFeaz4DxAmAHagolwArXjEfxT9YUHE4_DumPCDwOTxwGA3aBCV5K3HayFzXDtGkf5pOt2DMF-LgU4DoKitazHMT50P6HGxPBKB73u3fpCFn_vqcHPa1WF4iEws3hFc/s1600/2025-06-21%2010.59.32.heic&quot;/&gt;
&lt;figcaption&gt;A view down upon walls and rooftops of nearby buildings to our hotel in Asakusa. The view is dotted with pipes, ladders and potted plants.&lt;/figcaption&gt;
&lt;/figure&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/8291470710422348832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/8291470710422348832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/8291470710422348832'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/8291470710422348832'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2025/06/photos-from-inspiring-trip-in-japan.html' title='Photos from an inspiring trip in Japan'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSjW-afFi31bkRb0tXINxy_j9hVf9EqMby3OzGpqAlI3qcGLHRbzYR4Nuzo3ctSMMop9aLgFOGz9j_mr8SpkbSbXrXAZHJ4muaTMFKkOpx3Chs_AhJGKPnF45eDTOrEGD_yCtYYy3d_w5LTs5s3u3nFpX3FT89P79SO0rNLLsb6LzKAH4AjgiGyuiHiU8/s72-c/2025-06-18%2011.29.11.heic" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-4949056993255103046</id><published>2025-01-10T14:26:00.052+01:00</published><updated>2026-01-24T11:08:59.380+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="The Big Forest"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>Procedural creature progress 2021 - 2024</title><content type='html'>&lt;p&gt;For my game &lt;a href=&quot;https://runevision.com/multimedia/thebigforest/&quot; target=&quot;_blank&quot;&gt;The Big Forest&lt;/a&gt; I want to have creatures that are both procedurally generated and animated, which, as expected, is quite a research challenge.&lt;/p&gt;

&lt;p&gt;As mentioned in my &lt;a href=&quot;https://blog.runevision.com/2025/01/2024-retrospective.html&quot; target=&quot;_blank&quot;&gt;2024 retrospective&lt;/a&gt;, I spent the last six months of 2024 working on this – three months on procedural model generation and three months on procedural animation. My work on the creatures actually started earlier though. According to my commit history, I started in 2021 after shipping &lt;a href=&quot;https://runevision.com/multimedia/eyeofthetemple/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt; for PCVR, though my work on it prior to 2024 was sporadic.&lt;/p&gt;

&lt;p&gt;Though the creatures are still very far from where they need to be, I&#39;ll write a bit here about my progress so far.&lt;/p&gt;

&lt;h3&gt;The goal&lt;/h3&gt;

&lt;p&gt;I need lots of forest creatures for the gameplay of &lt;i&gt;The Big Forest&lt;/i&gt;, some of which will revolve around identifying specific creatures to use for various unique purposes. I &lt;a href=&quot;https://blog.runevision.com/2024/10/procedural-game-progression-dependency.html&quot; target=&quot;_blank&quot;&gt;prototyped the gameplay&lt;/a&gt; using simple sprites for creatures, but the final game requires creatures that are fully 3D and fit well within the game&#39;s &lt;a href=&quot;https://www.youtube.com/watch?v=VxMwggFQRQM&quot; target=&quot;_blank&quot;&gt;forest terrain&lt;/a&gt;.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1UPpJ75QM7Xwsrvo0xIj0kez8I_P2AndgRJm0Ni5X-OIakCbGmOtmxB41rRByO6-ZueTWCjluFsRdukGS3pdEWYchfh1vtFMrqimIXPbYFQDDlg93HyHwR1pWhjksvCQO4qqGT1ER6MZ-dmB75ojV2dmvV7EyMD67dwZ-wE8LiweSFgELjVkt0tc7Nrk/s1600/CreaturesGoal.jpg&quot;&gt;&lt;img alt=&quot;creatures from prototype → replace with 3D procedural creatures → put into procedural terrain&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1UPpJ75QM7Xwsrvo0xIj0kez8I_P2AndgRJm0Ni5X-OIakCbGmOtmxB41rRByO6-ZueTWCjluFsRdukGS3pdEWYchfh1vtFMrqimIXPbYFQDDlg93HyHwR1pWhjksvCQO4qqGT1ER6MZ-dmB75ojV2dmvV7EyMD67dwZ-wE8LiweSFgELjVkt0tc7Nrk/s1600/CreaturesGoal.jpg&quot;/&gt;&lt;/a&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;p&gt;I&#39;ve seen a fair amount of projects with procedural creatures. It&#39;s not too hard to create a simple torso with legs, randomizing the configuration, and animating movement by transitioning the feet between footsteps in straight lines or simple arcs.&lt;/p&gt;

&lt;p&gt;This works fine for bugs, spiders, lizards and other crawly critters, as well as for aliens and alien-like fantasy creatures. The project Critter Crosser is doing &lt;a href=&quot;https://www.youtube.com/watch?v=a87tB__3KEs&quot; target=&quot;_blank&quot;&gt;very cool things with this&lt;/a&gt;. While it features mammals too, I&#39;m not sure they&#39;d translate well outside the game&#39;s intentionally low-res, quirky aesthetic.&lt;/p&gt;

&lt;p&gt;If we also consider games where only the animation is procedural, &lt;a href=&quot;https://www.youtube.com/watch?v=sVntwsrjNe4&quot; target=&quot;_blank&quot;&gt;Rain World&lt;/a&gt; is another example where this works great for its low-definition but highly dynamic alien-like creatures. &lt;a href=&quot;https://www.spore.com/&quot; target=&quot;_blank&quot;&gt;Spore&lt;/a&gt; is a classic example too, though its creatures often end up looking both alien and goofy.&lt;/p&gt;

&lt;p&gt;For &lt;i&gt;The Big Forest&lt;/i&gt; though, I want creatures that feel like they truly belong in a forest, with movement and design reminiscent of quadruped mammals like foxes, bears, lynx, squirrels, and deer. The way mammals look and move is far too distinct to simply &quot;wing it&quot; – at least in my game&#39;s aesthetic. Achieving realistic mammalian creatures requires thorough study, so although I also plan to include non-mammal creatures, I’m focusing primarily on mammals for now.&lt;/p&gt;

&lt;h3&gt;Procedural generation of creatures&lt;/h3&gt;

&lt;p&gt;The basic problem is to generate forest creatures with plausible anatomy with a small set of parameters and ensure that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The parameters are &lt;i&gt;meaningful&lt;/i&gt; so I can use them to get the results I want.&lt;/li&gt;
&lt;li&gt;Any random values for the parameters will always create valid creatures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My main challenge is identifying what constitutes meaningful parameters. This is something I have to discover gradually, starting with a large number of low-level parameters based on minimal assumptions and eventually narrowing down to a smaller set of high-level parameters as I refine the logic.&lt;/p&gt;

&lt;p&gt;From the beginning, I decided to focus on basic proportions for the foreseeable future, without worrying about more subtle shape details. For this reason I limited the generated meshes to extruded rectangles. I had to start somewhere, and here&#39;s the glorious first mesh:&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtXytqhyphenhyphen_a4t847yOVBqISeUAYnq142sqOI3W1rG93bj35inzVd2JPQwdihzHo2-J4ClKzFO1_fyfBGIceeG05dp7EqEimFbfuFubwFi-J9dhLi5NOtK7NYiLBPSDzfMW2j1PIxtw1fRsliwvlXUgiBIyMKiKLw79LqpAQ1wTjtbjjCqvhIYLJhnDoi1Y/s1600/CreatureBeginning.jpg&quot;&gt;&lt;img alt=&quot;A very boxy creature.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtXytqhyphenhyphen_a4t847yOVBqISeUAYnq142sqOI3W1rG93bj35inzVd2JPQwdihzHo2-J4ClKzFO1_fyfBGIceeG05dp7EqEimFbfuFubwFi-J9dhLi5NOtK7NYiLBPSDzfMW2j1PIxtw1fRsliwvlXUgiBIyMKiKLw79LqpAQ1wTjtbjjCqvhIYLJhnDoi1Y/s1600/CreatureBeginning.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;Later I specified the torso, each leg, each foot, the neck, head, jaw, tail, and each ear as multi-segmented extruded rectangles. I found this approach easily sufficient for capturing the likeness of different animals. By the end of 2023, I had produced these three creatures and the ability to interpolate between them:&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqSYzXAl8cK0PjbxbihvcIChlvunZ0MNQakBBftgypmocql7oZFndVniCfL2HT-OPM8H3KwbQJJAGcrlgidcRJoD8pmASjODDIBSefK1F3Z1es82GUw_GgtKloRSRXmdGe6PKGgADloYfXk3NHolTQFfXhddj9dGPPxsXEBWdBUG5qzod5WxvmRhgTIzQ/s1600/ThreeCreatures.jpg&quot; &gt;&lt;img alt=&quot;Simple 3D models of a bull elk, a coyote and a cat.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqSYzXAl8cK0PjbxbihvcIChlvunZ0MNQakBBftgypmocql7oZFndVniCfL2HT-OPM8H3KwbQJJAGcrlgidcRJoD8pmASjODDIBSefK1F3Z1es82GUw_GgtKloRSRXmdGe6PKGgADloYfXk3NHolTQFfXhddj9dGPPxsXEBWdBUG5qzod5WxvmRhgTIzQ/s1600/ThreeCreatures.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;This was based on very granular parameters, essentially a list of bones with alignment and thickness data. Each bone length, rotation values, and skin distance from the bone in various directions was an input parameter, totaling 503 parameters.&lt;/p&gt;

&lt;p&gt;Creating creatures from scratch using these parameters was impractical, so I developed a tool to extract data from skinned meshes. The tool identified which vertices belonged to which bones and derived the thickness values from that. However, it was error-prone, partly due to inconsistent skinning of the reference models. For example, in the cat model, one of the tail bones wasn’t used in the skinning, which confused my script. This is why part of the cat’s tail is missing in the image above.&lt;/p&gt;

&lt;p&gt;I tried to implement workarounds for such edge cases, and various ways to manually guide the script towards better results for each creature, but each new reference 3D model seemed to come with new types of quirks to handle. After resuming work in 2024, I had these seven creatures, with their reference 3D models shown below them:&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA8YIPRMFJ4YGFHJKBAVMZVnuzdO0H8BTyCkgysFDxfrgdVPeaaLqE6NnuQrFbAqv-VZ1f3m11yF8Twe5vYkB3BBwkyUCwp5FPrwFTkyTmeLKMww9Scoumvr2zbtaUJeH4TupIGT00epd40MHRW6aiHk2B8KFH29sU1j96IgXDOO3Ai1lf73hwTTm5DcE/s1600/SevenCreatures.jpg&quot;&gt;&lt;img alt=&quot;Seven generated creatures. Five of them have hand-crafted reference 3D models below.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA8YIPRMFJ4YGFHJKBAVMZVnuzdO0H8BTyCkgysFDxfrgdVPeaaLqE6NnuQrFbAqv-VZ1f3m11yF8Twe5vYkB3BBwkyUCwp5FPrwFTkyTmeLKMww9Scoumvr2zbtaUJeH4TupIGT00epd40MHRW6aiHk2B8KFH29sU1j96IgXDOO3Ai1lf73hwTTm5DcE/s1600/SevenCreatures.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;(I lost two of my original reference 3D models – the coyote and bull elk – because they were in Maya format. Since I don’t have Maya installed, when a project reimport was triggered, Unity couldn’t import the models, and they vanished. Since it&#39;s not standard practice to commit Unity’s imported data (the Library folder) to source control, I couldn’t recover them.)&lt;/p&gt;

&lt;p&gt;Anyway, so far all my efforts had been focused on representing diverse creatures through a uniform structure that can be interpolated, but I hadn&#39;t yet made progress on defining higher-level parameters.&lt;/p&gt;

&lt;h4&gt;Failed attempts at automatic parametrization&lt;/h4&gt;

&lt;p&gt;Once I shifted my focus to defining higher-level parameters, the first thing I tried out was using Principal Component Analysis (PCA) (&lt;a href=&quot;https://en.wikipedia.org/wiki/Principal_component_analysis&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;) to automatically identify these parameters based on my seven example animals. In technical terms, it worked. The PCA algorithm created a parametrization of seven parameters, and here&#39;s a video where I manipulate them one at a time:&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240807_CreaturePrincipalComponentAnalysis.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;
  
&lt;p&gt;As I suspected though, the results weren&#39;t useful because each parameter influenced many traits at once, with lots of overlap, making the parameters &lt;i&gt;not meaningful&lt;/i&gt;.
  
&lt;p&gt;Why did it create seven parameters? Well, when you have X examples, it&#39;s easy to create a parametrization with X parameters that can represent all of them. You essentially assign parameter 1 to represent &#39;contribution from example 1&#39;, parameter 2 to represent &#39;contribution from example 2&#39;, and so on. This is essentially a weighted average or interpolation. While this isn&#39;t exactly what Principal Component Analysis does, for my purposes it was just as unhelpful. Manipulating the parameters still &lt;i&gt;felt&lt;/i&gt; more like interpolating between examples than controlling specific traits.&lt;/p&gt;

&lt;p&gt;When I talk about &quot;meaningful parameters&quot;, I mean parameters I can understand – something I could use in a &quot;character creator&quot; to easily adjust the traits of a creature to achieve the results I want. Say, parameters such as:&lt;p&gt;

&lt;ul&gt;
&lt;li&gt;Bulkiness&lt;/li&gt;
&lt;li&gt;Tallness (relative to back spine length)&lt;/li&gt;
&lt;li&gt;Head length (relative to back spine length)&lt;/li&gt;
&lt;li&gt;How pointy the ears are&lt;/li&gt;
&lt;li&gt;Thickness of the tail at the base (relative to torso thickness)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, PCA doesn’t work that way. Each parameter it produces influences many traits at once, making it impossible to control one trait at a time. I encountered the same issue in the academic research project &lt;a href=&quot;https://smal.is.tuebingen.mpg.de/&quot; target=&quot;_blank&quot;&gt;The SMAL Model&lt;/a&gt;. While this project is far more sophisticated than what I could do, and is based on a much larger set of example animals, their PCA-based parametric model (&lt;a href=&quot;https://dawars.me/smal/&quot; target=&quot;_blank&quot;&gt;which you can try interactively here&lt;/a&gt;) suffers from the same problem. Even though it can represent a wide range of animals, I wouldn&#39;t know how to adjust the parameters to create a specific animal without excessive trial and error.&lt;/p&gt;

&lt;p&gt;I&#39;m also convinced that throwing modern AI at the problem wouldn&#39;t work either. Not only would it require far more example models (which I don&#39;t have) and AI training expertise (which I have no interest in acquiring); it still wouldn&#39;t address the fundamental issue: An automated process can&#39;t understand what correlations and parameters are meaningful to a human.&lt;/p&gt;

&lt;p&gt;Another problem with automated parameters is that they don&#39;t seem to guarantee valid results. When experimenting with my own PCA setup, or with the &lt;i&gt;SMAL Model&lt;/i&gt; I linked to, it&#39;s easy to come across parameter combinations that produce deformed glitchy models. Part of finding meaningful parameters is figuring out what constitutes meaningful ranges for them. For example, the parameter &quot;Thickness of the tail at the base&quot; might range from 0 (a minimal tail thickness, like a cow&#39;s) to 1 (a tail as thick as the torso, like a crocodile&#39;s or sauropod&#39;s).&lt;/p&gt;

&lt;p&gt;This ensures that the tail thickness can&#39;t accidentally exceed the torso’s. It also means that changing the torso thickness may affect the tail thickness too. While this technically involves &quot;affecting multiple things at once&quot;, it’s done in a way that’s sensible and meaningful to a human (specifically, me). An automated process can&#39;t know which of these &quot;multiple things at once&quot; relationships feel meaningful or arbitrary.&lt;/p&gt;

&lt;h4&gt;Manual parametrization work&lt;/h4&gt;

&lt;p&gt;Having concluded there was no way around doing a parametrization manually, I began writing a script with high-level parameters, which would produce the values for the low-level parameters (bone alignments and thicknesses) as output.&lt;/p&gt;

&lt;p&gt;I made a copy of all my example creatures, so now I had three rows: The original reference models, the extracted creatures (automatically created based on analyzing the skinned meshes of the references) and the new sculpted creatures that I would try to recreate using high-level parameters.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhweRQDbrL3Ia-804ASZtUgbwxzVn1CtB1qVw7I3hx0gaSkyBwnimdq-chw_nCxm322nX507yJBWwQfeaUZAsgm3l_4OijqwHCMgrw0rGNKDP3hJZNP-VvdIKD15DOufeNf8fV4HKGhyphenhyphenTluJYpNi4X3FBlHd_PMEilfeQpQtd40h2f_-uBSctCSvUWFlm4/s1600/ThreeRows.jpg&quot;&gt;&lt;img alt=&quot;Three rows of creatures.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhweRQDbrL3Ia-804ASZtUgbwxzVn1CtB1qVw7I3hx0gaSkyBwnimdq-chw_nCxm322nX507yJBWwQfeaUZAsgm3l_4OijqwHCMgrw0rGNKDP3hJZNP-VvdIKD15DOufeNf8fV4HKGhyphenhyphenTluJYpNi4X3FBlHd_PMEilfeQpQtd40h2f_-uBSctCSvUWFlm4/s1600/ThreeRows.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;Initially, the high-level parameters controlled only the torso thickness (both horizontal and vertical) and tapering, while the other features remained as defined by the extracted creatures. Gradually, I expanded the functionality of the high-level parameters, ensuring that the results didn&#39;t deviate too much from the extracted models – unless they were closer matches to the reference models.&lt;/p&gt;

&lt;p&gt;Why keep the extracted models around at all instead of directly comparing with the original reference models? Well, I was still working with only extruded rectangles, and there&#39;s only so much detail that approach can capture compared to the high-definition reference models. The extracted models provided a realistic target to aim for, at least for the time being.&lt;/p&gt;

&lt;p&gt;From there, my methodology for moving towards more high-level parameters was, and still is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gradually identify correlations between parameters across the example creatures, and encode those into the generation code. The goal is to reduce the number of parameters by combining multiple lower-level parameters into fewer higher-level ones, all while ensuring that all the example creatures can still be generated using these higher-level parameters.&lt;/li&gt;
&lt;li&gt;As the parameters get fewer and more high-level, it becomes easier to add more example creatures, which provides more data for further study of correlations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;i&gt;I repeat these steps as long as rolling random parameter values still doesn&#39;t produce sensible results.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Here&#39;s a messy work in progress:&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240830_CreaturesWIP.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;To help me spot correlations between parameters, I wrote a tool that visualizes the correlation coefficients between all pairs of parameters, and shows the raw data in the corner when hovering the cursor over a specific pair. (In this video, the tool did not yet display all parameter types, so a lot of parameters are missing.)&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240906_CorrelationTool.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h4&gt;Focus on joint placement within the body&lt;/h4&gt;

&lt;p&gt;In 2024, most of my focus on parametrization revolved around the sensible placement of joints within creatures. For instance, in all creatures with knees, the knee joint is positioned closer to the front of the leg than the back. While the knee placement was fairly straightforward, determining the placement of hip, shoulder, and neck joints across creatures with vastly different proportions proved significantly more challenging.&lt;/p&gt;

&lt;p&gt;Many of my reference 3D models looked sensible externally, but had questionable and inconsistent rigging (placement of joints) from an anatomical perspective.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiHHFFMVDAj-nKwCE9gLGD5qtVeftDIM4_4mounqUEpOIvCur-VVtLHo5gpzuMcVxPLl4q9iB_ZBy096YLLVwmulfcLpBANdm0t65Cy_jjpD9OquDcVfa-BjuIL_fnnAWvDvlUfr14p13K3oo4dxRl90tw_HTqSw-y_mJZSTQPc9RJelaE3dVadkogOPw/s1600/CatModelBadAnatomy.jpg&quot;&gt;&lt;img alt=&quot;Comparison of anatomy of cat 3D model with anatomical picture of a cat&#39;s skeleton.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiHHFFMVDAj-nKwCE9gLGD5qtVeftDIM4_4mounqUEpOIvCur-VVtLHo5gpzuMcVxPLl4q9iB_ZBy096YLLVwmulfcLpBANdm0t65Cy_jjpD9OquDcVfa-BjuIL_fnnAWvDvlUfr14p13K3oo4dxRl90tw_HTqSw-y_mJZSTQPc9RJelaE3dVadkogOPw/s1600/CatModelBadAnatomy.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;Anatomical reference images of bones and joints in various animals were also frequently inconsistent. I could find detailed references from multiple angles for dogs, cats and horses, but not much else. For instance, depictions of crocodile anatomy varied greatly: Some showed the spine in the neck centered, while others placed it near the back of the neck.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHx_buil4q3UP8IqXG76qtqzp7Hwc5hBQJ5vjL9GCoDQDWMDxwHcbPmN8rs-UVH3uklTzsoskDDNJ85y_VGv-vHxfkjDKpbBsYKn5FDDgB0hPzaZxlhRPCbm-gdBC3NyGEy_LFX3iuT-pBEWN55BSVHCppkV13MUIor4fFan0j_YSXwhOyPptvT7S4vMo/s1600/CrocodileComparison.jpg&quot;&gt;&lt;img alt=&quot;Comparison of four different reference images showing the skeleton within a silhouette of a crocodile. The spine in the neck is inconsistent across them.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHx_buil4q3UP8IqXG76qtqzp7Hwc5hBQJ5vjL9GCoDQDWMDxwHcbPmN8rs-UVH3uklTzsoskDDNJ85y_VGv-vHxfkjDKpbBsYKn5FDDgB0hPzaZxlhRPCbm-gdBC3NyGEy_LFX3iuT-pBEWN55BSVHCppkV13MUIor4fFan0j_YSXwhOyPptvT7S4vMo/s1600/CrocodileComparison.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;All of this uncertainty meant I was constantly second-guessing joint placement – both when contemplating how the procedural generation should work and when adding new example creatures. I wanted to solve this one and for all, so I could stop worrying about it.&lt;/p&gt;

&lt;p&gt;Solving the joint placement would also simplify the process of adding additional example creatures, since I could just focus on making them look right &quot;from the outside&quot; without worrying about joints placement. Eventually, I did largely solve it. By this point, I had established 106 high-level parameters that controled all the 503 low-level parameters.&lt;/p&gt;

&lt;h4&gt;Speeding up creation of additional example creatures&lt;/h4&gt;

&lt;p&gt;Once joint placement was mostly automated, I come up with the idea of accelerating the creation of example creatures using Gradient Descent (&lt;a href=&quot;https://en.wikipedia.org/wiki/Gradient_descent&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;). My goal was to implement a Gradient Descent-based tool that could automatically adjust creature parameters to make the creature match the shape of a reference 3D model.&lt;/p&gt;

&lt;p&gt;To my surprise, the approach actually worked. In the video below, the tool I created adjusts the 106 parameters of a creature to align its shape with the silhouettes of a giraffe:&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240913_GradientDescent.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The tool works by capturing silhouettes from multiple angles of the reference model (once) and of the procedural model (at each step of the iterative Gradient Descent process). It calculates how different the procedural silhouettes are from the reference silhouettes, using this difference as the penalty function for the Gradient Descent.&lt;/p&gt;

&lt;p&gt;To measure the difference between two silhouettes, the method creates a &lt;a href=&quot;https://catlikecoding.com/sdf-toolkit/docs/texture-generator/&quot; target=&quot;_blank&quot;&gt;Signed Distance Field&lt;/a&gt; (SDF) from both silhouettes being compared. To speed up the process, I made my SDF-generator of choice Burst-compatible (&lt;a href=&quot;https://gist.github.com/runevision/af22b9ea8dc5a9b432aa9af4924bc6c4&quot; target=&quot;_blank&quot;&gt;available here&lt;/a&gt;). For each pixel near the silhouette border (pixels with distance values close to zero) the process retrieves the corresponding pixel&#39;s distance value from the other SDF to determine how far away the other silhouette border is at that point. The penalty function sums these distances across all tested pixels in all silhouette pairs, yielding the overall penalty.&lt;/p&gt;
  
&lt;p&gt;This explains why, in the video, the legs growing are the first feature to change. Increasing the leg lengths reduces the most distance penalties at once. After that, extending the neck length has the greatest impact.&lt;/p&gt;

&lt;p&gt;Notably, the process doesn&#39;t get the ears of the giraffe right. The reference model has both ears and horns, while my generator can&#39;t create horns yet. So the Gradient Descent process, which aims to match the silhouettes as closely as possible, made the ears large and round so they effectively serve double duty as both ears and horns. I later worked around this by hiding the horns of the reference model.&lt;/p&gt;

&lt;p&gt;I also experimented with a standard optimization method called the &quot;Adam&quot; optimizer, but the &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/113126701540691172&quot; target=&quot;_blank&quot;&gt;results were not good&lt;/a&gt;. Ultimately, the automated process wasn&#39;t perfect, but it complemented my manual tweaks to speed up the creation of example creatures to some extent.&lt;/p&gt;

&lt;p&gt;By this point, I had spent three months in 2024 working on procedural creature generation and had developed eleven example creatures covering a variety of shapes. I eventually scrapped the &quot;extracted creatures&quot; because the combination of high-level parametrization and Gradient Descent tooling made them unnecessary as an intermediate step.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil-DDtRbH5oQ2oZKLeSpvLDuHSCFERINs6b2a1jo7zgNywAdWgtneTzY0jOE_dqml8HEeadJjyr9gKvu1JvOsGF5dEfCa8BHOa5NiP1gERJY8Fin7Yze6ExclRWaYLiBRx1Ve0p2j7bicYBIZ-UaBODF0ZUjONTfUG8j1525quhfkbWJ8haZIS5Oigw3w/s1600/ElevenCreatures.jpg&quot;&gt;&lt;img alt=&quot;Eleven creatures.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil-DDtRbH5oQ2oZKLeSpvLDuHSCFERINs6b2a1jo7zgNywAdWgtneTzY0jOE_dqml8HEeadJjyr9gKvu1JvOsGF5dEfCa8BHOa5NiP1gERJY8Fin7Yze6ExclRWaYLiBRx1Ve0p2j7bicYBIZ-UaBODF0ZUjONTfUG8j1525quhfkbWJ8haZIS5Oigw3w/s1600/ElevenCreatures.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;However, I was not even close to a sufficient high-level parametrization yet. Feeling the need for a change of pace, I decided to shift my focus to the procedural animation of the creatures.&lt;/p&gt;

&lt;h3&gt;Intermission&lt;/h3&gt;

&lt;p&gt;As I was writing this, I realized that while I’m convinced I haven’t yet achieved the goal of ensuring that &quot;any random values for the parameters will always create valid creatures&quot;, I hadn’t actually put it to the test. So, I quickly wrote a script to assign random values to all the high-level parameters. These are the results:&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20250110_RandomCreatures_2024.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;While a few of the results look cool, most are not close to meeting my standards, as I expected. Still, this randomizer could prove useful going forward. It might help me identify which aspects of the generation are still insufficient and why, guiding my further refinement of the procedural generation.&lt;/p&gt;

&lt;p&gt;Anyway, back to what happened in 2024.&lt;/p&gt;

&lt;h3&gt;Procedural animation of creatures&lt;/h3&gt;

&lt;p&gt;When it comes to procedural animation, I have the advantage that I wrote my Master&#39;s Thesis in 2009 about &lt;a href=&quot;https://runevision.com/tech/locomotion/&quot; target=&quot;_blank&quot;&gt;Automated Semi-Procedural Animation for Character Locomotion&lt;/a&gt;, accompanied by an implementation called the &lt;i&gt;Locomotion System&lt;/i&gt;. That was based on modifying hand-crafted animations to adapt to arbitrary paths and uneven terrain.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/v2q5kuic6HA?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Even before that, I implemented fully procedural (pre-rendered) animations as far back as in 2002 when I was 18.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/EehHVXjf1Sk?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;In the summer of 2022, I tried to essentially recreate that, but this time in real-time and interactive. As a starting point, I used my 2009 Locomotion System, stripping out the parts related to traditional animation clips. Instead, I programmed the feet to simply move along basic arcs from one footstep position to the next. To test it, I manually created some programmer-art &quot;creatures&quot; with various leg configurations.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20220817_CreatureAnimationMontage.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;In 2024, I resumed this work, now applying it to my procedurally generated creature models.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241024_DogWalkingStiff.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The result looked somewhat nice but were rather stiff, and the approach only works for taking small steps. As I&#39;ve touched on before, animating procedural, mammal-like creatures to look natural is a tough challenge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quadruped mammals like cats, dogs, and horses move their limbs in more complex ways. Or at least, we&#39;re so familiar with their movements that any inaccuracies makes the movements look weird to us.&lt;/li&gt;
&lt;li&gt;Fast gaits, such as galloping, are more complicated than walking.&lt;/li&gt;
&lt;li&gt;The animation must control not only the legs, but also the spine, tail, neck, etc.&lt;/li&gt;
&lt;li&gt;Since the creatures are generated at runtime, the animation must work out of the box &lt;i&gt;without any manual tweaks&lt;/i&gt; for individual creatures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That&#39;s a tall order even with my experience, but hey, I like a good challenge.&lt;/p&gt;

&lt;p&gt;My approach to procedural animation is purely kinematic, relying on forward kinematics (FK) and inverse kinematics (IK). This means I write code to directly control the motion of bodies and limbs without considering the forces that drive their movement. In other words, there’s no physics simulation involved and no training or evolutionary algorithms (&lt;a href=&quot;https://www.youtube.com/watch?v=pgaEE27nsQw&quot; target=&quot;_blank&quot;&gt;like this one&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A training-based approach isn&#39;t viable for creatures generated at runtime, and frankly, I have no interest in pursuing it. The only way the animation interacts with the game engine’s physics system is by using ray casts to determine where footsteps should be placed on the ground.&lt;/p&gt;

&lt;h4&gt;Hilarity ensues&lt;/h4&gt;

&lt;p&gt;As an aside, one of the fun parts of working on procedural animation is that works in progress often look &lt;i&gt;goofy&lt;/i&gt;. When I first applied the procedural animation to my procedurally generated creatures, I was impatient and ran it before implementing an interface to specify the timing of the different legs relative to each other. As I wrote on social media, &lt;i&gt;&quot;It might be hard to believe, but this animation is actually 100% procedural.&quot;&lt;/i&gt;&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241024_JumpingDog.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The system itself already supported leg timing, as it was inherited from the Locomotion System, where timing was automatically set based on analyzing animation clips. However, in the modified fully procedural version, I hadn&#39;t yet implemented a way to manually input the timing data. Once I did, things looked a lot more sensible, as shown in the previous video.&lt;/p&gt;

&lt;p&gt;Other people&#39;s comments about the absurd animations sometimes inspire me to create more silly animations, just for fun. &lt;i&gt;&quot;Somebody commented that the procedural spider and the procedural dog are destined to fight, but actually they are friends, they are best pals and like to go on adventures together.&quot;&lt;/i&gt;&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241025_SpiderAndDog.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Around this time, I wanted to better evaluate my procedural animation by directly comparing it to hand-crafted animation. To do this, I applied the procedural animation to 3D models I had purchased from the Asset Store, comparing it to the included animation clips that came with those models.&lt;/p&gt;

&lt;p&gt;Continuing the theme of goofiness, my first attempt at this comparison had a bug so hilariously absurd that it became my most viral post ever on &lt;a href=&quot;https://x.com/runevision/status/1857823929575870911&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://bsky.app/profile/runevision.bsky.social/post/3lb3cikpmzs2n&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt; and &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/113493586274443116&quot; target=&quot;_blank&quot;&gt;Mastodon&lt;/a&gt;. (The added music adds a lot to this one, so consider playing with sound on!)&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/VxjwzIJghGs?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;People would inevitably suggest, and sometimes even plead, that I bring this absurd silliness into the game I’m making, for fun and profit. While I understand the sentiment, the reality is that my vision for &lt;i&gt;The Big Forest&lt;/i&gt; is not that kind of game. There&#39;s definitely room for some light-hearted moments, but that’s not the primary focus. For reference, think of a Ghibli movie – there’s a certain kind of silliness that would fit well there, but it would need to align with the overall tone.&lt;/p&gt;

&lt;h4&gt;Incremental progress and study&lt;/h4&gt;

&lt;p&gt;I started studying my procedural animation alongside the handcrafted animations to better understand the subtle but important differences. Here&#39;s the comparison tool I made again, this time without the hilarious bug.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241118_AnimalComparisonFixed.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Even without the bug, it still looks very rough. At higher speeds, it becomes clear that the approach of simply moving the feet from one footstep position to the next doesn&#39;t work.&lt;/p&gt;

&lt;p&gt;In real life (and in the reference animations), at high speeds like galloping, the feet don&#39;t stay in contact with the ground for most of their backward trajectories. They only touch the ground for short durations. My procedural animation didn&#39;t account for this yet. Instead, the hips got pulled down to be within distance of the feet, and that&#39;s what caused the torsos of the procedurally animated creatures to drag along the ground.&lt;/p&gt;

&lt;p&gt;Once I tried to account for this, things improved slightly – at least in that the torsos no longer dragged along the ground.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241121_AnimationComparisonStepImprovement.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;To better make informed decisions about how far up the feet should lift, how much time they should spend touching the ground, and similar animation aspects, I developed a tool to plot various properties of the reference animations. For example, the plot below shows that as the stride distance (relative to the length of the leg) increases, the proportion of time the foot is in the air also increases. The white dotted curve represents my own equation that I attempted to fit to the data.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4hvpC9gl4OG7oNotQKC-A9m9aC2VKJgrcFHWrlG4xKW3UX7rbg5u7NrKIc9oIsZUk4AOy4z-Aomd5lfhBZ1LaT7get4i4uRpuozYud-gaG_sqf-iuSth3sodXos-ZHpGiFhYnBsaxdiBf9XJMILPYPiWbbnFSeSRl6k6MAHwoZQpXNpq726Ccz8s5oaU/s1600/FlightDurationNorm.jpg&quot;&gt;&lt;img alt=&quot;A scatter plot with colored dots and a white curve approximating them.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4hvpC9gl4OG7oNotQKC-A9m9aC2VKJgrcFHWrlG4xKW3UX7rbg5u7NrKIc9oIsZUk4AOy4z-Aomd5lfhBZ1LaT7get4i4uRpuozYud-gaG_sqf-iuSth3sodXos-ZHpGiFhYnBsaxdiBf9XJMILPYPiWbbnFSeSRl6k6MAHwoZQpXNpq726Ccz8s5oaU/s1600/FlightDurationNorm.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;Below is another plot that shows the signed horizontal distance between the hip and the foot (actually, the &lt;i&gt;footstep position&lt;/i&gt;) along the horizontal axis, and the foot&#39;s lift on the vertical axis. In the center, where the foot is directly below the hip, the lift is generally zero. Notably, the plot includes data from gaits at different speeds (walking, trotting, galloping), but the distance at which the foot lifts off the ground is fairly consistent across those speeds. So while higher speeds are associated with longer step lengths, the &quot;distance&quot; (relative to the creature) that a foot is in contact with the ground is not proportional to the step length. Instead, it it&#39;s closer to a constant value, relative to the leg length.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiCdRVah6blNHFm0e2R4B1a1qZlgD6rxOGKhHlc8xDcvKhwyjb724g5QyUNA3mAWwgExZ7qyTrBl7zp5U8jXfOl1Ld7Sg0P0DlXqFKJ41RCl8gG_9Wj4Xhw7fMChuDEB506QycOBehUge4_mS0nwp46W_fMw77ju_7nJyhL03e4DdC_F3tQ6tmLASroAk/s1600/DistanceLift.jpg&quot; &gt;&lt;img alt=&quot;A scatter plot with colored dots and a white curve approximating them.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiCdRVah6blNHFm0e2R4B1a1qZlgD6rxOGKhHlc8xDcvKhwyjb724g5QyUNA3mAWwgExZ7qyTrBl7zp5U8jXfOl1Ld7Sg0P0DlXqFKJ41RCl8gG_9Wj4Xhw7fMChuDEB506QycOBehUge4_mS0nwp46W_fMw77ju_7nJyhL03e4DdC_F3tQ6tmLASroAk/s1600/DistanceLift.jpg&quot;/&gt;&lt;/a&gt;

&lt;p&gt;I made many plots with this tool, visualizing data from the reference animations in all kinds of ways. Some of the plots revealed clear trends, like the two above. Others resulted in a jumble of unrelated curves or dots that I couldn&#39;t use for anything. In this way, my process was (and is) very much a classic research approach: Formulating hypotheses, testing them, discarding those that don&#39;t pan out, and building upon the ones that do.&lt;/p&gt;

&lt;h4&gt;Inverse kinematics overhaul&lt;/h4&gt;

&lt;p&gt;I had noticed that many animals kind of bend or curl their feet – and sometimes the entire lower part of their front legs – when lifting them. However, my procedural animation didn&#39;t capture this behavior at all. I could hack around this by dynamically adjusting the foot rotations over the walk cycle, but it often resulted in unnatural poses.&lt;/p&gt;

&lt;p&gt;Eventually, I concluded that I needed to revamp the inverse kinematics (IK) algorithm I was using, with focus on better handling foot roll and bending scenarios. My old Locomotion System employed a two-pass IK approach, where the foot rotation was given as input to the first IK pass. Based on the orientation of the lower leg found by the IK, the foot rotation would be adjusted – rotated around either the heel or toe – to ensure a more natural ankle angle, followed by a second IK pass to make the leg match the new ankle position. This two-pass approach worked all right for the Locomotion System, which was applied on top of hand-crafted animation. However, I found it insufficient for the fully procedural animation I was working on now.&lt;/p&gt;

&lt;p&gt;In principle, this two-pass approach could be changed to run iteratively, rather than just twice. However, this would be computationally expensive, since the IK algorithm itself is already iterative. Instead, I implemented a new IK algorithm where the foot rotation is not a static input, but is controlled by the IK itself.&lt;/p&gt;

&lt;p&gt;Having the IK handle the foot rotation is a bit tricky, as it must behave quite differently depending on how much weight is on the foot, ranging from none to full weight.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241213_IKHuman_SomeSnapping.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;I made significant progress with this approach, although there’s a tricky issue: There are edge cases where multiple solutions can satisfy the given constraints. This makes the leg poses, which are state-less, sometimes snap from one configuration to another based on even tiny changes in the input positions. I have some ideas on how to address this, but I haven&#39;t tested them yet.&lt;/p&gt;

&lt;p&gt;After incorporating the new IK system and adding logic to make the feet bend when lifted, my results looked like this at the end of 2024:&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241219_AnimationComparisonIKImprovements.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;While it&#39;s still a bit glitchy and far from perfect, the bending of the feet and legs is at least a step in the right direction.&lt;/p&gt;

&lt;h3&gt;And that&#39;s how far I got so far&lt;/h3&gt;

&lt;p&gt;Both the procedural model generation and the procedural animation still have a long way to go, after spending around three months on each, and that can feel a bit demotivating. On the other hand, I&#39;ve been making steady progress, even if it&#39;s slow. Writing this post has actually helped me realize just how much I&#39;ve accomplished so far after all.&lt;/p&gt;

&lt;p&gt;That said, I feel it&#39;s time for a break from the creatures. When I return to them later, I&#39;ll hopefully do so with renewed energy.&lt;/p&gt;

&lt;p&gt;I wish I could have wrapped up this post with a satisfying milestone or a neat conclusion, but there was already so much to cover, and I didn&#39;t want to delay this write-up any further. I also think there&#39;s value in showing the messiness of creative processes and research. Let&#39;s see where I&#39;m at when I write about the procedural creatures next time!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/4949056993255103046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/4949056993255103046' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4949056993255103046'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4949056993255103046'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2025/01/procedural-creature-progress-2021-2024.html' title='Procedural creature progress 2021 - 2024'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1UPpJ75QM7Xwsrvo0xIj0kez8I_P2AndgRJm0Ni5X-OIakCbGmOtmxB41rRByO6-ZueTWCjluFsRdukGS3pdEWYchfh1vtFMrqimIXPbYFQDDlg93HyHwR1pWhjksvCQO4qqGT1ER6MZ-dmB75ojV2dmvV7EyMD67dwZ-wE8LiweSFgELjVkt0tc7Nrk/s72-c/CreaturesGoal.jpg" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-5237592921176380673</id><published>2025-01-05T17:00:00.013+01:00</published><updated>2025-09-18T16:25:34.795+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>2024 retrospective</title><content type='html'>&lt;p&gt;Another year went by as an indie game developer and what do I have to show for it?&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://blog.runevision.com/2024/01/2023-retrospective-and-goals-for-new.html&quot; target=&quot;_blank&quot;&gt;last year&#39;s retrospective&lt;/a&gt; I wrote that apart from working on my game The Big Forest in general, I had four concrete goals for 2024:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Present my Fractal Dithering technique
&lt;/li&gt;&lt;li&gt;Release my Layer-Based ProcGen for Infinite Worlds framework as open source
&lt;/li&gt;&lt;li&gt;Wrap up and release The Cluster as a free experimental game
&lt;/li&gt;&lt;li&gt;Make better use of my YouTube channel
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I ended up doing only two of those, but it was the two most important ones to me, so I&#39;m feeling all right with that.&lt;/p&gt;

&lt;h3&gt;Release of LayerProcGen as open source&lt;/h3&gt;

&lt;p&gt;I released my &lt;a href=&quot;https://runevision.com/tech/layerprocgen/&quot; target=&quot;_blank&quot;&gt;LayerProcGen framework&lt;/a&gt; as open source in May 2024. LayerProcGen is a framework that can be used to implement layer-based procedural generation that&#39;s infinite, deterministic and contextual.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/tech/layerprocgen/_pageshot.jpg&quot;&gt;

&lt;p&gt;I wrote &lt;a href=&quot;https://runevision.github.io/LayerProcGen/&quot; target=&quot;_blank&quot;&gt;extensive documentation&lt;/a&gt; describing not only the specifics of how to use it, but also the overarching ideas and principles it&#39;s based on. I also did &lt;a href=&quot;https://www.youtube.com/watch?v=4oJGkx0K8UQ&quot; target=&quot;_blank&quot;&gt;a talk at Everything Procedural Conference&lt;/a&gt; about it, which was well received.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/4oJGkx0K8UQ?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I&#39;m unsure how many people are using the framework directly for their games, but I know of several who&#39;ve been inspired by its underlying ideas and made their own implementations.&lt;/p&gt;

&lt;p&gt;Sythelux Rikd &lt;a href=&quot;https://github.com/Sythelux/LayerProcGen&quot; target=&quot;_blank&quot;&gt;ported LayerProcGen to Godot&lt;/a&gt;. The core framework worked in Godot out of the box, but Sythelux ported various of its Unity-dependent optional utilities and made example scenes for Godot. Oli Scherer created &lt;a href=&quot;https://crates.io/crates/layer-proc-gen&quot; target=&quot;_blank&quot;&gt;a Rust implementation of LayerProcgen&lt;/a&gt; with some slightly different architectural choices. For his game &quot;Around The World&quot; Thomas ten Cate aka Frozen Fractal &lt;a href=&quot;https://frozenfractal.com/blog/2024/12/25/around-the-world-20-two-steps-forward-one-step-back/&quot; target=&quot;_blank&quot;&gt;wrote his own implementation&lt;/a&gt; that works on a sphere.&lt;/p&gt;

&lt;p&gt;Overall I feel like LayerProcGen has made at least a little dent in the procedural generation community, and I&#39;m happy to have been able to make such a contribution.&lt;/p&gt;

&lt;h3&gt;Release of The Cluster as a free experimental game&lt;/h3&gt;

&lt;p&gt;I finally wrapped up and released &lt;a href=&quot;https://runevision.com/multimedia/thecluster/&quot; target=&quot;_blank&quot;&gt;The Cluster&lt;/a&gt;, a game I&#39;d been working on on-and-off since 2003! I already &lt;a href=&quot;https://blog.runevision.com/2024/08/the-cluster-is-now-released.html&quot; target=&quot;_blank&quot;&gt;wrote about it here&lt;/a&gt;, so no need to repeat myself further, but despite not having much of an impact on anything, I&#39;m personally happy to at long last have this &quot;unfinished business&quot; out of the way.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/IEoBuw9PyBU?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;h3&gt;Stuff I didn&#39;t get to do&lt;/h3&gt;

&lt;p&gt;I didn&#39;t get around to presenting and releasing my &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/110508837173343595&quot; target=&quot;_blank&quot;&gt;Fractal Dithering&lt;/a&gt; technique. Hopefully this year!&lt;/p&gt;

&lt;p&gt;Update January 2025: &lt;a href=&quot;https://runevision.com/tech/dither3d/&quot; target=&quot;_blank&quot;&gt;I got it done&lt;/a&gt; less than a month after writing this blog post, yay!&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20230608_DitheringImprovedMultipleScenes.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;I also never made more &quot;proper&quot; YouTube videos after &lt;a href=&quot;https://www.youtube.com/watch?v=VxMwggFQRQM&quot; target=&quot;_blank&quot;&gt;the one in January 2024 about the terrain generation&lt;/a&gt;. I considered doing one about LayerProcGen, but there&#39;s already &lt;a href=&quot;https://www.youtube.com/watch?v=4oJGkx0K8UQ&quot; target=&quot;_blank&quot;&gt;the video of my conference talk about it&lt;/a&gt;. I could probably explain the framework and ideas slightly better by creating a video with nice animated graphics and diagrams, but it would be a lot of work for marginal added utility. I also considered doing one about all the interesting tech in The Cluster, but I didn&#39;t feel like diverting more of my time to that game over working on my current game. Why no new videos about my current game The Big Forest then? Well, read on...&lt;/p&gt;

&lt;h3&gt;Progress on The Big Forest&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://runevision.com/multimedia/thebigforest/&quot; target=&quot;_blank&quot;&gt;The Big Forest&lt;/a&gt; is the game I&#39;m currently working on, and it&#39;s &lt;i&gt;still&lt;/i&gt; in its early stages, just like I said last year. The game will be fully procedurally generated, and so far I&#39;ve been working on a series of disconnected experiments and proofs of concept that will eventually all be rolled into the game. These include procedural generation of terrain, gameplay progression, creatures and music.&lt;/p&gt;

&lt;p&gt;I had worked on the terrain generation in 2023, and I continued this work in the first few months of 2024.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Previously the paths in the terrain had simply gone from one chunk corner to the diagonally opposite one. I now generated points of interest (with towers for now) and &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/111965140413339798&quot; target=&quot;_blank&quot;&gt;made the paths connect those&lt;/a&gt;, although it&#39;s &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/111969850551720188&quot; target=&quot;_blank&quot;&gt;not yet completely robust&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I managed to radically &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/112020015968986511&quot; target=&quot;_blank&quot;&gt;speed up the generation&lt;/a&gt; by making use of Unity&#39;s Burst compiler (without Unity Jobs, which are not a good fit). I&#39;m very happy with that. For fun, I made a video where I had &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/112048859440623368&quot; target=&quot;_blank&quot;&gt;drastically increased the player&#39;s speed&lt;/a&gt;, like they&#39;re some kind of fast hedgehog.&lt;/li&gt;
&lt;li&gt;I changed the terrain chunk implementation to &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/112060197698774248&quot; target=&quot;_blank&quot;&gt;use chunks of different sizes&lt;/a&gt;, with larger chunks of lower resolution further away from the player. This made it possible to expand the draw distance greatly without slowing the generation down.&lt;/li&gt;
&lt;li&gt;Using chunks of different resolutions introduced cracks in the terrain, so I &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/112111082855710507&quot; target=&quot;_blank&quot;&gt;implemented a skirt solution&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240306_Sonic.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;On the subject of YouTube videos though, I&#39;m not sure I could make an interesting video of the 2024 terrain progress mentioned above, and there&#39;s plenty of other videos out there that cover very similar ground.&lt;/p&gt;
  
&lt;p&gt;After this I kind of needed progress with other aspects of the game before it made sense to focus more on the terrain. After taking a break to wrap up and release LayerProcGen and The Cluster, I returned to The Big Forest to work on its procedural creatures.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20240830_CreaturesWIP.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;I spend the latter half of 2024 working on that - three months on creature model generation and three months on procedural animation. I was writing a whole section about that here, but it got so long that I&#39;ve written &lt;a href=&quot;https://blog.runevision.com/2025/01/procedural-creature-progress-2021-2024.html&quot; target=&quot;_blank&quot;&gt;a whole separate post about the procedural creatures&lt;/a&gt; instead. Long story short though, I had some progress but it&#39;s still very far from where it needs to be.&lt;/p&gt;

&lt;p&gt;The fact that it&#39;s still well short of &lt;i&gt;being any good&lt;/i&gt; means I don&#39;t consider it good material for a YouTube video either, as I think such videos work best when they can conclude in a satisfying wrap-up of &lt;i&gt;something&lt;/i&gt;. I did write the blog post though, and now I need a bit of a break before I resume working on the creatures again.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20241024_DogWalkingStiff.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Oh right, a video of a bug in the procedural animation I was working on became my most viral post ever on &lt;a href=&quot;https://x.com/runevision/status/1857823929575870911&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://bsky.app/profile/runevision.bsky.social/post/3lb3cikpmzs2n&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt; and &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/113493586274443116&quot; target=&quot;_blank&quot;&gt;Mastodon&lt;/a&gt;. (The creatures in this video are not procedurally generated; I was testing the procedural animation on purchased animal models for research purposes.)&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/VxjwzIJghGs?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;h3&gt;Other tidbits&lt;/h3&gt;

&lt;p&gt;I can take no credit for it, but my business partner for the Quest port of Eye of the Temple, &lt;a href=&quot;https://salmi.de/&quot; target=&quot;_blank&quot;&gt;Salmi Games&lt;/a&gt;, released an update for Quest 3 that adds real-time shadows from the torch, higher frame rates (90fps almost everywhere), improved texture resolutions and aniso, and higher clarity due to foveated rendering being mostly disabled. This brings the Quest version (on Quest 3) even closer to the PCVR version. &lt;a href=&quot;https://www.uploadvr.com/eye-of-the-temple-quest-3-upgrade/&quot; target=&quot;_blank&quot;&gt;UploadVR covered it here&lt;/a&gt;.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/7guF_Y7EYDM?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I very occasionally make music, and in 2024 I released two very different tracks. And as a first, these ones even have vocals (by me): &lt;a href=&quot;https://soundcloud.com/rune-skovbo-johansen/just-to-say-goodbye&quot; target=&quot;_blank&quot;&gt;Just to Say Goodbye&lt;/a&gt;, a sad song about an alien with bad timing, and &lt;a href=&quot;https://soundcloud.com/rune-skovbo-johansen/sorte-gryde&quot; target=&quot;_blank&quot;&gt;Sorte Gryde&lt;/a&gt;, a metal re-imagining of an old Danish singing game, with a dash of Saturday-morning cartoon villainy.&lt;/p&gt;

&lt;iframe height=&quot;166&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1893005367&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=true&amp;show_comments=false&amp;show_user=false&amp;show_reposts=false&amp;show_teaser=false&quot;&gt;&lt;/iframe&gt;

&lt;iframe height=&quot;166&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1894621044&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=true&amp;show_comments=false&amp;show_user=false&amp;show_reposts=false&amp;show_teaser=false&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I was briefly mentioned in &lt;a href=&quot;https://www.youtube.com/watch?v=ilnq1ZNmhoM&quot; target=&quot;_blank&quot;&gt;this video about making games feel mysterious&lt;/a&gt; by Mark Brown of Game Maker&#39;s Toolkit due to my 2021 article about &lt;a href=&quot;https://blog.runevision.com/2021/02/designing-for-sense-of-mystery-and.html&quot; target=&quot;_blank&quot;&gt;designing for a sense of mystery and wonder&lt;/a&gt;. Neat!&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/ilnq1ZNmhoM?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;When I was around 11 I would draw &quot;video games&quot; on paper during breaks at school. Not sketches or design docs, but games that were fully playable using your finger to indicate where your avatar is, and following simple rules. Earlier this year &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/113578994527354282&quot; target=&quot;_blank&quot;&gt;I had these games scanned&lt;/a&gt; (42 pages!). I made a &lt;a href=&quot;https://srv2.zoomable.ca/viewer.php?i=img68375edd8b9f287e_SonicIII_Overview&amp;amp;embed=0#zoom=0.71773&amp;amp;x=0.49065&amp;amp;y=0.55222&quot; target=&quot;_blank&quot;&gt;zoomable annotated display of one of the games&lt;/a&gt;. I&#39;d like to do more with the other games too, maybe even make a (digitally) playable game out of the one with 3D perspective dungeons.&lt;/p&gt;

&lt;table class=&#39;imagelist&#39;&gt;&lt;tr&gt;
&lt;td colspan=&quot;3&quot;&gt;&lt;a class=&#39;fancybox&#39; data-fancybox-group=&#39;1&#39; href=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpMjbl2Uts_JpqiyLmfICElmOkREgpoQpK7mEQNHmHnRNh6HU8pMLaEQ8uJoaWZTZ8jA1TfmRzx0lyc10tpXCEcAWjgJUHcRjkEYRWNQ4Df_ZPcQ3F-OpE0ML9cwIp2YKxtVDgIGP-k6JMb3UZ7NhyReLHPFOca7iWo3DZCo8ExqybIoljmbEpOFG8ajU/s1600/dungeon.jpg&#39;&gt;&lt;img src=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpMjbl2Uts_JpqiyLmfICElmOkREgpoQpK7mEQNHmHnRNh6HU8pMLaEQ8uJoaWZTZ8jA1TfmRzx0lyc10tpXCEcAWjgJUHcRjkEYRWNQ4Df_ZPcQ3F-OpE0ML9cwIp2YKxtVDgIGP-k6JMb3UZ7NhyReLHPFOca7iWo3DZCo8ExqybIoljmbEpOFG8ajU/s1600/dungeon.jpg&#39; alt=&quot;A drawing inside a box-like dungeon drawn in perspective where there&#39;s grid-based tiles on the floor and ceiling.&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;&lt;a class=&#39;fancybox&#39; data-fancybox-group=&#39;1&#39; href=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiReIEj7zqLcmhgfWf3JdM2riwvAKgn2BWcqmMi2E0q6J1fg13TObGDytyznPG2uDeor4_867eLOZXjgzewDC8VzlOIvLUWEMqmR05bBXz9D3RncwgAPpkcL3BZ0vZ293FNXTUUipWUHoFr7P7sZmfCsL5yS6B2uXhWKktPsaGMrspO-TTlhMKoCaDQ8Q/s1600/platformer1.jpg&#39;&gt;&lt;img src=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiReIEj7zqLcmhgfWf3JdM2riwvAKgn2BWcqmMi2E0q6J1fg13TObGDytyznPG2uDeor4_867eLOZXjgzewDC8VzlOIvLUWEMqmR05bBXz9D3RncwgAPpkcL3BZ0vZ293FNXTUUipWUHoFr7P7sZmfCsL5yS6B2uXhWKktPsaGMrspO-TTlhMKoCaDQ8Q/s1600/platformer1.jpg&#39; alt=&quot;Grid paper with a platformer level drawn with pencil.&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a class=&#39;fancybox&#39; data-fancybox-group=&#39;1&#39; href=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1MW3KOTfc-QhssxzH2IjaygYM_48I7MyauOAS1Y0wRdjmgZ4FUlfPI7Xm1xJjAfRSprTaGRHVumVvXrrKvS2JDLH2WLegxpAvmuaGzUOms-elathZ78NaY65rBGOOL5sHSSOZxSB2sGudMfAYHIYp0nYDXLLt27NrWdaJLRXluXa4_IVxyz2Lt-nU0aI/s1600/laby.jpg&#39;&gt;&lt;img src=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1MW3KOTfc-QhssxzH2IjaygYM_48I7MyauOAS1Y0wRdjmgZ4FUlfPI7Xm1xJjAfRSprTaGRHVumVvXrrKvS2JDLH2WLegxpAvmuaGzUOms-elathZ78NaY65rBGOOL5sHSSOZxSB2sGudMfAYHIYp0nYDXLLt27NrWdaJLRXluXa4_IVxyz2Lt-nU0aI/s1600/laby.jpg&#39; alt=&quot;A drawing of an isometric maze with various special elements like one-way passages and secret passages.&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a class=&#39;fancybox&#39; data-fancybox-group=&#39;1&#39; href=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGi7QmfQWGfxoGZJm6nf3LK8hcpj4JgIfC4FOLj2pwY2IrZm6GjZ4cUvvoRsx1_kEQq7GaD9xSwPrDOkWpSJxhVMSaE3RTTF-pusnRB-4boE-4sUVrFZPhR6jXGX1sw-tJzcsqwE8lKunHITMFAk4rVcah1SDaNbt5O3N_d0nRttMA6sSzHn-ELVml6uU/s1600/platformer2.jpg&#39;&gt;&lt;img src=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGi7QmfQWGfxoGZJm6nf3LK8hcpj4JgIfC4FOLj2pwY2IrZm6GjZ4cUvvoRsx1_kEQq7GaD9xSwPrDOkWpSJxhVMSaE3RTTF-pusnRB-4boE-4sUVrFZPhR6jXGX1sw-tJzcsqwE8lKunHITMFAk4rVcah1SDaNbt5O3N_d0nRttMA6sSzHn-ELVml6uU/s1600/platformer2.jpg&#39; alt=&quot;A drawing of a platformer level with various cave entrances that are connected pair-wise.&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;h3&gt;Goals for 2025&lt;/h3&gt;

&lt;p&gt;I&#39;ll keep this short.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Develop the creature generation and animation sufficiently to put them into the game. If I&#39;m still not there by 2026, I need to seriously reevaluate some things.&lt;/li&gt;
&lt;li&gt;Make at least one new YouTube video about The Big Forest.&lt;/li&gt;
&lt;li&gt;Present my Fractal Dithering technique.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wish me luck!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/5237592921176380673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/5237592921176380673' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5237592921176380673'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5237592921176380673'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2025/01/2024-retrospective.html' title='2024 retrospective'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpMjbl2Uts_JpqiyLmfICElmOkREgpoQpK7mEQNHmHnRNh6HU8pMLaEQ8uJoaWZTZ8jA1TfmRzx0lyc10tpXCEcAWjgJUHcRjkEYRWNQ4Df_ZPcQ3F-OpE0ML9cwIp2YKxtVDgIGP-k6JMb3UZ7NhyReLHPFOca7iWo3DZCo8ExqybIoljmbEpOFG8ajU/s72-c/dungeon.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-1089164083362341606</id><published>2024-10-02T17:49:00.012+02:00</published><updated>2025-05-15T10:54:14.930+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="article"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="The Big Forest"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>Procedural game progression dependency graphs</title><content type='html'>&lt;p&gt;In 2022 I came up with some new ideas for what kind of game &lt;a href=&quot;https://runevision.com/multimedia/thebigforest/&quot; target=&quot;_blank&quot;&gt;The Big Forest&lt;/a&gt; (working title) could be. During the year, I developed a way to procedurally create dependency graphs and also procedurally create fully playable game levels based on the graphs.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/ProgressionDependencyGraphThumb.png&quot;&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;p&gt;In the video below you can see the prototype I had near the end.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphGarden.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;A dependency graph is a concept in mathematics and computer science which has been independently &quot;discovered&quot; by lots of game developers because it turns out to be pretty central to designing any non-linear game.&lt;/p&gt;
  
&lt;p&gt;At its simplest you can think of locks and keys. A locked door has the corresponding key as a &lt;i&gt;dependency&lt;/i&gt; to be able to progress through the door. But dependencies can also be abilities in a Metroidvania game, quest objectives in an RPG, or required inventory items for a puzzle in a point-and-click adventure.&lt;/p&gt;
  
&lt;p&gt;Here&#39;s a few different articles by others that discuss what they are. Note the lack of standardized terminology. I personally use &quot;game progression dependency graph&quot; since the concept is applicable to all non-linear games, not just puzzles or dungeons.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20230313045524/https://garethrees.org/2004/12/01/ocarina-of-time/&quot; target=&quot;_blank&quot;&gt;The puzzle structure of Ocarina of Time by Gareth Rees&lt;/a&gt; (2004)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://runevision.com/multimedia/cavex/#307&quot; target=&quot;_blank&quot;&gt;Placing locks and keys based on a binary tree by Rune Skovbo Johansen&lt;/a&gt; (2007)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.squidi.net/three/entry.php?id=158&quot; target=&quot;_blank&quot;&gt;PGC: Puzzle Tree mechanic on Squidi.net&lt;/a&gt; (2012)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://grumpygamer.com/puzzle_dependency_charts&quot; target=&quot;_blank&quot;&gt;Puzzle Dependency Charts by Ron Gilbert of Monkey Island fame&lt;/a&gt; (2014)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gamedeveloper.com/design/puzzle-dependency-graph-primer&quot; target=&quot;_blank&quot;&gt;Puzzle Dependency Graph Primer by Joshua Weinberg&lt;/a&gt; (2016)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.patreon.com/posts/how-my-boss-key-13801754&quot; target=&quot;_blank&quot;&gt;Boss Key dungeon graphs by Mark Brown of Game Maker&#39;s Toolkit&lt;/a&gt; (2017)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Dependency_graph&quot; target=&quot;_blank&quot;&gt;Dependency graph Wikipedia article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I posted about my game progression dependency graph tech on social media (Mastodon and Twitter) throughout developing it. But when people ask me about it now, it&#39;s hard to point to posts scattered across a year of social media posts.&lt;/p&gt;

&lt;p&gt;I&#39;ve copied all those posts (nearly verbatim) into this blog post so it&#39;s documented conveniently in one place. For this reason it contains not only the conclusions at a single point in time, but also the questions I asked, my confusion, and my developing understanding of the problem space over time. Each header corresponds to a new thread. Images and videos generally relate to the text above them.&lt;/p&gt;

&lt;p&gt;Let&#39;s start the journey.&lt;/p&gt;

&lt;h3&gt;March 30 2022&lt;/h3&gt;

&lt;p&gt;I&#39;m slowly starting to experiment with novel generated graph structures again, here with an early and rough game progression dependency tree. I&#39;ll need to merge certain locations, turning it into a directed acyclic graph, and later generate a spatial graph based on it.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/Graph.png&quot;&gt;

&lt;p&gt;I must say I find it tricky to work out data structures for this. Which concepts should be nodes and which should be edges? And with both different types of nodes and different types of edges, should those types be represented as class types (inheritance) or just with data?&lt;/p&gt;

&lt;p&gt;I keep having to revise my thinking about which concepts are represented as nodes in the graph and which as connections...&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/Graph.jpg&quot;&gt;

&lt;p&gt;The graph generation now creates a directed acyclic graph rather than a tree structure. It took a long time to get the layout to be nice, avoiding crossed edges when possible and minimizing wasted space.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/Acyclic.png&quot;&gt;

&lt;p&gt;In the replies someone mentioned &lt;a href=&quot;https://github.com/tcoxon/metazelda&quot; target=&quot;_blank&quot;&gt;Metazelda&lt;/a&gt;. It looked familiar so I might have seen it a long time ago. I also did basic &lt;a href=&quot;https://runevision.com/multimedia/cavex/#307&quot; target=&quot;_blank&quot;&gt;lock+keys for my game Cavex&lt;/a&gt; myself back in 2007. (Cavex eventually turned into &lt;a href=&quot;https://runevision.com/multimedia/thecluster/&quot; target=&quot;_blank&quot;&gt;The Cluster&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;The concept I&#39;m working on now takes place in a bit more of an open world where areas are accessible by default and only certain places locked off. The &quot;tunnel/dungeon carving&quot; mindset feels like it might not be as helpful in this context, but I&#39;m still figuring things out.&lt;/p&gt;

&lt;h3&gt;April 6 2022&lt;/h3&gt;

&lt;p&gt;If I have to spend a lot of time looking at these generated game progression dependency graphs, I might as well make them nice to look at.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/AnimatedGraphs.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;I revised my thinking on the nodes again and added a &quot;location&quot; requirement to almost all the node types. On the first try, the resulting graph had multiple new neat ways of bending the connections, without me having changed the layout function at all. Robust algorithm I guess. :)&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/NewConnections.png&quot;&gt;

&lt;p&gt;Unfortunately it doesn&#39;t seem as robust in avoiding crossed edges anymore.&lt;/p&gt;

&lt;p&gt;Hmmmmmmmm&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphWIP.png&quot;&gt;

&lt;p&gt;First glimpse of an idea to generate a dependency graph and a spatial graph simultaneously from the same underlying data structure.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/DualGraph.png&quot;&gt;

&lt;p&gt;Really, no need for distant parts of the spatial graph to repel each other quite so much. This can make the graph more curvy, more interesting looking, and more compact at the same time.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/DependencyAndSpatialGraphs.png&quot;&gt;

&lt;h3&gt;April 10 2022&lt;/h3&gt;

&lt;p&gt;Left: Game progression dependency graphs.&lt;br/&gt;
Right: Spatial graphs that could be the basis of where things are located in the world.&lt;/p&gt;

&lt;p&gt;A key for a locked gate is a direct dependency, but can be located far away spatially.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/DualGraphs.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Some people may be reminded of &lt;a href=&quot;https://www.squidi.net/three/c_procedural.php&quot; target=&quot;_blank&quot;&gt;articles on squidi.net&lt;/a&gt; about procedural generation, which discuss how you could generate an entire game using these principles. It’s a classic resource, and those articles cover a lot of ground, some of which one will inevitably hit when trying to do procedural progression (as this article on puzzle trees also states). Light on implementation details but great food for thought.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/PuzzleTreesQuote.jpg&quot;&gt;

&lt;p&gt;I&#39;m going towards an approach of generating the structures by incrementally injecting new dependencies anywhere rather than a simple recursive top-down approach. And I decided to generate both graphs simultaneously rather than as consecutive passes.&lt;/p&gt;

&lt;p&gt;These two things combined should hopefully make it possible to inform new dependency injections both on what would be a good spot dependency-wise and a good spot spatially. That&#39;s the next thing I&#39;ll focus on.

&lt;p&gt;The game progression dependency graph and spatial graph visualizations now support changing the data structure on the fly.
This makes it possible to see the node injections as they happen, and exactly how they modify the graph. Alas the jiggles had to go.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/IncrementalInjection.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;I found out I can create more balanced game progression dependency graphs by switching to an approach I call ... (checks notes)&lt;/p&gt;

&lt;p&gt;Exploding The Graph, Then Picking Up The Pieces.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/ExplodingGraph.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The approach so far is powerful in the theoretical possibility space of graphs it &lt;i&gt;can&lt;/i&gt; create, but it tends to  only open up one new location at a time, stifling player choice. I&#39;m struggling to find a way for the generation to embody the &lt;a href=&quot;https://web.archive.org/web/20230313045524/https://garethrees.org/2004/12/01/ocarina-of-time/&quot; target=&quot;_blank&quot;&gt;&quot;just right&quot; shapes described by Gareth Rees&lt;/a&gt;.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/WellBalanced.png&quot;&gt;

&lt;p&gt;The problem definitely relates to the branching factor, though whether to focus on in-going or out-going edges or both is unclear. The question is then how to construct a DAG with one start node, one end node and &lt;i&gt;n&lt;/i&gt; in-between nodes with a given desired branching factor.&lt;/p&gt;

&lt;h3&gt;April 18 2022&lt;/h3&gt;

&lt;p&gt;I guess I&#39;m getting closer to something I might be able to use: Dividing n nodes into m columns and then connecting them. But I&#39;m not entirely happy with how specific/hardcoded/restrictive this approach is. For example, this will never create connections that skip rows.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/LocationBalance.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;By the way, the graphs here are at a different abstraction level than the previous graphs I&#39;ve shown. Here, only location nodes are considered. All the other node types can be injected and connected later in a way that respects the same dependencies.&lt;/p&gt;

&lt;p&gt;After sleeping on it I came up with a much better approach that creates more random and organic graphs, and always ensures ingoing and outgoing edges are either 1 or 2. Just looking at these results makes me much happier than the results in the previous video.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/LocationBalance2.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The new approach is based on a simple graph rewrite rule I keep applying on random edges until the desired number of nodes is reached.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphRewriteRule.png&quot;&gt;

&lt;p&gt;I may have been inspired by a chapter in Dormans Joris&#39; thesis &lt;a href=&quot;https://eprints.illc.uva.nl/id/eprint/2118/1/DS-2012-12.text.pdf&quot; target=&quot;_blank&quot;&gt;Engineering Emergence&lt;/a&gt; which I read recently after some people mentioned it.&lt;/p&gt;

&lt;h3&gt;Graph layout rewrite&lt;/h3&gt;

&lt;p&gt;At this point I took some time improving the graph layout algorithm for the dependency graph, but didn&#39;t post on social media about it. The graph layout takes cues from the algorithm explained on the Wikipedia page about &lt;a href=&quot;https://en.wikipedia.org/wiki/Layered_graph_drawing&quot; target=&quot;_blank&quot;&gt;Layered Graph Drawing&lt;/a&gt; (Sugiyama-style) and I improved my implementation by taking ideas from these papers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.research-collection.ethz.ch/handle/20.500.11850/505558&quot; target=&quot;_blank&quot;&gt;Scalable Drawing of Nested Directed Acyclic Graphs With Gates and Ports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kups.ub.uni-koeln.de/54863/&quot; target=&quot;_blank&quot;&gt;Simple and Efficient Bilayer Cross Counting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/3-540-44541-2_22&quot; target=&quot;_blank&quot;&gt;A Fast Layout Algorithm for k-Level Graphs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the layout improvements I took a six month break from the game progression dependency graph research and focused on other things for a while, before taking it up again in November.&lt;/p&gt;

&lt;h3&gt;November 13 2022&lt;/h3&gt;

&lt;p&gt;Top: Game progression dependency graphs.&lt;br/&gt;
Bottom: Spatial graphs that show where things are in the world.&lt;/p&gt;

&lt;p&gt;A key for a locked gate is a direct dependency, but can be located far away spatially. Next step is making gameplay objects from the spatial graph nodes.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/DualGraph3DAngle.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The graph rendering used to be based on IMGUI with ugly matrix hacks but I spent today changing it to be based on &lt;a href=&quot;https://acegikmo.com/shapes/&quot; target=&quot;_blank&quot;&gt;Shapes by Freya Holmer&lt;/a&gt; so it supports perspective and is just much nicer. It&#39;s an awesome library and the switch was very easy.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/Graph3D.gif&quot;&gt;

&lt;h3&gt;November 19 2022&lt;/h3&gt;

&lt;p&gt;&quot;I&#39;ll just add some icons to my game progression dependency graph,&quot; I thought.
Haha, except, what do the icons really represent? The obstacle or the reward? Both? One week later, I&#39;ve ended up with this schematic representation.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphIconographic.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Here&#39;s two quite similar graphs before and after the iconographic makeover. Icons inside a node represent the obstacle/medium of that node, while icons shown at the top edge of a node represent the reward/outcome.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphBefore.png&quot;&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphAfter.png&quot;&gt;

&lt;h3&gt;November 24 2022&lt;/h3&gt;

&lt;p&gt;With the dual game progression dependency graph and spatial graph, I can now begin to construct a world to explore. Right now it&#39;s still looking rather abstract. 😅&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphPlayMode.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h3&gt;November 28 2022&lt;/h3&gt;

&lt;p&gt;Whee, I now have actual &quot;gameplay&quot; created from my game progression dependency graph and spatial graph (starting from 16s in the video). Only a few node types for now, but it&#39;s a cool milestone! 🗝🍎🐱🚩&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphGameplay.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The game will be focused on exploration, paying attention to the environment and finding clues in it about how to progress.&lt;/p&gt;

&lt;p&gt;A note on the spatial graph. The spatial positions of elements are laid out based on a node relaxing / repulsion algorithm, and then Voronoi cells are created at each position and walls created between cells that don’t belong to the same location.&lt;/p&gt;

&lt;h3&gt;November 30 2022&lt;/h3&gt;

&lt;p&gt;Every gate, key, creature etc. now has a unique generated pattern to identify it by, so I could get rid of all the letters. One step closer to a world full of visually depicted clues.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphPatternedIcons.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Adding some trees. Trees make everything 1000% better.&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphTrees.png&quot;&gt;

&lt;h3&gt;December 3 2022&lt;/h3&gt;

&lt;p&gt;Generating a strange walled garden full of secret clues, based on a game progression dependency graph.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/GraphGarden.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Someone noted in the replies that the &quot;kitty keys&quot; are an unusual concept, and that they couldn&#39;t think of an example where you need item A to lure creature B to point C to unlock gate D. I don’t know of that exact constellation elsewhere either. In some animes (and also The Fifth Element) a human is a key. And in the game Rime there’s some robots that serve as keys. I thought animals could be a fun variation on this already strange theme.&lt;/p&gt;

&lt;h3&gt;December 19 2022&lt;/h3&gt;

&lt;p&gt;Why did I implement this mechanic!? It&#39;ll just reveal I&#39;m terrible at remembering things!
Anyway, just a few new mechanics implemented for my strange walled garden that&#39;s procedurally generated based on a game progression dependency graph.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/ComboLock.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h3&gt;December 23 2022&lt;/h3&gt;

&lt;p&gt;Playing an instrument and finding songs with curious powers in this strange garden. (The game progression dependency graph it&#39;s procedurally generated from is shown at the end.)&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/ProgressionDependencyGraph/Instrument.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h3&gt;End of prototype&lt;/h3&gt;

&lt;p&gt;At this point I stopped working on this prototype. As a proof of concept it had succeeded with the successful generation of fully playable little levels with a variety of gameplay mechanics and clue types.&lt;/p&gt;

&lt;p&gt;The limiting factor was no longer the dependency graphs themselves.

&lt;p&gt;One limiting factor now is the iconographic gameplay. Different creatures are all little cat head icons only differentiated by different colored patterns. For things to be more evocative, immersive, and easy to remember, I need to actually generate 3D animals of a wide variety. So that&#39;s the next thing I started working on, though out of scope for this blog post.&lt;/p&gt;

&lt;p&gt;Another limiting factor is that I envision exploration to play an important rule in making the game satisfying to play, but the aesthetic of the prototype does not make exploration interesting at all. Luckily, another aspect of the game I&#39;ve been working on is &lt;a href=&quot;https://www.youtube.com/watch?v=VxMwggFQRQM&quot; target=&quot;_blank&quot;&gt;beautiful terrain generation&lt;/a&gt;. So eventually I need to integrate the procedural progression gameplay into those generated landscapes. But again, I need to first put work into creating procedural 3D models of the various gameplay elements before it can all be meaningfully integrated.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this chronology! If you have any questions, let me know in the comments. And if you want to follow the ongoing development of The Big Forest, check out the social media links in the menu, or copy-paste my blog URL into your RSS reader.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/1089164083362341606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/1089164083362341606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1089164083362341606'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1089164083362341606'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2024/10/procedural-game-progression-dependency.html' title='Procedural game progression dependency graphs'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-1192283347904257078</id><published>2024-08-18T12:35:00.006+02:00</published><updated>2025-05-14T15:12:46.666+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="eas"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="TheCluster"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><title type='text'>The Cluster is now released</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://runevision.com/multimedia/thecluster/&quot; target=&quot;_blank&quot;&gt;The Cluster&lt;/a&gt; is finally released and &lt;a href=&quot;https://runevision.itch.io/the-cluster&quot; target=&quot;_blank&quot;&gt;available for free on Itch&lt;/a&gt;. It&#39;s a 2.5D exploration platformer set in an open world that&#39;s carefully procedurally planned and generated, and does a few interesting things I haven&#39;t yet seen in other games (check out the links for more info).&lt;/p&gt;

&lt;img src=&quot;https://runevision.com/multimedia/thecluster/_pageshot.jpg&quot; style=&quot;display: none;&quot;&gt;

&lt;p&gt;Here&#39;s a trailer:&lt;/p&gt;

&lt;iframe allowfullscreen=&quot;&quot; src=&quot;https://www.youtube-nocookie.com/embed/IEoBuw9PyBU?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;My last blog post about The Cluster was in 2016 and titled &quot;&lt;a href=&quot;https://blog.runevision.com/2016/09/development-of-cluster-put-on-hold.html&quot; target=&quot;_blank&quot;&gt;Development of The Cluster put on hold&lt;/a&gt;&quot;, and by that I meant put on hold indefinitely.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;p&gt;At that time I had reached the conclusion that I had to give up my ambition of releasing The Cluster in the form I had envisioned. That would have required way more variety and features to be implemented, and due to a variety of burdens detailed in the post, that was not really viable after all, due to various details of the game&#39;s design and implementation.&lt;/p&gt;

&lt;p&gt;The context for this decision was that I had envisioned The Cluster to be a commercial title, and it was my primary game development project at the time. (Back then I was a game developer only in my spare time.) I wanted to switch my focus to different projects that were more viable to be able to be released as commercial games, specifically &lt;a href=&quot;https://runevision.com/multimedia/eyeofthetemple/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt;, which has since been completed and released to decent success, and &lt;a href=&quot;https://runevision.com/multimedia/thebigforest/&quot; target=&quot;_blank&quot;&gt;The Big Forest&lt;/a&gt; (working title), which I&#39;m working on these days.&lt;/p&gt;

&lt;p&gt;Still, I had put an incredible amount of work into The Cluster over many many years (going back to an initial prototype in Game Maker in 2003!), so I never managed to get reconciled with the idea of it never being available for others to see and play. Especially since, like I mentined, it does some things I haven&#39;t seen elsewhere. So at some point I decided I wanted to release it for free sooner or later, as I also mentioned in &lt;a href=&quot;https://blog.runevision.com/2022/10/one-year-later.html&quot; target=&quot;_blank&quot;&gt;this 2022 blog post&lt;/a&gt;. Not in the ambitious form originally envisioned, but in the limited but fully playable state it had already reached, plus a bit of polish to smooth out rough edges - for example adding robust gamepad support.&lt;/p&gt;

&lt;p&gt;And so, between 2016 and now I returned now and then to work on The Cluster for a little while, polishing it, fixing bugs, adding gamepad support, adding a settings menu, adding interaction prompts for how the controls work, and lastly, getting a round of playtesting by volunteers and addressing feedback from them. At the beginning of 2024 &lt;a href=&quot;https://blog.runevision.com/2024/01/2023-retrospective-and-goals-for-new.html&quot; target=&quot;_blank&quot;&gt;I said I wanted to get it out this year&lt;/a&gt;, and well, now it&#39;s finally out.&lt;/p&gt;

&lt;p&gt;The graphics are nothing special and the gameplay can get a bit repetitive over time, but still, for people who are content exploring a big world in search of artefacts, where there is a clear structure and purpose to the world layout, the game can be fun for a few hours, and provide an experience different from other games out there.&lt;/p&gt;

&lt;p&gt;It&#39;s also a showcase game for my open-source framework for layer-based infinite procedural generation, &lt;a href=&quot;https://runevision.github.io/LayerProcGen/&quot; target=&quot;_blank&quot;&gt;LayerProcGen&lt;/a&gt;. Oh yeah, I released that a few months ago, which I guess I never blogged about!&lt;/p&gt;

&lt;p&gt;Anyway, the game is free, so give it a try. And if you do, let me know what you think! :)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/1192283347904257078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/1192283347904257078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1192283347904257078'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1192283347904257078'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2024/08/the-cluster-is-now-released.html' title='The Cluster is now released'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-2462117757083201699</id><published>2024-01-08T16:03:00.011+01:00</published><updated>2025-09-18T16:22:41.643+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>2023 retrospective and goals for the new year</title><content type='html'>&lt;p&gt;2023 was a pretty good year for me!&lt;/p&gt;

&lt;p&gt;I&#39;ll touch here briefly on my personal life, then go on to talk about the Quest 2 release and sales of Eye of the Temple, and finally talk about my new game project and goals for 2024.&lt;/p&gt;

&lt;h3&gt;Personal life&lt;/h3&gt;

&lt;p&gt;It&#39;s the first year since the pandemic that didn&#39;t feel affected by it. I moved from Denmark to Finland in 2020, just as the pandemic began, so on the social side it was some slow years initially.&lt;/p&gt;

&lt;p&gt;Things picked up in 2022, but especially in 2023 we had lots of family and friends from Denmark visit us here and have a great time, and we also made more strides on the local social network front.&lt;/p&gt;

&lt;p&gt;Particularly memorable was a wonderful weekend celebrating the 40th birthdays of me and a friend, with some of my closest family and friends from Denmark and Finland at a site called Herrankukkaro in the beautiful Finnish archipelago.&lt;/p&gt;

&lt;h3&gt;Eye of the Temple released on Quest and turned a profit&lt;/h3&gt;

&lt;p&gt;In April 2023, a year and a half after the original PC release on Steam, my VR game Eye of the Temple was &lt;a href=&quot;https://blog.runevision.com/2023/05/behind-the-design-of-eye-of-the-temple-out-on-quest-2.html&quot; target=&quot;_blank&quot;&gt;finally released for Quest 2&lt;/a&gt;, with the help of &lt;a href=&quot;https://salmi.de/&quot; target=&quot;_blank&quot;&gt;Salmi Games&lt;/a&gt;. While it was super tough getting there, in the end we managed to ship the game at a level of quality I&#39;m very proud of. Others agreed; it got a great critical reception, as well as a high user rating of 4.7 out of 5 stars.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/mM5vLkPpJi8?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;It&#39;s super gratifying regularly seeing new reviews of the game from people who say it&#39;s the best VR experience they&#39;ve had. Oh, and recently, &lt;a href=&quot;https://www.uploadvr.com/top-25-best-meta-quest-3-games/&quot; target=&quot;_blank&quot;&gt;UploadVR ranked it the 5th best game for Quest 3&lt;/a&gt; and &lt;a href=&quot;https://screenrant.com/meta-quest-2-games-download-play-first/&quot; target=&quot;_blank&quot;&gt;Screen Rant ranked it the 6th best game for Quest 2&lt;/a&gt;. Wow, what an achievement for my little game! (But remember, critical acclaim does not equal sales…)&lt;/p&gt;

&lt;p&gt;I’m no longer working on the game at this point. After being occupied with it over a span of seven years, I really want to move on, and I&#39;m also done with VR in general for now. But the sales of the game are still developing, so let&#39;s talk a bit about that.&lt;/p&gt;

&lt;p&gt;My thinking about the game’s sales performance has changed a lot over time. I didn&#39;t pay myself a regular salary during the game’s three years of full time work. But when evaluating the game financially, I use the old salary from my previous job as reference, and calculate whether my time investment at that salary (I’ll refer to it as just “my investment”) would be covered retroactively by the game’s revenue. Of course, I also keep in mind that the covered percentage would be higher if I based it on a more moderate salary.&lt;/p&gt;

&lt;p&gt;I was initially slightly disappointed in the Steam sales. As I &lt;a href=&quot;https://blog.runevision.com/2021/11/launching-eye-of-temple-this-was-my.html&quot; target=&quot;_blank&quot;&gt;wrote about&lt;/a&gt; back in November 2021, the projected year one sales would only cover 25% of my investment. Back then I expected the Steam year one revenue to make up the majority of the game&#39;s lifetime revenue. &lt;a href=&quot;https://blog.runevision.com/2022/10/one-year-later.html&quot; target=&quot;_blank&quot;&gt;One year later&lt;/a&gt;, the sales had outperformed that projection, and my investment was actually covered 40%.&lt;/p&gt;

&lt;p&gt;A lot has happened since then, in particular due to the Quest launch.&lt;/p&gt;

&lt;p&gt;Comments from many VR developers in 2021 and 2022 had indicated that Quest sales could commonly be 5x-10x as large as Steam VR sales. For Eye of the Temple, the Quest week one revenue was merely twice of what the Steam week one revenue had been, so it was not quite as high as Salmi Games and I had hoped for. Speaking with other VR developers in 2023, it seems that the time when Eye of the Temple launched on Quest was generally a bad period for Quest game sales.&lt;/p&gt;

&lt;p&gt;Still, Quest is easily the most important VR platform, and later the sales picked up significantly, with the recent Black Friday and Xmas sales combined having as big an impact on revenue as the launch sales. Already, 70% of total revenue has come from Quest and 30% from Steam, with the Quest version having been out for a shorter time.&lt;/p&gt;

&lt;img alt=&quot;Cumulative revenue from Steam and Quest&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpXnlSsN7sOkcPRZ784zlesqYbxmHoCYMvEeBOEYbud7le659N627qzlGJZWFIbi3BEjW78dDY2IbNMvjjdOJ2607kJ06QlAFUcCQydIlU08g57aMX0bpzX91Zzr9gxAJjOcZPntzRKFKG4iXOE_TA-r_NyazXa3SCXJ6RdVaYvIVFZG_Homv6_klgbZY/s1600/CumulativeRevenueFromSteamAndQuest.png&quot; /&gt;

&lt;p&gt;My investment is now covered 140%. In other words, even based on a proper salary for myself that&#39;s fitting for my experience, Eye of the Temple has recently flipped well into profitability. That still doesn&#39;t make it a runaway hit, but it&#39;s really nice to know that it&#39;s a success not only creatively and as a passion project, but also in terms of financial sustainability. Back in 2020 when I was still developing the game, I had not expected that at all for my first commercial title.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;My new project: The Big Forest&lt;/h3&gt;

&lt;p&gt;So what comes after Eye of the Temple? Like I wrote above, I&#39;m done with VR for now.&lt;/p&gt;

&lt;p&gt;The working title of the new game I&#39;m developing is &quot;The Big Forest&quot;. It&#39;s set in a big mystical forest and has a strong focus on exploration. The gameplay will involve light puzzles based on connecting clues found through exploration and gradually gaining access to new areas.&lt;/p&gt;

&lt;p&gt;The project is in its early stages. The game will be fully procedurally generated, and so far I&#39;ve been working on a series of disconnected experiments and proofs of concept that will eventually all be rolled into the game. These include procedural generation of terrain, gameplay progression, creatures and music.&lt;/p&gt;

&lt;p&gt;I started working on the game in 2022, but I put it on hold shortly after, when I started working on the Quest 2 version of Eye of the Temple. In the last third of 2023, I started working on the procedural landscape for the game again. You can see an overview of that progress in the video below.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/VxMwggFQRQM?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;As for what the game is about in general, I made &lt;a href=&quot;https://runevision.com/multimedia/thebigforest/&quot; target=&quot;_blank&quot;&gt;this page about The Big Forest&lt;/a&gt; where you can read more about it.&lt;/p&gt;

&lt;h3&gt;Goals for 2024&lt;/h3&gt;

&lt;p&gt;I expect The Big Forest to be my focus for several years (and that might end up being an understatement).&lt;/p&gt;

&lt;p&gt;But I also have a list of more concrete things I hope to get done in 2024, not all directly related to my game:&lt;/p&gt;

&lt;h4&gt;Present my Fractal Dithering technique&lt;/h4&gt;

&lt;p&gt;Update January 2025: Didn&#39;t quite make it for 2024, but &lt;a href=&quot;https://runevision.com/tech/dither3d/&quot; target=&quot;_blank&quot;&gt;it&#39;s done now&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to release a video, blog post, and source code for a rendering technique I call &lt;a href=&quot;https://mastodon.gamedev.place/@runevision/110508837173343595&quot; target=&quot;_blank&quot;&gt;Fractal Dithering&lt;/a&gt;. It&#39;s unrelated to my game — just something I developed because I had an idea for it and had to try it out. The code is all done, and I worked on an explainer video (not the one here below) back in June-July 2023. But making the video took so long that I ended up having to take a break from it because I was losing motivation. Let&#39;s get that wrapped up.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20230608_DitheringImprovedMultipleScenes.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h4&gt;Release my Layer-Based ProcGen for Infinite Worlds framework as open source&lt;/h4&gt;

&lt;p&gt;Update May 2024: &lt;a href=&quot;https://runevision.github.io/LayerProcGen/&quot; target=&quot;_blank&quot;&gt;It&#39;s done&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I&#39;ve put more than a decade into developing a framework for contextual procedural generation of infinite worlds. I &lt;a href=&quot;https://blog.runevision.com/2013/09/layer-based-procedural-generation-for.html&quot; target=&quot;_blank&quot;&gt;wrote about it here&lt;/a&gt; in 2013. I originally developed it for the game The Cluster I was working on at the time. I since abandoned that game, but now I&#39;m using the framework for The Big Forest. I think the framework could be useful for others as well, which is why I&#39;d like to open-source it.&lt;/p&gt;

&lt;p&gt;The generality of the framework is proven by using it for two entirely different games - The Cluster being a 2.5D platformer where the world is made out of generated meshes and The Big Forest being a first/third-person game based on generated terrains. In 2023 I put some work into removing cruft from the framework that was only relevant to The Cluster, and generally streamlining it. There&#39;s still some more of that work left to do.&lt;/p&gt;

&lt;h4&gt;Wrap up and release The Cluster as a free experimental game&lt;/h4&gt;

&lt;p&gt;Update August 2024: &lt;a href=&quot;https://blog.runevision.com/2024/08/the-cluster-is-now-released.html&quot; target=&quot;_blank&quot;&gt;It&#39;s done&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I already &lt;a href=&quot;https://blog.runevision.com/2022/10/one-year-later.html&quot; target=&quot;_blank&quot;&gt;wrote about it here&lt;/a&gt; in 2022, but I&#39;d like to wrap up my old game The Cluster and release it for free as an unfinished game, partly because the game is fully playable and one can easily have a few hours of fun playing it, and partly because the game demonstrates a lot of interesting things that can be done with my Layer-Based Procedural Generation for Infinite Worlds framework in areas including level design and pathfinding. It&#39;s the longest-running project of my life, and it&#39;d be nice to get it out there, even if it&#39;s in an incomplete state.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/KsGy-Hc_AWk?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;h4&gt;Make better use of my YouTube channel&lt;/h4&gt;

&lt;p&gt;Until recently, &lt;a href=&quot;https://www.youtube.com/@runevision&quot; target=&quot;_blank&quot;&gt;my YouTube channel&lt;/a&gt; just had various videos that show off things with little or no comment, and without any channel branding or identity. I&#39;d like to start making videos in a more &quot;classic YouTube format&quot; where I discuss a subject with a proper intro and outro, channel branding, background music, etc.&lt;/p&gt;

&lt;p&gt;I&#39;ve just recently kickstarted that effort with the video about &lt;a href=&quot;https://www.youtube.com/watch?v=VxMwggFQRQM&quot; target=&quot;_blank&quot;&gt;developing a procedural landscape for The Big Forest&lt;/a&gt; that I embedded further up this page. I aim to produce a few more such videos in 2024, for example one video for each of the subjects mentioned above.&lt;/p&gt;

&lt;h4&gt;What would you like to see?&lt;/h4&gt;

&lt;p&gt;The goals above all relate to things I&#39;d like to share, so I&#39;m very interested in gauging which of those things might be of interest to you all. If there&#39;s anything you&#39;d be interested in in particular, let me know!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/2462117757083201699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/2462117757083201699' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/2462117757083201699'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/2462117757083201699'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2024/01/2023-retrospective-and-goals-for-new.html' title='2023 retrospective and goals for the new year'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpXnlSsN7sOkcPRZ784zlesqYbxmHoCYMvEeBOEYbud7le659N627qzlGJZWFIbi3BEjW78dDY2IbNMvjjdOJ2607kJ06QlAFUcCQydIlU08g57aMX0bpzX91Zzr9gxAJjOcZPntzRKFKG4iXOE_TA-r_NyazXa3SCXJ6RdVaYvIVFZG_Homv6_klgbZY/s72-c/CumulativeRevenueFromSteamAndQuest.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-2305422124700071631</id><published>2023-09-15T16:39:00.010+02:00</published><updated>2025-05-14T15:07:04.317+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><title type='text'>Charts to visualize how much you owe Unity for their per-install Runtime Fee</title><content type='html'>&lt;p&gt;Unity Technologies has announced a new Unity Runtime Fee that charges developers a fee of up to $0.20 per installed game above certain thresholds. According to my calculations, it can be a bankruptcy death-trap, at least in certain cases.&lt;/p&gt;

&lt;p&gt;Shockingly, the owed percentage is unbounded to the point that the owed amount can exceed gross revenue, since it depends on installs, not sales.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update 1:&lt;/b&gt; &lt;i&gt;Unity since &lt;a href=&quot;https://web.archive.org/web/20230922234125/https://blog.unity.com/news/open-letter-on-runtime-fee&quot; target=&quot;_blank&quot;&gt;backtracked and apologized&lt;/a&gt; for the announced changes. With the new updates to the terms, Unity will clamp the install fees to be at maximum 2.5% of revenue. And the changes will not be retroactive after all. Furthermore, John Riccotello is stepping down as CEO. There are more details in the linked blog post.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update 2:&lt;/b&gt; &lt;i&gt;About a year later, Unity &lt;a href=&quot;https://unity.com/blog/unity-is-canceling-the-runtime-fee&quot; target=&quot;_blank&quot;&gt;canceled the runtime fee altogether&lt;/a&gt;. Good.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Nevertheless, Unity has suffered a tremendous decrease in trust and goodwill, which already was not great before. With the cancellation, there is less urgency for developers to switch to a different engine, but the whole situation has highlghted the importance of being prepared for such a scenario and have eyes and ears open towards other engines as well.&lt;/i&gt;&lt;/p&gt;
  
&lt;p&gt;&lt;i&gt;The original post continues below.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;You can check out the specifications in their &lt;a href=&quot;https://blog.unity.com/news/plan-pricing-and-packaging-updates&quot; target=&quot;_blank&quot;&gt;blog post&lt;/a&gt;. Based on those, I&#39;ve made two charts where you can look up how big a percentage of your gross revenue you would owe Unity, based on the number of installs and on how much revenue you make for each of those installs. The fee specifications are different for Unity Personal and Unity Pro, so there is a chart for each.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXFh624JSWU2oQNLi15HWtKl36PpdDVCtNne769g_U1mIhPUpCGgxxO3Xw5SZffBWcv7oygby0-dNcmp_S6wlDUUV0UwiJBS9i7WlUTPxxyEoNxfFNjufO4gzzUHekaMStNYxElLHwXUmTEIfDcBBc4j6b-4EpHm9dlH7X4pRmpMV3AvZV4RbduuneUNs/s1600/UnityInstallFeeGraphPersonal3.png&quot;/&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZRB2_Jl9NLSveBM1_5XwNzeR5KKCPrvDb5puhX76ebIN0g8cF75oGuH1SMbgJK0FAe3evu_Md-2xUItYBsiDoXV-GYIbS-LI3h1f5uKRijC_0cFgkU0VFYOtNCvwNDLM1X4bXHtkkIwr5eop1Si9DN7QVys5CcboP0kgil68LEbvsrBGpGbrYnNVKA3A/s1600/UnityInstallFeeGraphPro3.png&quot;/&gt;

&lt;p&gt;If you want to check the math used for the charts, you can check out the source for the &lt;a href=&quot;https://www.desmos.com/calculator/iayndiv9d5&quot; target=&quot;_blank&quot;&gt;chart for Unity Personal&lt;/a&gt; and the &lt;a href=&quot;https://www.desmos.com/calculator/n1xtoon4j7&quot; target=&quot;_blank&quot;&gt;chart for Unity Pro&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Effect on free-to-play games&lt;/h3&gt;

&lt;p&gt;The first takeaway is that free-to-play games are kind of screwed, since the average revenue per user is often very low in that monetization model. This is probably deliberate. See, Unity is reducing or waiving the new fees for games that make use of certain services of theirs, such as Unity Gaming Services or Unity LevelPlay mediation for mobile ad-supported games. And there are reports that getting more games to adopt these services and &lt;a href=&quot;https://mobilegamer.biz/unity-is-offering-a-runtime-fee-waiver-if-you-switch-to-levelplay-as-it-tries-to-kill-applovin/&quot; target=&quot;_blank&quot;&gt;kill off the competition&lt;/a&gt; was the whole point of introducing the new fees. This sounds like a rather shitty anti-competitive practice.&lt;/p&gt;

&lt;p&gt;Enough about free-to-play though; I don&#39;t personally care that much about it and my knowledge about this area is very limited. What about premium games? Even if those are just collateral damage in Unity&#39;s strategy, they are still profoundly impacted.&lt;/p&gt;

&lt;h3&gt;Effect on premium games&lt;/h3&gt;

&lt;p&gt;Premium games (games that are bought with an up-front purchase) can typically have price tags such as $10, $20 or $60, and at those prices, Unity&#39;s Runtime Fee of $0.20 (or lower) per install is just a tiny fraction, right? No, unfortunately that&#39;s not how it works at all.&lt;/p&gt;

&lt;p&gt;Sure, if you assume that a premium game has one install per unit sold, and think of the revenue per install as the original price the game is sold at, then the new fees don&#39;t look too bad for premium games. But it&#39;s a trap to think that way.&lt;/p&gt;

&lt;h4&gt;The average lifetime price for a premium game is lower than you think&lt;/h4&gt;

&lt;p&gt;The average price a game sells at over its lifetime can be a fraction of the price it sells for initially. Deep discounts (e.g. 90% off on Steam) and bundles (Humble Bundles and similar) can rapidly drag down the lifetime average price of a game, since it often happens that way more people buy it at these lower price points than at the original price.&lt;/p&gt;

&lt;p&gt;So when using the charts above, don&#39;t consider a game&#39;s initial price. Instead, think of the lowest price the game could be sold at when it&#39;s at the maximum discount it will ever be, or when it&#39;s sold in a bundle together with other games, each game earning only very little per sale.&lt;/p&gt;

&lt;p&gt;And that low price, &lt;i&gt;that&#39;s just the starting point&lt;/i&gt;.&lt;/p&gt;

&lt;h4&gt;The number of installs is not the same as the number of copies sold&lt;/h4&gt;

&lt;p&gt;Don&#39;t think of the X axis in the charts above as the number of copies sold. The number of installs can be much higher, due to a variety of factors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A customer can install their purchase copy on multiple devices. Unity has said this will count as multiple installs.&lt;/li&gt;
  &lt;li&gt;A customer can uninstall the game and later install it again. Unity initially said this will count as separate installs and later said it won&#39;t. They have not disclosed how they would be able to know.&lt;/li&gt;
  &lt;li&gt;On some devices and stores, updating a game to a newer version might count as a new install. Unity has not disclosed their methodology.&lt;/li&gt;
  &lt;li&gt;Pirated versions of a game are unrelated to copies sold. Unity has said those won&#39;t be counted, but in practice they have no way of knowing if a given install is a pirated copy or not. They have said that developers are welcome to contact them if they suspect they have been victims of piracy. If this does not fill you with confidence, you&#39;re not alone.&lt;/li&gt;
  &lt;li&gt;Sometimes, full premium games are made &lt;a href=&quot;https://www.rockpapershotgun.com/assassins-creed-odyssey-is-free-to-play-this-weekend&quot; target=&quot;_blank&quot;&gt;free to play for a weekend&lt;/a&gt; or similar. It&#39;s a kind of demo, but using the same build as the full game. It&#39;s just limited in time. Meta also has a &lt;a href=&quot;https://developer.oculus.com/blog/buyer-confidence-try-before-you-buy/&quot; target=&quot;_blank&quot;&gt;try before you buy&lt;/a&gt; functionality where players can try certain games for e.g. 15 or 30 minutes before deciding if they want to buy it. These types of demos, that are not separate builds, count towards the install counts of the full game, and obviously the number of people who try the game can be much higher than the number who end up buying it. It essentially behaves similar to the free-to-play model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;How to actually use the charts&lt;/h3&gt;

&lt;p&gt;The problem is that you probably have little idea what the sold-copies-to-installs ratio will be for your game, given all the unpredictable factors mentioned above (multiple devices, reinstalls, updates, piracy, time-limited full-game demos if applicable). But you can &lt;i&gt;start&lt;/i&gt; by pretending one sale equals one install and plot a point in the chart based on that.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Plot an &lt;i&gt;initial starting point&lt;/i&gt; in the chart based on sold copies and revenue per sold copy:
    &lt;ul&gt;
      &lt;li&gt;For the X axis, predict how many copies your game will sell.&lt;/li&gt;
      &lt;li&gt;For the y axis, predict the average price the game will sell at, keeping in mind that it&#39;ll probably be closer to the lowest price the game will ever sell at than to the initial price.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now spot the diagonal black line that goes through the chart, which represents the 0% threshold.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt; Draw a line from your chosen initial starting point in the graph and down and to the right, parallel to that black 0% line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The higher the sold-copies-to-installs ratio is, the further you will move down and to the right along that line. This is because a higher sold-copies-to-installs ratio will both increase the number of installs and decrease the revenue per install. And in these particular charts, it forms a straight line because both the X axis and Y axis are exponential.&lt;/p&gt;

&lt;h4&gt;Example&lt;/h4&gt;

&lt;p&gt;Let&#39;s say you expect your game will sell on average for $10, taking discounts etc. into account, and that you expect to sell 300k copies. You want to know what you might owe Unity if you stay on the Unity Personal license (which is actually allowed regardless of revenue according to their announced changes).&lt;/p&gt;

&lt;p&gt;So in the chart for Unity Personal you plot in an initial point, which is at 300k on the X axis and at $10 on the Y axis. This would represent what you owe if there is exactly one install per sold copy.&lt;/p&gt;

&lt;p&gt;But to be aware of potential effects of the sold-copies-to-installs ratio being higher, you draw in a diagonal line starting from your initial point and going parallel to the bottom black 0% line.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrJ47fu-Gls171J4zXvH3Y2w4JucFsZHZDtjLafPuEGF2bV9bEYOSfhiRiSlzfXdvZCjfXPicvhF3-ATu4dR-vjcFwHP2in0awvXYZn_3UNWEzfbJAKztJQWomJzCCzktZxUeOLNllLpWZ2jqgaWWwgVft1HGtWOtCEzPo50X98DrA97A6QG02ycAS44k/s1600/UnityInstallFeeGraphPersonal3Example.png&quot;/&gt;

&lt;p&gt;Following this line shows you the effect of higher sold-copies-to-installs ratios, such as 2x and 10x, and you can see how this drastically affects how big a percentage of your gross revenue you owe to Unity.&lt;/p&gt;

&lt;h3&gt;Consequences&lt;/h3&gt;

&lt;p&gt;Unfortunately I can&#39;t help you figure out what is a realistic sold-copies-to-installs ratio to expect, because I have no idea even for my own games, let alone others&#39;. And that&#39;s kind of the problem here. Charging based on installs is utterly bonkers due to how unpredictable it is.&lt;/p&gt;

&lt;p&gt;It&#39;s impossible to budget for. And it makes all kinds of things which are a normal part of game development (like discounting your game, accepting that piracy is inevitable, etc.) into suddenly nerve-wrecking issues since they could have drastic effects on what you owe Unity.&lt;/p&gt;

&lt;p&gt;On top of the number of installs being unpredictable even if they were counted correctly, you also can&#39;t trust Unity to do that, since the way they track it is proprietary and unaccountable. It relies on Unity saying &quot;trust us, you owe us this much money&quot; and you not being able to inspect their methodology, data, or calculations at all. And many of the things they claim they will correctly count or correctly refrain from counting, are simply not practically possible.&lt;/p&gt;

&lt;p&gt;In fact, an alleged Unity employee (and it looks legit to me) &lt;a href=&quot;https://forum.unity.com/threads/unity-plan-pricing-and-packaging-updates.1482750/page-55#post-9299384&quot; target=&quot;_blank&quot;&gt;posted anonymously&lt;/a&gt; that Unity is aware developers may in some cases lose more per install than they earn, even to the point of bankruptcy, but that they would &quot;fix this with the customer to not bankrupt them&quot;.&lt;/p&gt;

&lt;p&gt;The issue with that is that no serious business would leave a matter of potentially going &lt;i&gt;bankrupt&lt;/i&gt; to be addressed with some future ad-hoc fix at another company&#39;s whim. That stuff needs to be up-front and contractual, &lt;i&gt;even&lt;/i&gt; with companies you trust, let alone with Unity.&lt;/p&gt;

&lt;p&gt;In short, this is an absolute train wreck.&lt;/p&gt;

&lt;p&gt;On a related note, I also &lt;a href=&quot;https://twitter.com/runevision/status/1702259250985124115&quot; target=&quot;_blank&quot;&gt;wrote here&lt;/a&gt; about how contrary to what Unity says themselves, Unity 2022.x or earlier and Unity 2021.x LTS or earlier are not affected by the Unity Runtime Fee as far as I can tell, based on Unity&#39;s own Terms of Service. It covers how a previous version of the Terms of Service allowed to stick with that version of the Terms of Service if you don&#39;t upgrade Unity, and how it doesn&#39;t matter that Unity removed that clause in a later version of the Terms of Service, since the older terms did not give them the right to change the terms like that.&lt;p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/2305422124700071631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/2305422124700071631' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/2305422124700071631'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/2305422124700071631'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2023/09/charts-to-visualize-how-much-you-owe.html' title='Charts to visualize how much you owe Unity for their per-install Runtime Fee'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXFh624JSWU2oQNLi15HWtKl36PpdDVCtNne769g_U1mIhPUpCGgxxO3Xw5SZffBWcv7oygby0-dNcmp_S6wlDUUV0UwiJBS9i7WlUTPxxyEoNxfFNjufO4gzzUHekaMStNYxElLHwXUmTEIfDcBBc4j6b-4EpHm9dlH7X4pRmpMV3AvZV4RbduuneUNs/s72-c/UnityInstallFeeGraphPersonal3.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7125435951758122607</id><published>2023-05-06T16:29:00.011+02:00</published><updated>2025-09-13T16:40:19.399+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="article"/><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="press"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>Behind the design of Eye of the Temple</title><content type='html'>&lt;p&gt;My VR adventure &lt;a href=&quot;https://eyeofthetemple.com&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt;, that I&#39;ve been working on since 2016, has landed on the Meta Quest 2! It was released last week on April 27th.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://www.oculus.com/experiences/quest/5361030930653377/&quot; target=&quot;_blank&quot;&gt;Get Eye of the Temple for Quest 2 on the Oculus Store&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Originally released for SteamVR in October 2021, so many people have asked for it to be brought to the Quest 2 as a native app, so I&#39;m happy it&#39;s finally a reality. The Quest 2 version was co-developed with Salmi Games and it took all our combined and complimentary skills to bring the game to life at target framerate on the Quest 2 mobile hardware.&lt;/p&gt;

&lt;p&gt;We also made this new trailer:&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/kTNMdfxPSLY?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The game got a fantastic reception! UploadVR called it &quot;&lt;a href=&quot;https://www.uploadvr.com/eye-of-the-temple-review/&quot; target=&quot;_blank&quot;&gt;A Triumphant Room-Scale Adventure&lt;/a&gt;&quot; and has labeled it an essential VR experience, and it got great video coverage by &lt;a href=&quot;https://www.youtube.com/watch?v=lvHU-199hUY&quot; target=&quot;_blank&quot;&gt;Beardo Benjo&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=XIqI_pmUktg&quot; target=&quot;_blank&quot;&gt;BMFVR&lt;/a&gt; and many others. It also got great user reviews and a high review score on the Oculus Store.&lt;/p&gt;

&lt;h3&gt;Behind the design&lt;/h3&gt;

&lt;p&gt;To mark the Quest 2 launch of Eye of the Temple, I&#39;ve written no less than three articles - published elsewhere - about different aspects of its design.&lt;/p&gt;

&lt;h4&gt;The Origins and Inspirations of ‘Eye of the Temple’&lt;/h4&gt;

&lt;p&gt;To celebrate the launch, I spoke with Meta about the origins of Eye of the Temple and the wide variety of inspirations (from classic platformers to Ico and Indiana Jones) behind the game.&lt;/p&gt;

&lt;p&gt;Read the article on the &lt;a href=&quot;https://www.meta.com/en-gb/blog/quest/eye-of-the-temple-vr-meta-quest-2-platformer/&quot; target=&quot;_blank&quot;&gt;Meta Quest blog&lt;/a&gt;&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqtXUjRdQN_EUTWJaxmnI7miLIK8AxP1ZdrN9gYWzTVUmBlo5qPFaVVquG2BIrOyeBeQ46hj7MpgvMQ9pKZvUwE4FQM40p19MiHSFHc5OVDFLl3G8Joob6MgbrtSBxt2lsn4E92L9ebRmeNYE3qAWEe7LU9N7_CYQk_rGLLfkbJrFAbJTivFCLyC6n/s1600/InspirationsCollage.jpg&quot;/&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h4&gt;Approachable and Immersive Design in ‘Eye of the Temple’&lt;/h4&gt;

&lt;p&gt;Immersion can mean many things, and VR has lifted the ceiling for immersion in games higher than ever before. In this article, I’ll detail how a design dogma of “embodied immersion” in Eye of the Temple goes hand-in-hand with making the game highly approachable—even for people who don’t normally play video games.&lt;/p&gt;

&lt;p&gt;Read the article on the &lt;a href=&quot;https://developer.oculus.com/blog/eye-of-the-temple-vr-immersion-game-design/&quot; target=&quot;_blank&quot;&gt;Oculus Developer blog&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMh1OtBa4QUhsy-PeLGUa9UToO0hwfuvrXbMh2AC9J4lZ9AJuyzr_n6bLH_q1zq6n9RUokoxMeUSrwISziX31WQO2N2s5TESB_o-H4zgLnJeFJqGPOam2pxOrzLn2KkQKsUEv3zqwjO3zFkQPNhYLr1d5CzqwkASyxE1JGPkIQ8pq4_N0pA9e3WGH_/s1600/DesignDogmaThumb.jpg&quot;/&gt;

&lt;h4&gt;The Hidden Design Behind the Ingenious Room-Scale Gameplay in ‘Eye of the Temple’&lt;/h4&gt;

&lt;p&gt;Eye of the Temple is one of the rare VR games that focuses on not just on pure room-scale movement, but &lt;i&gt;dynamic&lt;/i&gt; room-scale movement. The result is a uniquely immersive experience that required some clever design behind the scenes to make it all work. This guest article explains the approach.&lt;/p&gt;

&lt;p&gt;Read the guest article on &lt;a href=&quot;https://www.roadtovr.com/eye-of-the-temple-design-room-scale-vr-gameplay/&quot; target=&quot;_blank&quot;&gt;Road to VR&lt;/a&gt;&lt;/p&gt;

&lt;img style=&quot;width: 100%;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4JKvReN5wjMXVw4fptRptmn467MiC9rvu0ezXM1oPnF-ioHeAmzcVSFleQySacGHqPye86gY-ftN_ERl1MsVIVIs5fPL-ebTgfedkW9G9IuqLbUh_a2vBkCcsVgiZGZQY63wPewi9cM3St-5etVONz5S4s2FJZ7V9zCredQihflLHahYrgzywy5WH/s1600/05_platform_pattern_overlays.gif&quot;/&gt;

&lt;h3&gt;Other bits and pieces&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Here&#39;s a reddit post talking about how we had to &lt;a href=&quot;https://www.reddit.com/r/virtualreality/comments/12dnjg8/it_wasnt_easy_but_heres_how_i_managed_to_make_a/&quot; target=&quot;_blank&quot;&gt;completely change the water effect implementation&lt;/a&gt; on Quest 2 in order to keep the same aesthetic on the mobile hardware.&lt;/li&gt;
  &lt;li&gt;Here&#39;s a short &lt;a href=&quot;https://www.youtube.com/watch?v=XfGxukVhSJs&quot; target=&quot;_blank&quot;&gt;YouTube video&lt;/a&gt; where I explain how the room-scale platforming gameplay works behind the scenes. It essentially covers some of the same subject as the Road to VR guest article I mentioned above, but in less details.&lt;/li&gt;
  &lt;li&gt;Here&#39;s an &lt;a href=&quot;https://eyeofthetemple.com/faq.html&quot; target=&quot;_blank&quot;&gt;FAQ&lt;/a&gt; with answers to common questions we&#39;ve received since the Quest 2 release.&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7125435951758122607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7125435951758122607' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7125435951758122607'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7125435951758122607'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2023/05/behind-the-design-of-eye-of-the-temple-out-on-quest-2.html' title='Behind the design of Eye of the Temple'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqtXUjRdQN_EUTWJaxmnI7miLIK8AxP1ZdrN9gYWzTVUmBlo5qPFaVVquG2BIrOyeBeQ46hj7MpgvMQ9pKZvUwE4FQM40p19MiHSFHc5OVDFLl3G8Joob6MgbrtSBxt2lsn4E92L9ebRmeNYE3qAWEe7LU9N7_CYQk_rGLLfkbJrFAbJTivFCLyC6n/s72-c/InspirationsCollage.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-6857202744615880444</id><published>2022-10-14T17:08:00.014+02:00</published><updated>2025-05-14T15:07:38.332+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="procedural"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>One year later...</title><content type='html'>&lt;p&gt;Today is the one year anniversary of the &lt;a href=&quot;https://blog.runevision.com/2021/11/launching-eye-of-temple-this-was-my.html&quot; target=&quot;_blank&quot;&gt;release&lt;/a&gt; of my VR adventure &lt;a href=&quot;https://store.steampowered.com/app/589940/Eye_of_the_Temple/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt; on Steam! It&#39;s currently 40% off to celebrate.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKDNd4o_XJYkzzH_x02QgN6GJBcnLcnv6MbJacclAcmwcaKcI-MOtxWiwkFZ7uc9ReYBwOlBTV2eLuZ2kdso-tgBjTNQN2_2hBtw6FJWjlJfnZnhu1OL60hzORpk9zeZnBkzpbcSdgB-5Ul8NlDSM4edhyAN-gqt9Kdm1tUL6KPob6bss7wrwVLQTn/s1600/anniversary.png&quot; /&gt;

&lt;iframe height=&quot;190&quot; src=&quot;https://store.steampowered.com/widget/589940/?t=Step%20from%20one%20moving%20block%20to%20another%2C%20dodging%20traps%20and%20solving%20puzzles%20with%20your%20torch%20and%20whip%20in%20hand%2C%20as%20you%20explore%20a%20vast%20and%20treacherous%20temple%20in%20VR%20using%20your%20own%20feet.&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I thought I&#39;d take a moment to talk about what I&#39;ve been up to since the release, both related to Eye of the Temple and other projects.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;

&lt;h3&gt;Eye of the Temple updates&lt;/h3&gt;

&lt;p&gt;In the months after the release I worked on various fixes and updates to the game.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In December I added &lt;a href=&quot;https://store.steampowered.com/news/app/589940/view/3145199382107773902&quot; target=&quot;_blank&quot;&gt;save slots selection&lt;/a&gt; and &lt;a href=&quot;https://store.steampowered.com/news/app/589940/view/3145200016677501366&quot; target=&quot;_blank&quot;&gt;Steam Cloud support&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;In February I implemented some &lt;a href=&quot;https://store.steampowered.com/news/app/589940/view/3129441223341503055&quot; target=&quot;_blank&quot;&gt;minor improvements to the VR comfort options&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;In April I released a new feature called &lt;a href=&quot;https://store.steampowered.com/news/app/589940/view/3220646723626863522&quot; target=&quot;_blank&quot;&gt;Speedrun Challenges&lt;/a&gt; with bite-sized fast-paced physical challenges and Steam leaderboards integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of those, the Speedrun Challenges was the biggest feature. Leading up to its release, a handful of people from the game&#39;s Discord community had been testing the feature and competing for top spots on the leaderboards of the challenges. This was really great to see! I also set up &lt;a href=&quot;https://www.speedrun.com/eye_of_the_temple/levels&quot; target=&quot;_blank&quot;&gt;a page on speedrun.com&lt;/a&gt; and even implemented &lt;a href=&quot;https://www.speedrun.com/eye_of_the_temple/guide/iwtym&quot; target=&quot;_blank&quot;&gt;autosplitter integration&lt;/a&gt; for the popular speedrun timer LiveSplit, meaning that the game can control starting and stopping the timer exactly.&lt;/p&gt;

&lt;p&gt;Here&#39;s a video of Mettanine&#39;s current world record for the first speedrun challenge:&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/BGWsSWZeGso&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I had contemplated whether to run some sort of contest when the Speedrun Challenges feature released. However, after some contemplations back and forth, I decided not to wait and see if there was any interest in the Speedrun Challenges feature at all. I figured a contest should be used to boost existing interest, not conjure up interest out of thin air based solely on extrinsic rewards.&lt;/p&gt;

&lt;p&gt;As it turned out, there wasn&#39;t any interest to speak of. Once the feature released (which I posted about in various speedrun and VR subreddits and Discord servers, on Steam and Twitter, and wrote to journalists about), there were only a couple of people trying it out - much fewer than the handful who had been fairly active testing it during beta. Oh well. While certainly some people &lt;a href=&quot;https://twitter.com/benz145/status/1495457949229064193&quot; target=&quot;_blank&quot;&gt;found the idea fascinating&lt;/a&gt;, I guess speedrunning and physically intense VR are two niches with too tiny an overlap, at least for PC VR.&lt;/p&gt;

&lt;h4&gt;How has the game performed in its first year?&lt;/h4&gt;

&lt;p&gt;I wrote last year that sales of Eye of the Temple around its release had been mediocre, and that assuming year one sales would be about 3x of week one sales, the game would be on track to cover maybe half of its production costs after one year of sales if I based it on giving myself only an entry level game programmer salary.&lt;/p&gt;
  
&lt;p&gt;Year one sales outperformed that projection, instead being 4.45x of week one sales in units sold, and 4.1x in revenue. So that&#39;s nice! The costs are about two thirds covered instead of only half. If I instead base the costs on my old salary I got at Unity, they would be covered only 40% so far. However, I think expecting a lower salary when going indie is reasonable, especially in the beginning.&lt;/p&gt;

&lt;h4&gt;What about a Quest 2 port of Eye of the Temple?&lt;/h4&gt;

&lt;p&gt;&lt;b&gt;Edit:&lt;/b&gt; &lt;a href=&quot;https://www.oculus.com/experiences/quest/5361030930653377/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple for Quest 2&lt;/a&gt; released on April 27 2023! See &lt;a href=&quot;https://blog.runevision.com/2023/05/behind-the-design-of-eye-of-the-temple-out-on-quest-2.html&quot; target=&quot;_blank&quot;&gt;this post&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;&lt;s&gt;There&#39;s still no announcement regarding a Quest 2 port of Eye of the Temple at this time, but I do hope and believe it can happen, and there are still continuous efforts trying to make it a reality. Let&#39;s just say, I&#39;ve been in a whole lot of meetings.&lt;/s&gt;&lt;/p&gt;


&lt;h3&gt;My next game&lt;/h3&gt;

&lt;p&gt;I have ideas for a new game, but it&#39;s in very early stages. It won&#39;t be a VR game. It&#39;ll be procedurally generated world focused on exploration. It doesn&#39;t have a name yet, but let&#39;s call it &lt;i&gt;The Big Forest&lt;/i&gt; for now.&lt;/p&gt;

&lt;p&gt;As the code name suggests, the game will take place in a big forest. I developed a procedural environment experiment in 2016 that serves as a proof of concept.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/4ujnThRTxrQ?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The game will have a generated structure of progression. In April I worked on experiments generating such structures and visualizing them as dependency graphs and spatial graphs.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20221010_DualGraphs.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;The game will have procedurally generated and animated creatures, and I&#39;ve experimented a bit in August with procedural animation. Luckily I can draw on my experience developing my Locomotion System back in 2009.&lt;/p&gt;

&lt;video autobuffer loop controls playsinline&gt;
&lt;source src=&quot;https://runevision.com/blog/videos/20221010_ProceduralAnimation3Legs.mp4#t=0.001&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;Furthermore I have ideas about how to populate the world in a way that&#39;s informed by my article from 2021 about &lt;a href=&quot;https://blog.runevision.com/2021/02/designing-for-sense-of-mystery-and.html&quot; target=&quot;_blank&quot;&gt;designing for a sense of mystery and wonder&lt;/a&gt;. Combining all these elements into an actual game is going to be a tall order though.&lt;/p&gt;

&lt;h3&gt;My old game The Cluster&lt;/h3&gt;

&lt;p&gt;Before I started working on Eye of the Temple in 2016, I had worked for over ten years on a fully procedurally generated 2.5D platformer game called The Cluster. (Fun fact: The term &quot;procedural generation&quot; was not in common use back when I started in 2003, so I called it random level generation.)&lt;/p&gt;
  
&lt;p&gt;Eventually in 2016 I &lt;a href=&quot;https://blog.runevision.com/2016/09/development-of-cluster-put-on-hold.html&quot; target=&quot;_blank&quot;&gt;gave up&lt;/a&gt; releasing that game in a traditional sense, for a variety of reasons. But in the past year I&#39;ve gone back and implemented a few improvements and bug fixes, and I&#39;m considering whether I should spend a bit of time wrapping it up enough to be released for free as an experimental game, or an extended tech demo if you will. (Update: I &lt;a href=&quot;https://blog.runevision.com/2024/08/the-cluster-is-now-released.html&quot; target=&quot;_blank&quot;&gt;released The Cluster as a free game&lt;/a&gt; in August 2024.)&lt;/p&gt;

&lt;p&gt;For one, the game is fully playable and certain people can easily have a few hours of fun playing it. I recently recorded half an hour of gameplay here:&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/KsGy-Hc_AWk?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;For another, the game demonstrates several techniques that I think are still to this day somewhat novel within the field of procedural generation.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Overall, the game&#39;s procedural generation applies a planning approach to an infite world generated on the fly. In &lt;a href=&quot;https://blog.runevision.com/2015/08/procedural-world-potentials-simulation.html&quot; target=&quot;_blank&quot;&gt;this article&lt;/a&gt; from 2015 I contrast the simulation and the functional approaches with the planning approach, which is more akin to traditional level design. In procedurally generated games, there are many examples of a planning approach used on finite levels generated all at once, for example in rogue-likes, and there are examples of the functional approach used for infinite worlds that are generated on the fly, for example in Minecraft. But I&#39;m not sure how many games have used a planning approach for infinite worlds. The Cluster&#39;s multi-tiered map shows the game&#39;s planned space on a vast scale.&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTyRIexEd7q8ogeVycJjR0uz4k6-R_E5BW032v0B1PGYI1ZOjP3bhogR7Sevznu1Bv0ThL6fWeAeEr5jFzJ7U5pmbiu0q0VeGzjI_a8YVaqyMNg8KhDplMerH2z6E6ZkKp6Z3XMby8lIMvMnTB7AEtcOeJzTNfK9FcXgqXIwlGbmd2Zeg8a_eJDQf5/s1600/20220917_TheClusterMap.gif&quot;/&gt;&lt;/li&gt;
  &lt;li&gt;It demonstrates that the &quot;Layer-Based Procedural Generation for Infinite Worlds&quot; approach that I discuss in this moderately popular &lt;a href=&quot;https://www.youtube.com/watch?v=GJWuVwZO98s&quot; target=&quot;_blank&quot;&gt;YouTube video&lt;/a&gt; from 2013 actually works and scales up to a playable game.&lt;/li&gt;
  &lt;li&gt;The game has directional signs at various spots where the road forks, pointing the way to landmarks like shrines, gates and the hub village. While this is common in manually designed games, I&#39;m not sure if I&#39;ve seen it in procedurally generated worlds. The things pointed to exist far outside the currently generated chunks, and reinforces the feeling of the world as a carefully planned place.&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQnxcaFw0l3bEDH_KxptdRZtk4Rq4oXGyKcZVI0WYw0UM2fCs0nVfkswDJkhcn64vcECzWi7O3xJRgOrV-8nr3yE2MQeSvAPtccL2DYQp9v5AHWZG83wx8930qWq3t9cJHbpfpurFRSyfG7KlyETOKxh79uNzL6VAgERvZjk6cgv6nST8SArKBybq5/s1600/20220913_DirectionalSigns.gif&quot;/&gt;&lt;/li&gt;
  &lt;li&gt;Because the game&#39;s planned world has knowledge of goals far outside the currently generated chunks of the world, the gameplay can revolve around exploration with a hints system that provides a balance in between aimlessness and knowing where to go.&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKYZf99vUAK6N0sBDYL_-Y4Oz7J0PE779yA4gWI4m0UFVtw32bxVLeOonOwRlSXKF0IIWKFSP0vDBnEfPSN_FlNcS-ydM4WBw3jMt2RNU_WY_O-wIauhk6viaNOxLIwUyw0sXNN4VXaWuupXDuvQU-EBCZxcBpB-IPpLKwDq264d5qixYA6vRqCm3q/s1600/20221010_RevealedArtefactArea.gif&quot;/&gt;&lt;/li&gt;
  &lt;li&gt;It incorporates full enemy path finding in a 2D platform game, and moreover a procedurally generated one at that, so enemies can follow the player almost everywhere. It may have been done before, but it&#39;s certainly not common in platformers.&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd_0-9qzJmqzyedyy9INGuOqXEFwVkUck1QgrYXLM5-a22JdceGZzC2ZtEcSq0jC190EzOD0kY1tA4SxOsDfQ0FJWEYUhjiUt8MHLtP2x6Z6QcKDpsfECflgoc37_dT_VFJQjDb5qEitY-B2xO_RMtpC9QrGBNCOcL5A_61JCO9dFhbx0s3MEwxLlc/s1600/20221010_Enemies2.gif&quot;/&gt;&lt;/li&gt;
  &lt;li&gt;The game has sophisticated camera framing. Based on the locations of walls, ground and ceiling segments, the camera positions the player differently in the frame and smoothly interpolates between these different framings.&lt;/li&gt;
  &lt;li&gt;The game has a lot of built in debug options that makes it possible to inspect various aspects of the generation at the various layers of abstraction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It feels like a shame to let all this go unreleased. On the other hand, any work on this free release can be seen as a distraction from working on my next proper game which has commercial potential. If you&#39;re interested in the release of this game, please let me know, since that all helps motivating me to wrap it up.&lt;p&gt;

&lt;h3&gt;Overall&lt;/h3&gt;

&lt;p&gt;It&#39;s been a bit of a weird year. My attention has been split between all of the things above: Updates to Eye of the Temple, meetings related to porting it, working on various experiments for my new game, and tinkering on wrapping up my old procedural platformer. There&#39;ve been periods of productive focus and motivation, but also periods in between of procrastination and lack of motivation. I hope I can find my way into a more persistent groove soon.&lt;/p&gt;

&lt;p&gt;I can&#39;t talk much about Eye of the Temple, but if there&#39;s anything related to The Big Forest or The Cluster that you find interesting and would like to hear more about, let me know! This can help inform future blog posts and videos, and maybe even what I&#39;ll focus my attention on.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/6857202744615880444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/6857202744615880444' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6857202744615880444'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6857202744615880444'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2022/10/one-year-later.html' title='One year later...'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKDNd4o_XJYkzzH_x02QgN6GJBcnLcnv6MbJacclAcmwcaKcI-MOtxWiwkFZ7uc9ReYBwOlBTV2eLuZ2kdso-tgBjTNQN2_2hBtw6FJWjlJfnZnhu1OL60hzORpk9zeZnBkzpbcSdgB-5Ul8NlDSM4edhyAN-gqt9Kdm1tUL6KPob6bss7wrwVLQTn/s72-c/anniversary.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7437005772465403039</id><published>2021-11-22T13:53:00.020+01:00</published><updated>2025-09-13T16:41:00.654+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="article"/><category scheme="http://www.blogger.com/atom/ns#" term="carreer"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game culture"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="press"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>My experience launching Eye of the Temple</title><content type='html'>&lt;p&gt;My VR adventure &lt;a href=&quot;http://eyeofthetemple.com/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt;, that I&#39;ve been working on for the past five years, has finally shipped! It was released last month on October 14th.&lt;/p&gt;

&lt;p&gt;Naturally this was a huge milestone for me after having worked on it for so long. And while I&#39;ve released some smaller games for free in the past, Eye of the Temple is my commercial debut game. I actually did it! Wow, I say, patting myself on the back.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdyATWgnJtJDHAeeDvRraqiikjdaNfTUTJe_LuFkL_jer_iN6D5K06oHUKeJ5uIgVfjLKIOY-yL1J7xtKSs0mU3orQBmYc6blP27VI2DT6bjGG8dihC-fvJh78JJQbKXf5oiQVv1HsSfQ/s1920/hd_resolution.png&quot; /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;iframe height=&quot;190&quot; src=&quot;https://store.steampowered.com/widget/589940/?t=Step%20from%20one%20moving%20block%20to%20another%2C%20dodging%20traps%20and%20solving%20puzzles%20with%20your%20torch%20and%20whip%20in%20hand%2C%20as%20you%20explore%20a%20vast%20and%20treacherous%20temple%20in%20VR%20using%20your%20own%20feet.&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Shipping the game has been great, but also a bit confusing emotionally. There has been some big ups and also some downs. I might as well write about it here - mostly for my own sake, but who knows if it could be useful or just entertaining to someone else.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h3&gt;The time leading up to launch&lt;/h3&gt;

&lt;p&gt;I’m a developer first and foremost, and I frankly don’t enjoy doing work related to promotion very much. I know many others are in the same boat.&lt;/p&gt;

&lt;p&gt;The last major development work I did before launching was implementing localization around the end of August. Then came some weeks of working intensely on creating two trailers - the launch trailer for launch day, and a shorter launch day announcement trailer to be released a month before launch. Both trailers used mixed reality footage recorded by &lt;a href=&quot;https://www.youtube.com/c/ANABURN&quot; target=&quot;_blank&quot;&gt;Anaburn&lt;/a&gt;.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/eTjoEFVg3Pw?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/B5Bn9qdy3FY?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;When the trailers were more or less done, I had an entire month of doing just promotional work like creating gifs, sending out a press release and mails to journalists and creators (influencers) about the upcoming launch, tweeting, preparing the game for launch in Steamworks, tweeting specifically to influencers, plan pre-launch exclusive streaming with Ragesaq and spazkoga, writing to the (small) mailing list, etc. etc.&lt;/p&gt;

&lt;p&gt;Once launch day came, I had been deeply entrenched in “PR mode” for a long while, which is probably not ideal for my psyche.&lt;/p&gt;

&lt;h3&gt;Launch day&lt;/h3&gt;

&lt;p&gt;Release day finally came and I spent much of it sending out emails to journalists and YouTubers, writing posts on Reddit, Twitter and Facebook, and keeping the awesomely supportive people on the game&#39;s &lt;a href=&quot;https://discord.gg/yGN7bDQ&quot; target=&quot;_blank&quot;&gt;Discord server&lt;/a&gt; informed, and asking for their support once again. At 4 pm (local time in Finland) I finally pressed the release button and then I was busy replying to the flurry of comments and replies everywhere for a few hours.&lt;/p&gt;

&lt;p&gt;A few days earlier I had asked for advice on Twitter about what to do on release day in order for it to be a good emotional experience. The &lt;a href=&quot;https://twitter.com/runevision/status/1447098196891742209&quot; target=&quot;_blank&quot;&gt;general advise&lt;/a&gt; was to avoid sitting in front of a screen all day obsessively hitting refresh on pages, and instead make sure to take time to celebrate the achievement of shipping in good company with good food and drinks. And so I did!&lt;/p&gt;

&lt;p&gt;At 6 pm my partner and I went over to a launch party that my friends at &lt;a href=&quot;https://www.forbidden.dev/&quot; target=&quot;_blank&quot;&gt;Forbidden Studios&lt;/a&gt; had graciously offered to host at their studio. Champagne was had, pizza was eaten, and some people tried out the game for the first time while onlookers were entertained by it. Lots of chatting and high spirits. This was really nice and I hardly checked the Internet at all.&lt;/p&gt;

&lt;p&gt;In the following days my notifications were on fire like I&#39;ve never experienced before, and I spent all my time replying, retweeting and posting a few things of my own. It was kind of stressful but also very cool.&lt;/p&gt;

&lt;p&gt;I checked the sale stats too.&lt;/p&gt;

&lt;h3&gt;Mediocre sales&lt;/h3&gt;

&lt;p&gt;Sales of Eye of the Temple were not absent. The game was selling. It just wasn&#39;t selling a lot.&lt;/p&gt;

&lt;p&gt;Let me clarify one thing. Most indie games aren&#39;t selling a lot. In fact, most indie games sell less than Eye of the Temple. It&#39;s well known that only a fraction of games on Steam make enough money to make game development sustainable for their developers. Even a base level of success (only barely covering the costs of making the game) requires being way above the median. So let me start by saying that I’m lucky the game has been selling at all.&lt;/p&gt;

&lt;p&gt;Will sales of Eye of the Temple on Steam cover the costs of making it? Not really. I’ve developed Eye of the Temple over five years, but some of it was part time. It corresponds to about three years of full time work. Since it’s predominantly developed solo with only little use of contractors, the biggest expense is salary for myself. If I calculate with a salary for myself that’s less than half of what I’ve earned in the past, and lower than the average entry level game programmer salary (ignoring I’m a senior programmer with 13 years of experience), the game is on track to cover maybe half of that after one year of sales, assuming year one sales will be about &lt;a href=&quot;https://newsletter.gamediscover.co/p/steam-the-state-of-long-tail-revenue&quot; target=&quot;_blank&quot;&gt;3x of week one sales&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But I’m fortunate to have other sources of income besides the game sales, so I won’t be struggling paying my bills. Don’t worry about me.&lt;/p&gt;

&lt;p&gt;Really, the main reason the sales feel mediocre to me is that I think there’s a lot more people who would enjoy the game (and have the means to play it). But before I can meditate on the question of whether it feels like Eye of the Temple should have been able to sell better, we first need to catch up with some other things that happened.&lt;/p&gt;

&lt;h3&gt;An awesome review score&lt;/h3&gt;

&lt;p&gt;Four days after release I wrote this on Twitter:&lt;/p&gt;

&lt;blockquote&gt;Eye of the Temple currently has 32 reviews from paying customers. I&#39;m curious if it&#39;ll reach the magical threshold of 50 reviews in the first week. No matter how highly a game is rated, it can only go from &quot;Positive&quot; to &quot;Very Positive&quot; with 50 reviews.&lt;/blockquote&gt;

&lt;p&gt;And lo and behold! Already the day after I could write this:&lt;/p&gt;

&lt;blockquote&gt;Eye of the Temple reached 50 reviews, and Steam changed the label to &#39;Very Positive&#39;! This honestly happened quicker than I thought it would, and I really appreciate the help from you all! Thanks a lot!&lt;/blockquote&gt;

&lt;p&gt;A “very positive” rating on steam requires at least 50 reviews and that at least 80% of them are positive. But Eye of the Temple has a much higher rate of positive reviews. At one point it was 98%, a fact I used as part of drawing focus on the end of the launch discount.&lt;/p&gt;

&lt;figure&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii5jzCrw7_8MHtBzqrqYzrk0dVx2UgvEVLYcJD9pLLsbR3nl6iQLyKlOWEs1YpSWQQNM_ZSwB4GbRrYJ1QfAa3LlGyiBJ1lp8EMkmGDWDJXkERE6Ph5_3W4cQfDDTVV8-n9LA79qUgAhI/s16000/launch_discount.png&quot; /&gt;&lt;figcaption&gt;Promotional image used when the launch discount was about to end.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;It’s since dropped to 96%. (With only a bit over 100 reviews, all it takes is one more negative review to make it drop one percentage point, while it takes over 20 positive reviews for it to climb back up again.) Still, that’s a super high percentage I hadn’t expected at all, and I’m positively thrilled the game has been received that well!&lt;/p&gt;

&lt;p&gt;During development I had the impression, based on play-testing with lots of people (also VR first-timers), that only quite few people had issues with motion sickness when playing the game. However, I always had a worry that my perception was skewed for some reason, and that lots of people would report getting motion sickness once the game shipped, and that this would have a big negative impact on the review score. But that never happened at all, and that has been a huge relief!&lt;/p&gt;

&lt;h3&gt;The awesome Steam reviews&lt;/h3&gt;

&lt;p&gt;The reviews on Steam are just awesome. They proclaim Eye of the Temple to be not only mechanically groundbreaking with an unprecedented level of immersion, but also simply one of the best VR games created.&lt;/p&gt;

&lt;p&gt;Capturing the essence of over 100 reviews is no easy task but I’ve put together the following summary, with links back to 27 of the original reviews.&lt;/p&gt;

&lt;p&gt;A slew of reviews highlight the uniqueness of the game, saying it’s “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198304924585/recommended/589940&quot; target=&quot;_blank&quot;&gt;a refreshing change to see a new game form in VR&lt;/a&gt;”, that there’s “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198297094844/recommended/589940&quot; target=&quot;_blank&quot;&gt;nothing like this in VR&lt;/a&gt;”, and that it’s an “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198081849210/recommended/589940&quot; target=&quot;_blank&quot;&gt;instant classic&lt;/a&gt;”. Others write that it’s “&lt;a href=&quot;https://steamcommunity.com/id/remo4000/recommended/589940&quot; target=&quot;_blank&quot;&gt;some of the most creative VR gameplay of any VR game&lt;/a&gt;”, that it’s “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198020804147/recommended/589940&quot; target=&quot;_blank&quot;&gt;nothing short of genius&lt;/a&gt;”, and that “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198049683798/recommended/589940&quot; target=&quot;_blank&quot;&gt;this dev is some sort of mad genius&lt;/a&gt;”. Some write that it’s “&lt;a href=&quot;https://steamcommunity.com/id/wak7/recommended/589940&quot; target=&quot;_blank&quot;&gt;a revolution in Virtual Reality&lt;/a&gt;” because “&lt;a href=&quot;https://steamcommunity.com/profiles/76561199084427397/recommended/589940&quot; target=&quot;_blank&quot;&gt;the motion system is completely revolutionary&lt;/a&gt;” and that it has the “&lt;a href=&quot;https://steamcommunity.com/id/muschelhups/recommended/589940&quot; target=&quot;_blank&quot;&gt;potential to create a whole new genre in VR-Games&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;According to the reviewers, what makes it so innovative is that “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198042113113/recommended/589940&quot; target=&quot;_blank&quot;&gt;being able to actually walk through the entire game in your play space is just mind boggling and super immersive&lt;/a&gt;”, making it “&lt;a href=&quot;https://steamcommunity.com/profiles/76561197970329732/recommended/589940&quot; target=&quot;_blank&quot;&gt;one of those rare mind-blowing VR experiences&lt;/a&gt;”. Some say that the game “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198111577313/recommended/589940&quot; target=&quot;_blank&quot;&gt;does otherworldly things with your mental perception&lt;/a&gt;” that “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198019725395/recommended/589940&quot; target=&quot;_blank&quot;&gt;makes you forget you are in VR&lt;/a&gt;” and that as a result, “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198122174959/recommended/589940&quot; target=&quot;_blank&quot;&gt;the immersion level is off the chart&lt;/a&gt;” and it “&lt;a href=&quot;https://steamcommunity.com/id/12problems/recommended/589940&quot; target=&quot;_blank&quot;&gt;takes vr immersion to a new level&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;For some reviewers, that level of immersion made this VR adventure the “&lt;a href=&quot;https://steamcommunity.com/id/myfirkinprofile/recommended/589940&quot; target=&quot;_blank&quot;&gt;most ingenious and thrilling VR game&lt;/a&gt;”, speculating that “&lt;a href=&quot;https://steamcommunity.com/id/gratidude/recommended/589940&quot; target=&quot;_blank&quot;&gt;if Steven Spielberg or George Lucas made VR games instead of movies ... this is the VR game they would come up with&lt;/a&gt;” because it “&lt;a href=&quot;https://steamcommunity.com/id/fdruid/recommended/589940&quot; target=&quot;_blank&quot;&gt;captures perfectly the whole Indiana Jones vibe&lt;/a&gt;”, so that “&lt;a href=&quot;https://steamcommunity.com/id/mamefan/recommended/589940&quot; target=&quot;_blank&quot;&gt;if you want to feel like Indiana Jones, this is the closest you could ever get&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Overall, lots of reviewers say it’s “&lt;a href=&quot;https://steamcommunity.com/profiles/76561198043763009/recommended/589940&quot; target=&quot;_blank&quot;&gt;one of the best VR experiences”&lt;/a&gt; and “&lt;a href=&quot;https://steamcommunity.com/profiles/76561197999131167/recommended/589940&quot; target=&quot;_blank&quot;&gt;one of the greatest VR experiences of all time&lt;/a&gt;”. Several focus on room-scale, calling it “&lt;a href=&quot;https://steamcommunity.com/profiles/76561197997724206/recommended/589940&quot; target=&quot;_blank&quot;&gt;the best Roomscale VR Game&lt;/a&gt;” they’ve played and “&lt;a href=&quot;https://steamcommunity.com/profiles/76561199029229339/recommended/589940&quot; target=&quot;_blank&quot;&gt;the best room scale experience out there&lt;/a&gt;”. Some say it’s the “&lt;a href=&quot;https://steamcommunity.com/id/Dextrovix/recommended/589940&quot; target=&quot;_blank&quot;&gt;2nd best roomscale game&lt;/a&gt;” next to Half-Life: Alyx and that they “&lt;a href=&quot;https://steamcommunity.com/profiles/76561197971153087/recommended/589940&quot; target=&quot;_blank&quot;&gt;haven&#39;t had this much fun since playing Half Life Alyx&lt;/a&gt;”. Others think Eye of the Temple surpasses it and is simply the “&lt;a href=&quot;https://steamcommunity.com/id/trollnest3/recommended/589940&quot; target=&quot;_blank&quot;&gt;best VR game&lt;/a&gt;”. One reviewer didn’t limit it to VR and said: “&lt;a href=&quot;https://steamcommunity.com/profiles/76561197994207480/recommended/589940&quot; target=&quot;_blank&quot;&gt;I’ve been playing video games for 30+ years, and finding ALL the secrets in Eye of the Temple was easily the most satisfying moment I’ve ever had in a game!&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;It’s almost hard for me to believe how positively these reviews describe the game. I’m blown away and humbled by the response here.&lt;/p&gt;

&lt;p&gt;Of course, if you would rather sample some of the reviews yourself, you can see &lt;a href=&quot;https://store.steampowered.com/app/589940/Eye_of_the_Temple/#app_reviews_hash&quot; target=&quot;_blank&quot;&gt;all the reviews on Steam here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;The buzz&lt;/h3&gt;

&lt;p&gt;A whole lot of people made videos of Eye of the Temple on YouTube, most of which can be found &lt;a href=&quot;https://www.youtube.com/channel/UCYFkIA4j5FJvMLeAs04MzrQ&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. It’s too many to list, but I appreciate all of them! I gave out a lot of keys to even YouTubers with very low subscriber counts who had shown an interest in the game while it was in development. There has also been many people streaming the game.&lt;/p&gt;

&lt;p&gt;A few larger channels made videos as well. Here’s all the videos I know of with 2,000 views or more:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=9HQYHrjcWQo&quot; target=&quot;_blank&quot;&gt;Beardo Benjo&lt;/a&gt; (14K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YPc-ypCN2mU&quot; target=&quot;_blank&quot;&gt;Naysy&lt;/a&gt; (11K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CA-3Pz26vIA&quot; target=&quot;_blank&quot;&gt;Daily VR&lt;/a&gt; (5K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=iHOIfY5cQao&quot; target=&quot;_blank&quot;&gt;OtterWorldly&lt;/a&gt; (4K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Q2so4EJKdMo&quot; target=&quot;_blank&quot;&gt;Ben Plays VR&lt;/a&gt; (3K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=B5Bn9qdy3FY&quot; target=&quot;_blank&quot;&gt;My own official launch trailer&lt;/a&gt; (3K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=32ilizL_NXk&quot; target=&quot;_blank&quot;&gt;RitualNeo&lt;/a&gt; (2K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KaSox98yJb0&quot; target=&quot;_blank&quot;&gt;Disco-VR&lt;/a&gt; (2K views)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lot of the videos are really brilliant. The most concise is the excellent &lt;a href=&quot;https://www.youtube.com/watch?v=Q2so4EJKdMo&quot; target=&quot;_blank&quot;&gt;2 minute review&lt;/a&gt; by Ben Plays VR while two of the most entertaining to me are the mixed reality videos by &lt;a href=&quot;https://www.youtube.com/watch?v=YPc-ypCN2mU&quot; target=&quot;_blank&quot;&gt;Naysy&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/watch?v=iHOIfY5cQao&quot; target=&quot;_blank&quot;&gt;OtterWorldly&lt;/a&gt;. Naysy even had a &lt;a href=&quot;https://www.tiktok.com/@naysy_vr/video/7020519220840549633&quot; target=&quot;_blank&quot;&gt;TikTok video&lt;/a&gt; too that went viral with over 4 million views. That’s really cool!&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/Q2so4EJKdMo?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I couldn’t see any spikes in sales from any of these things, but I’m convinced they all helped a lot combined. All in all, it feels like there’s a bit of a “word of mouth” effect for Eye of the Temple.&lt;/p&gt;

&lt;h3&gt;The silence&lt;/h3&gt;

&lt;p&gt;Disappointment is just a miscalibration between expectation and reality. In this section I’ll talk about the biggest emotional let-down, but it’s important for me to emphasize that I’m not complaining, blaming anyone, or saying that the world is unfair. I’m just saying that I had certain expectations that were not met, which means they were incorrect to begin with.&lt;/p&gt;

&lt;p&gt;You see, I had kind of assumed that the press outlets and popular YouTube channels that had covered the game before its release, and spoken highly of it, would most likely also cover the release of the game. That turned out to be an incorrect assumption.&lt;/p&gt;

&lt;p&gt;Let’s start with the press. The highest-traffic outlets that have reviewed Eye of the Temple are &lt;a href=&quot;https://www.androidcentral.com/eye-temple-review&quot; target=&quot;_blank&quot;&gt;Android Central&lt;/a&gt;, &lt;a href=&quot;https://www.vrfocus.com/2021/10/review-eye-of-the-temple/&quot; target=&quot;_blank&quot;&gt;VRFocus&lt;/a&gt; and the German &lt;a href=&quot;https://mixed.de/eye-of-the-temple-test/&quot; target=&quot;_blank&quot;&gt;MIXED&lt;/a&gt;, which all reviewed it on launch day. Eye of the Temple hasn’t gotten reviews in more mainstream outlets like IGN, The Verge or Screen Rant, and I never much expected it would, since they never covered the game prior to release either.&lt;/p&gt;

&lt;p&gt;In contrast, the two most popular outlets for VR news, UploadVR and Road to VR, have covered the game multiple times prior to the release. UploadVR covered it &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-vr-game-requires-room-scale-locomotion/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-temple-puzzles/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-demo/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, and &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-release-date/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and mentioned it in an article &lt;a href=&quot;https://uploadvr.com/vr-games-2021/&quot; target=&quot;_blank&quot;&gt;38 Titles We Can’t Wait To Play&lt;/a&gt; and Road to VR covered it &lt;a href=&quot;https://www.roadtovr.com/hands-on-eye-temple-indiana-jones/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://www.roadtovr.com/eye-temple-puzzler-reelease-date-steamvr/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://www.roadtovr.com/eye-temple-release-date-trailer/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. With that much coverage prior to release, it took me by surprise that they didn’t review the game when it finally launched, and here over a month later still haven’t. UploadVR did post &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-launch-discount/&quot; target=&quot;_blank&quot;&gt;a quick note&lt;/a&gt; about the end of the launch discount and I appreciate that of course.&lt;/p&gt;

&lt;p&gt;Taking a bit more zoomed out perspective, we can look at Metacritic. Metacritic doesn’t include all reviews, but it can still give a general overview. When looking at the &lt;a href=&quot;https://www.metacritic.com/game/pc/eye-of-the-temple&quot; target=&quot;_blank&quot;&gt;Metacritic page for Eye of the Temple&lt;/a&gt; you can almost hear the tumbleweeds rolling, with its single review from VR Focus. Compare with the pages for other recently released VR games that sold much better: &lt;a href=&quot;https://www.metacritic.com/game/pc/i-expect-you-to-die-2-the-spy-and-the-liar&quot; target=&quot;_blank&quot;&gt;I Expect You to Die 2 (PC version)&lt;/a&gt; with 11 reviews and &lt;a href=&quot;https://www.metacritic.com/game/pc/sniper-elite-vr&quot; target=&quot;_blank&quot;&gt;Sniper Elite VR (PC version)&lt;/a&gt; with 20 reviews. Of course, those weren’t made by solo indie developers, but it’s just to put things in perspective.&lt;/p&gt;

&lt;p&gt;On YouTube a similar effect was going on, to a degree. Since we already talked about coverage of the released game on YouTube, with the most seen video having 14K views, we can do a little comparison with some videos from last year that covered the free demo of the game:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KoAFIHdZXs4&quot; target=&quot;_blank&quot;&gt;Ctop&lt;/a&gt; (105K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7KxsAH14Clo&quot; target=&quot;_blank&quot;&gt;Virtual Reality Oasis&lt;/a&gt; (50K views)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=hAS5LBAgkjE&quot; target=&quot;_blank&quot;&gt;A Wolf in VR&lt;/a&gt; (27K views)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the view counts of the videos of the released game seem almost quaint in comparison. The demo got covered by channels that have more subscribers and can command higher view counts. (That’s ignoring Naysy’s TikTok video that got 4M views of course. I don’t currently know how to meaningfully compare YouTube views with TikTok views.)&lt;/p&gt;

&lt;p&gt;Here, I had particularly thought it likely that Virtual Reality Oasis would cover the full game since he’d talked positively about it not only in his video but also in the podcast he hosts. On Twitter, after release, someone &lt;a href=&quot;https://twitter.com/VirtualPandaVR/status/1450008777260863488&quot; target=&quot;_blank&quot;&gt;suggested he was likely to cover the game&lt;/a&gt;, to which he replied “&lt;a href=&quot;https://twitter.com/vr_oasis/status/1450017504676532225&quot; target=&quot;_blank&quot;&gt;I already covered it and had a great time with it&lt;/a&gt;” - referring to his coverage of the demo a year prior. And I really appreciated that earlier coverage of course, and said as much. And yet: That there’s no reason to cover the released game when already having covered the demo is a logic that probably makes a lot of sense from the perspective of a YouTuber’s situation, but to the game developer it feels like getting cold water thrown in your face. My expectations were miscalibrated, and having them corrected was no fun.&lt;/p&gt;

&lt;p&gt;Another YouTuber I had hoped might cover the game, even if it was a slim chance, was Nathie. He hadn’t covered the game or its demo, but he had covered the game jam game Chrysalis Pyramid from five years earlier that was the precursor to the game. And back then he had said he hoped the developers would make a full game out of it, and he had made a bunch of suggestions for things to include in such a game. And now five years later, there is a full game, and it does include a lot of the things he suggested. If he then tried out that game on his channel, it would be like going full circle. It just seemed like such a good story, and people love good stories.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube-nocookie.com/embed/QT7260ZD7wc?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Two weeks after release I told that story through &lt;a href=&quot;https://twitter.com/runevision/status/1453096386799546377&quot; target=&quot;_blank&quot;&gt;this video&lt;/a&gt;, honestly hoping it might nudge him to cover the game on his channel. The video was very well received by people, and I was happy to see that Nathie also &lt;a href=&quot;https://twitter.com/NathieVR/status/1453110674465476609&quot; target=&quot;_blank&quot;&gt;quote tweeted it&lt;/a&gt; on his Twitter account, but alas still no video coverage. Ah well, it was worth a try.&lt;/p&gt;

&lt;p&gt;Anyway, lesson learned. With both press and influencers it seems logical to think “if the game got this amount of coverage before it was released, surely it will get at least as much if not more when it actually launches”. But that’s not a given at all. Reality can end up being the opposite.&lt;/p&gt;

&lt;h3&gt;Speculation time&lt;/h3&gt;

&lt;p&gt;Okay, there you have it, all caught up. The reviews on Steam were way better than I expected and there was a healthy buzz on YouTube. The coverage in the press (and to a degree among more mainstream YouTubers) was way worse than expected, and worse than coverage of the game prior to release had been. And the mediocre sales were somewhere in between, being lower than expected but not completely bad.&lt;/p&gt;

&lt;p&gt;Now I can meditate on whether it feels like Eye of the Temple should have been able to sell better, or rather on what the reasons might be that it didn’t.&lt;/p&gt;

&lt;h4&gt;Maybe PC VR is just dead&lt;/h4&gt;

&lt;p&gt;That’s what some people tell me. All the attention is on Oculus Quest these days. There might be something to this, though this doesn’t explain why some other recent PC VR games like &lt;a href=&quot;https://store.steampowered.com/app/752480/Sniper_Elite_VR/&quot; target=&quot;_blank&quot;&gt;Sniper Elite VR&lt;/a&gt;, &lt;a href=&quot;https://store.steampowered.com/app/1358140/Cooking_Simulator_VR/&quot; target=&quot;_blank&quot;&gt;Cooking Simulator VR&lt;/a&gt;, or &lt;a href=&quot;https://store.steampowered.com/app/1499120/I_Expect_You_To_Die_2/&quot; target=&quot;_blank&quot;&gt;I Expect You To Die 2&lt;/a&gt; sold way better on Steam than Eye of the Temple (extrapolated from number of reviews). And Eye of the Temple has as good Steam review or better as any of those.&lt;/p&gt;

&lt;h4&gt;Maybe it’s because the play area requirement limits who can play the game&lt;/h4&gt;

&lt;p&gt;That’s true. According to an old survey, only about 50% of people with VR headsets have a play area of 2m x 2m or more. Headsets have decreased in price since then, becoming available to people with lower income, and this might mean an even lower percentage have enough room now. But that’s only because the number of people with headsets grew so much.&lt;/p&gt;

&lt;p&gt;It’s estimated that &lt;a href=&quot;https://uploadvr.com/half-life-alyx-2-million/&quot; target=&quot;_blank&quot;&gt;2 million people own Half-Life Alyx&lt;/a&gt; and that per July this year there are nearly &lt;a href=&quot;https://www.roadtovr.com/steam-survey-vr-headsets-on-steam-data-july-2021/&quot; target=&quot;_blank&quot;&gt;3 million monthly connected headsets&lt;/a&gt; on Steam. Even if only 10% of those have a 2m x 2m play area, that’s still a huge market. So the play area requirement is by no means the bottleneck here.&lt;/p&gt;

&lt;h4&gt;Maybe people just don’t care as much about indie developers with no track record&lt;/h4&gt;

&lt;p&gt;Harsh but true to a degree. I mean, like I described above, there has been decent coverage of Eye of the Temple in the press prior to launch, and a respectable YouTube buzz when it launched, so it’s not like nobody cares. But when looking for reasons why there was so little coverage upon the actual launch, and also why the sales weren’t better, being an unknown indie is probably a notable factor in that.&lt;/p&gt;

&lt;h4&gt;Maybe it’s my lack of PR experience&lt;/h4&gt;

&lt;p&gt;Another factor that goes hand in hand with being an unknown indie developer &lt;i&gt;that self-publishes&lt;/i&gt; is having a lack of PR experience and know-how. While I’ve read a lot on the subject and followed a lot of best-practices (sending review keys to journalists and influencers well in advance of launch etc.), there’s undoubtedly also things I didn’t think about, things I didn’t execute well on, and things I did know about but didn’t have time to even try. I’m pretty sure this factors into the lack of press coverage.&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Maybe the demo stole some of the thunder&lt;/h4&gt;&lt;p&gt;Journalists and influencers prioritize &quot;fresh news&quot; and there&#39;s a risk that a demo (or free prologue) released in advance of a full game can detract from the &quot;news value&quot; of the release of the full game. The original intention was that the demo was released a few months in advance of the full game, which is supposedly the ideal gap, but then the full game took much longer to wrap up than I had thought. It ended up being released a full year after the demo, and this can further have magnified the &quot;old news&quot; effect.&lt;/p&gt;

&lt;h4&gt;Maybe the game just doesn’t have mainstream appeal&lt;/h4&gt;

&lt;p&gt;Oof, this is not a nice thought. This is also very speculative because it’s very hard for me to directly assess. While developing a game, it’s easy to get trapped in an echo chamber where you hear most feedback from fans of the game. I feel like I’ve always been aware of this, and while I’ve never dismissed positive feedback, I’ve kept in mind that it might not be representative of a larger player-base.&lt;/p&gt;

&lt;p&gt;However, the reviews on Steam has been just as positive. Is it possible for Steam reviews to be an echo chamber too? I suppose if a game’s presentation (trailer, store page etc.) very effectively selects for the people who will end up enjoying it, then maybe… If this is what has happened, it’s probably a good thing. It’s valuable for a game to only attract the people who will enjoy it, exactly so that it can get better reviews, word of mouth etc. from those who have played it.&lt;/p&gt;

&lt;p&gt;However, it would also have the effect that the positive reviews are not at all indicative of potential for more mainstream interest in the game, which could be counter-intuitive and confusing. This would explain the large discrepancy between the really positive Steam reviews and the mediocre sales and silence from the press. But I don&#39;t know if a &quot;Steam review echo-chamber&quot; is a plausible hypothesis or not.&lt;/p&gt;

&lt;h4&gt;Maybe it&#39;s the game&#39;s presentation that doesn&#39;t have sufficient appeal&lt;/h4&gt;

&lt;p&gt;One thing that goes against the &quot;limited mainstream appeal&quot; hypothesis is that many people have talked about how showing the game off to family and friends is a blast, and have recommended the game as a great choice to show to VR first-timers. I would think that this indicates very healthy mainstream appeal. Another possibility could be that while the game itself has good mainstream appeal, the game&#39;s presentation, such a trailers and store page, doesn&#39;t manage to convey that, and doesn&#39;t manage to attract all the people who would have enjoyed the game if they tried it. But the plausibility of this hypothesis is also hard for me to assess.&lt;/p&gt;

&lt;h4&gt;Maybe it’s a combination&lt;/h4&gt;

&lt;p&gt;It’s probably a bit of all of the above?&lt;/p&gt;

&lt;p&gt;Still, I have a feeling there’s a lot more people out there who would enjoy the game, and I hope more of those people might discover the game over time and get to see for themselves what those glowing reviews are raving about.&lt;/p&gt;

&lt;h3&gt;The future&lt;/h3&gt;

&lt;p&gt;Here’s what I have planned for Eye of the Temple:&lt;/p&gt;

&lt;p&gt;I want to add support for multiple save slots so multiple family members can play with separate saves, and people can let their friends try the game without losing their own progress.&lt;/p&gt;

&lt;p&gt;I might look into adding some features to the speedrun mode that might make it more motivating to try out, like having speedrun challenges for completing just a section of the game.&lt;/p&gt;

&lt;p&gt;And of course, I’d love to bring Eye of the Temple to Oculus Quest 2, but I don’t have the skill-set to do it myself. I’d need help from a skilled Unity developer (studio or individual contractor) with lots of experience profiling and optimizing for Quest or other mobile platforms. I&#39;m now in contact with a number of companies - we&#39;ll see how it goes!&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you have any thoughts on all of this, be sure to let me know. :)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7437005772465403039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7437005772465403039' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7437005772465403039'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7437005772465403039'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2021/11/launching-eye-of-temple-this-was-my.html' title='My experience launching Eye of the Temple'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdyATWgnJtJDHAeeDvRraqiikjdaNfTUTJe_LuFkL_jer_iN6D5K06oHUKeJ5uIgVfjLKIOY-yL1J7xtKSs0mU3orQBmYc6blP27VI2DT6bjGG8dihC-fvJh78JJQbKXf5oiQVv1HsSfQ/s72-c/hd_resolution.png" height="72" width="72"/><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7136464973342061675</id><published>2021-02-08T11:05:00.009+01:00</published><updated>2025-05-14T15:08:52.536+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="article"/><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><title type='text'>Designing for a Sense of Mystery and Wonder</title><content type='html'>&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5IEG7kMLnUiddFuWKXGbyiOeru3y5twG1VrYjYBnL7UZ_X8b0Jd2mxdXyWwdprPxqFRfa-_AygDO5OGbmac0R6Imyxs6LJbicFe-d8e9U9x-tI6X7WNrdutr4TtwIRQNClleaSQW-W4E/s16000/Cover.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5IEG7kMLnUiddFuWKXGbyiOeru3y5twG1VrYjYBnL7UZ_X8b0Jd2mxdXyWwdprPxqFRfa-_AygDO5OGbmac0R6Imyxs6LJbicFe-d8e9U9x-tI6X7WNrdutr4TtwIRQNClleaSQW-W4E/s16000/Cover.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;I play games to get to explore intriguing places, while challenge and story is secondary to me. But there still has to be a &lt;i&gt;point&lt;/i&gt; to the exploration. I don’t want to just wander around some place - I want to &lt;i&gt;uncover&lt;/i&gt; something &lt;i&gt;intriguing&lt;/i&gt; and ideally &lt;i&gt;mysterious&lt;/i&gt;. But the mystery lies not in the uncovering; it lies in the anticipation, or rather the lack of knowing exactly what I might find. In this article I examine &lt;i&gt;that&lt;/i&gt; sense of mystery and wonder that’s tied not to story or themes, but to exploration. I’ll be using the word &lt;i&gt;mystery&lt;/i&gt; as a shorthand for the kind of mystery and wonder I’m talking about here.&lt;/p&gt;

&lt;p&gt;Zelda: Breath of the Wild from 2017 is an amazing game to go explore in, and one of my all time favorites. That said, while there are many things in the game that exude a sense of mystery - and certainly more so than in the average open world game - there are also a lot of missed opportunities.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxGlSXanYbF4Uh2B0tx6cDSB2mqyPvfgx0I2XjQFflUFeI3je9bpsL0zaznfxGeZIKdAFnIBmPwIxwIipim_4-Ou_boWl79JmRUnJ1qJB_stEYS-DTy4ehcpeNsKKHAid05b8lFJgrSsA/s16000/BreathOfTheWild.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxGlSXanYbF4Uh2B0tx6cDSB2mqyPvfgx0I2XjQFflUFeI3je9bpsL0zaznfxGeZIKdAFnIBmPwIxwIipim_4-Ou_boWl79JmRUnJ1qJB_stEYS-DTy4ehcpeNsKKHAid05b8lFJgrSsA/s16000/BreathOfTheWild.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Breath of the Wild reinvented the Zelda formula as an open world game.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I’ll compare Zelda: Breath of the Wild (BOTW) with Zelda: A Link to the Past (ALTTP) to try to figure out why ALTTP has a stronger sense of mystery than BOTW. A Link to the Past is a much older Zelda game from 1991 but I first played it in 2019.&lt;/p&gt;

&lt;p&gt;Along the way I’ll be extracting four key design strategies for evoking a greater sense of mystery, and apply those strategies in the form of proposed design changes to BOTW. Finally, I’ll touch on some more general considerations to keep in mind when designing for a sense of mystery and wonder in general.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;Mystery-mileage&lt;/h3&gt;

&lt;p&gt;While I’m critical of certain aspects of Breath of the Wild in this article, I want to highlight a few things that did give me a sense of mystery and wonder: The eerie Lost Woods, the disorienting Thyphlo Ruins, and the three deceptive enormous labyrinths found in the world. These all evoked a great sense of intrigue and not knowing what I was dealing with or what I would find. But the sense of mystery in those locations largely came from them being unique one-of-a-kind things (or three-of-a-kind in the case of the labyrinths, although they were quite different from each other).&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnnpBYnvRhlPPtCCX6qJeq2_CXNOrffztK5wF8jjcB3O2Z2eMSw_T6M_L0DHcSrviPPFoIOLkNO2tWRsApHN-f9pXccRv6TIYuV-2tDyDcSTL_Qj4EgMUwyWjIJgUyoqXxMoqqXJyxwoY/s16000/Labyrinth.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnnpBYnvRhlPPtCCX6qJeq2_CXNOrffztK5wF8jjcB3O2Z2eMSw_T6M_L0DHcSrviPPFoIOLkNO2tWRsApHN-f9pXccRv6TIYuV-2tDyDcSTL_Qj4EgMUwyWjIJgUyoqXxMoqqXJyxwoY/s16000/Labyrinth.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;One of the three towering labyrinths in Breath of the Wild.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While having one-of-a-kind mysteries like this is absolutely great, not &lt;i&gt;everything&lt;/i&gt; in a large scale game can be uniquely different from everything else. It would require too many resources and not be manageable. That’s why this article focuses on strategies that make the existing variety of content in a game less predictable and more mysterious without requiring large amounts of additional variety of content. That’s the kind of strategies Breath of the Wild could have used to get better “mystery-mileage” out of its already amazing content.&lt;/p&gt;

&lt;h3&gt;Curiosities with unknown outcomes&lt;/h3&gt;

&lt;p&gt;Let’s start with the most obvious element that caused many people to feel that the world in BOTW is not as mysterious as it could have been. When you explore the vast world of Breath of the Wild, you’ll frequently come across something curious, like a circle of plants in a pond or an abstract stone sculpture with a piece missing. And initially you’ll go “huh, that’s curious” and be intrigued. Let’s investigate! You try to dive into that circle of plants in the pond or locate and add the missing piece to the stone sculpture - and a little fellow pops out of nowhere and rewards you with a Korok Seed! Oh cool!&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsvzEatC0dQ-59ZeRbG4Wo4QxUgjBWO6Bk9vJF650QdS059gT-rwlvkPoc21nxiadQttzIQHqFDEKlWZuZoJFkxwmcab3L15Bnmn_zUxYwGHAjRdoWRwLRgj6uTCQK0no-TeyYEYKwu88/s16000/KorokPuzzle.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsvzEatC0dQ-59ZeRbG4Wo4QxUgjBWO6Bk9vJF650QdS059gT-rwlvkPoc21nxiadQttzIQHqFDEKlWZuZoJFkxwmcab3L15Bnmn_zUxYwGHAjRdoWRwLRgj6uTCQK0no-TeyYEYKwu88/s16000/KorokPuzzle.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;A little puzzle in Breath of the Wild that rewards the player with a Korok Seed.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;However, by the 20th time you notice something curious, you’ll probably be thinking, “ah, it’s probably just another Korok Seed”. It’s still a fun little thing to do, and the Korok Seed is useful, sure, but there’s no longer any sense of mystery about it.&lt;/p&gt;

&lt;p&gt;To be clear, there are various small mysteries in BOTW that lead to other things than getting a Korok Seed, but those are usually related to quests that lead to an Ancient Shrine of the Blessing type. In contrast, Korok Seeds never involve a quest and always follow a set of predictable templates. It’s a many-to-one relationship: One set of curiosity types leads to Korok Seeds and a separate set of curiosity types leads to shrines.&lt;/p&gt;

&lt;h4&gt;Not knowing what you get&lt;/h4&gt;

&lt;p&gt;How does this compare to A Link to the Past? The closest analog in ALTTP might be the optional heart pieces, since they are also often hidden behind a little curiosity or mystery.&lt;/p&gt;

&lt;p&gt;Compared to the Korok seeds, though, the heart pieces in ALTTP are more strongly related to exploring nooks and crannies in the world. Sometimes you can see one in advance out of reach and the puzzle is figuring out how to reach it. Other times they just reward exploration but couldn’t have been known in advance.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE1-tBZP5a6FePAvfQoyletlMaN9McpeIptijAieR_AtciZ1LFp3355Yy8Oecik48HAiCf0IgopskWgsSwkHBwWvFum-6NGYNMguR7PaTgpUtbyeWAXL93Ck2ZiZRAIWrVu7x3Duv74EI/s16000/HeartPiece.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE1-tBZP5a6FePAvfQoyletlMaN9McpeIptijAieR_AtciZ1LFp3355Yy8Oecik48HAiCf0IgopskWgsSwkHBwWvFum-6NGYNMguR7PaTgpUtbyeWAXL93Ck2ZiZRAIWrVu7x3Duv74EI/s16000/HeartPiece.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Pieces of Heart are hidden away in many novel ways in A Link to the Past.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Sometimes they’re inside a chest, but chests can contain other things than heart pieces too. Similarly, reaching the heart pieces sometimes involves blowing a hole in a cracked wall with a bomb. But cracked walls can also lead to other things than heart pieces, so you won’t know what you’ll find. It’s a many-to-many relationship: Each of the curiosities that might lead to a heart piece (a chest, a cracked wall, etc) might also lead to another outcome.&lt;/p&gt;

&lt;p&gt;The fact that the curiosities or puzzles that lead to heart pieces don’t follow specific templates that are &lt;i&gt;only&lt;/i&gt; used for heart pieces means that finding heart pieces in ALTTP doesn’t feel formulaic and predictable in the same way that finding Korok Seeds does in BOTW. And this uncertainty and unpredictability about what to expect contributes to a sense of mystery.&lt;/p&gt;

&lt;h4&gt;The many-to-many relationship&lt;/h4&gt;

&lt;p&gt;What have we learned in this comparison between the curiosities in BOTW and in ALTTP?&lt;/p&gt;

&lt;p&gt;A question we can ask to determine if we are not getting the best mystery-mileage out of curiosities in the world is:&lt;/p&gt;

&lt;blockquote&gt;When the player sees something curious in the world, can they predict in advance what they’ll get out of it?&lt;/blockquote&gt;

&lt;p&gt;And a strategy we can make use of to decrease predictability of the outcome is:&lt;/p&gt;

&lt;blockquote&gt;Have a many-to-many relationship between the types of curiosities in the world and the types of outcomes.&lt;/blockquote&gt;

&lt;p&gt;Perhaps it can sound like unknown outcomes is about randomness, and that it’s the same principle that makes slot machines and loot boxes addicting but not intrinsically engaging. But unknown is not the same as random. When you explore a world and learn of an outcome of a given curiosity located at a specific location, this knowledge might be relevant later in the game, or if replaying the game. It’s a fact you’ve learned that’s tied to the experience of exploring the world. Loot boxes, in contrast, are not tied to a location in the world and the outcome can’t be learned. As such they’re not tied to exploration but are detached random events.&lt;/p&gt;

&lt;p&gt;Now let’s try to apply the strategy above to curiosities in Breath of the Wild. Perhaps some of the “Korok” style puzzles shouldn’t always lead to Korok Seeds. Sometimes they could lead to, say, an entrance to some area opening, a treasure chest being revealed, or it could mark the beginning of a new side-quest. Then you wouldn’t know in advance what you’d get or even it’s degree of significance. The relationship between curiosity and outcome would have been changed from a many-to-one relationship to a many-to-many relationship.&lt;/p&gt;

&lt;h3&gt;Ambiguous classification of spaces&lt;/h3&gt;

&lt;p&gt;In the last section we looked at how to make it harder to predict what you’re going to &lt;i&gt;get&lt;/i&gt;. In this section we’ll be looking into how to make it harder to form an idea of what something even &lt;i&gt;is&lt;/i&gt;. We’ll explore ambiguous classification starting with a comparison of the Ancient Shrines in BOTW with the dungeons in ALTTP.&lt;/p&gt;

&lt;h4&gt;Ancient Shrines and Dungeons&lt;/h4&gt;

&lt;p&gt;The entrance to a shrine in BOTW always uses (nearly) the same model. So you know exactly what a shrine looks like.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEtt650MqECoVQk0lgUmVS0_aX6sVYDLP7s2jdjunI5IWRno6dAZv4vDR15Dv02wv-mDa7Dpgp3utUqeefRlcruRAjb0hmhbMSc-giQgWbluju5xaMHk5i7_dlf8Mxa8z6uo25WEvypPA/s16000/Shrine.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEtt650MqECoVQk0lgUmVS0_aX6sVYDLP7s2jdjunI5IWRno6dAZv4vDR15Dv02wv-mDa7Dpgp3utUqeefRlcruRAjb0hmhbMSc-giQgWbluju5xaMHk5i7_dlf8Mxa8z6uo25WEvypPA/s16000/Shrine.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;An Ancient Shrine in Breath of the Wild. They all look like this.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;When you enter, you descend a long tube elevator down into an often enormous space. The kind of challenge found there varies greatly (sometimes there’s no challenge at all, if the challenge was reaching the shrine entrance in the first place), but invariably you will reach a platform at the end with a treasure chest and a monk who grants you a Spirit Orb that can be used to increase health or stamina. Then there’s a cut, and you’re back at the Shrine entrance in the world above.&lt;/p&gt;

&lt;p&gt;Dungeons in ALTTP are not an exact analog to Shrines in BOTW. The dungeons play a more central role since they give you new abilities, they end with boss fights, and beating them is required. Still, they’re close enough for our comparison.&lt;/p&gt;

&lt;p&gt;Entrances to dungeons in ALTTP don’t have a specific look; they are each unique.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqwObQN9lQJ4NQv7MEn64oAyHQR1ZpUzeclkgKSCHbIMBjhnNrhdNZP3P0J0f65F-eqBj0Slvaos5BTn-wJD9mBVMdsb0hzgWmvyjt-96-LosVBvBz5aVw5_XCI5MtDL-JOc35eQJexE8/s16000/Dungeons.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqwObQN9lQJ4NQv7MEn64oAyHQR1ZpUzeclkgKSCHbIMBjhnNrhdNZP3P0J0f65F-eqBj0Slvaos5BTn-wJD9mBVMdsb0hzgWmvyjt-96-LosVBvBz5aVw5_XCI5MtDL-JOc35eQJexE8/s16000/Dungeons.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Various entrances in A Link to the Past. Can you tell which of them lead to dungeons?&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Some of the images above depict entrances to dungeons while some of them depict other entrances that are not to dungeons. Can you tell which is which? I actually can’t remember this myself despite having played the game just a few years ago.&lt;/p&gt;

&lt;p&gt;I can’t overstate what this does for the sense of mystery when exploring this world. Instead of seeing “there’s a dungeon”, “there’s an X”, “there’s a Y” etc. I just see mysterious entrances. Who knows what’s inside? Compare this to BOTW where you always know when an entrance is an Ancient Shrine because all shrines look the same.&lt;/p&gt;

&lt;p&gt;Now, I know that some dungeons in ALTTP get explicitly marked on the world map, but that doesn’t counteract the sense of mystery entirely.&lt;/p&gt;

&lt;h4&gt;What even is a dungeon?&lt;/h4&gt;

&lt;p&gt;Now, if this was only about the entrances, we could say this is another example of a many-to-many relationship where you don’t know what the outcome is in advance when you see an entrance.&lt;/p&gt;

&lt;p&gt;But in ALTTP the mystery doesn&#39;t stop when you&#39;ve entered an entrance because even once inside, it&#39;s still not entirely clear what kind of space you&#39;ve entered. Is it a dungeon or not? And if it is, what does that mean exactly?&lt;/p&gt;

&lt;p&gt;For what is a dungeon? There&#39;s forum discussions online where people discuss how many dungeons ALTTP has, and people reach different numbers depending on which criteria they use. Is it the spaces where you get a new ability? The ones that end with a boss? The ones that are mapped out with a dungeon map? And does the castle that you clear one part of, and then later in the game return to clear another part of, count as one or two dungeons?&lt;/p&gt;

&lt;p&gt;This illustrates that it&#39;s not entirely clear cut what what constitutes a dungeon in this game, and I find that to be a &lt;i&gt;good&lt;/i&gt; thing. It’s harder to know what to expect, and consequently, it feels more like anything might be possible, when structures in the game don’t consistently follow clear templates and the player can’t conclusively classify the spaces they encounter.&lt;/p&gt;

&lt;p&gt;But just having occasional exceptions to the template isn’t enough. Imagine what it would do to the sense of mystery in ALTTP if dungeons clearly communicated “this dungeon follows the classic template” or “this dungeon is an exception” as soon as you see the entrance? This would greatly reduce the intrigue for the dungeons that follow the template, since it’s clear what to expect from them. This is exactly the situation we have in Breath of the Wild.&lt;/p&gt;

&lt;p&gt;BOTW does have a few dungeon-like places that don’t fit the shrine template. And they were highlights in the game. But the sense of mystery those “exceptions” from the template produce doesn’t rub off on the shrines, simply because it’s so easy to tell if something is a shrine or &lt;i&gt;something else&lt;/i&gt;. It’s important for the sense of mystery then, that the instances that are exceptions to the template can’t always clearly be told apart from the instances that follow the template.&lt;/p&gt;

&lt;h4&gt;Undermine simple classification&lt;/h4&gt;

&lt;p&gt;What have we learned in this comparison between the Ancient Shrines in BOTW and the dungeons in ALTTP?&lt;br /&gt;&lt;br /&gt;A question we can ask to determine if we are not getting the best mystery-mileage out of different types of spaces in the game is:&lt;/p&gt;

&lt;blockquote&gt;Can the player easily tell different types of spaces from each other and unambiguously classify them?&lt;/blockquote&gt;

&lt;p&gt;And a strategy we can make use of to increase ambiguity is:&lt;/p&gt;

&lt;blockquote&gt;Reduce or eliminate signifiers that would otherwise clearly distinguish different classes of spaces from each other, or introduce exceptions that challenge or confuse simple classification.&lt;/blockquote&gt;

&lt;p&gt;Now let’s try to apply this strategy to the Ancient Shrines in Breath of the Wild. Instead of using the same recognizable model for all shrines, it would have been viable to create a dozen different “entrance” 3d models, each of them still highly visible from afar so they can still serve as a goal to move towards, and have each shrine use one of those. Crucially, these entrance models should also be used for entrances to other things than shrines - like notable caves, hideouts, passages and similar. (Footnote: And yes, shrine entrances also have a Sheikah Plate activation mechanism and a teleport location marker. Where would they be if using an entrance model that’s not specific to Ancient Shrines? I don’t have an answer to that but it’s a solvable design problem.)&lt;/p&gt;

&lt;p&gt;This would make use of the many-to-many relationship discussed previously to ensure that when you’d see some entrance, you wouldn’t know what it would lead to - an Ancient Shrine, or something else. You’d have to investigate to find out.&lt;/p&gt;

&lt;p&gt;However, this only makes the nature of the space unclear &lt;i&gt;prior&lt;/i&gt; to entering it. To truly make the classification ambiguous, it would have to stay unclear also while inside the space, and maybe even still after having completed the encounter. This means we have to break down some of the other clear signifiers of Ancient Shrines too.&lt;/p&gt;

&lt;p&gt;Does every shrine have to begin with a tube elevator? Does it need to be a separate space from the outside world at all? Consider the shrines of the Blessing type, where the challenge lies in&amp;nbsp; finding and reaching the shrine entrance in the first place, typically in some hard to reach spot, while there’s no challenge inside the shrine space. The treasure chest and monk simply sit there.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwff74F_fNYsFDpAil9Fs-cmbvsci05mbp_9fuzL4ruoPpkfv6ushsDD_em1r1y3OPmj6H9zjqBem7Y1Un7Zxy38_BPz1ll_ZMamLMajPN0owgfVpdxdY2PvyrYffrd7-Ombs99IUj1c8/s16000/BlessingShrine.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwff74F_fNYsFDpAil9Fs-cmbvsci05mbp_9fuzL4ruoPpkfv6ushsDD_em1r1y3OPmj6H9zjqBem7Y1Un7Zxy38_BPz1ll_ZMamLMajPN0owgfVpdxdY2PvyrYffrd7-Ombs99IUj1c8/s16000/BlessingShrine.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;In Ancient Shrines of the Blessing type, the treasure chest and monk are reached without any challenge.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Why do shrines with no challenge inside need a separate shrine space at all? Couldn’t the monk sometimes hang out right in the hard to reach spot? In that case, it would be more ambiguous whether the defining trait of a shrine is just the presence of the monk, or if there has to be a separate shrine space as well.&lt;/p&gt;

&lt;p&gt;Another possibility could be that after completing one shrine in the game, the monk at the end would be missing. Maybe there’s a message that you have to find him elsewhere in the world (yes, “our monk is in another castle”). Would this still count as a shrine? And if so, would the shrine count as completed before or after finding the monk?&lt;/p&gt;

&lt;p&gt;If the answers to such questions could go either way, we’re on the right track towards the classification ambiguity that enhances the intrigue. If on the other hand you still think it would be obvious whether something is a shrine or not, think about what distinction makes it obvious and how that distinction could be broken down as well.&lt;/p&gt;

&lt;p&gt;One last point regarding this type of ambiguity is that UI and other meta-elements can easily counteract it, if not carefully avoided. For example, the ambiguity of what is or isn’t a shrine is decreased if a title displayed on the screen tells you that this is a shrine, like in the image above. Maybe those titles are deemed important to keep for other reasons, but it’s worth being aware of the tradeoff involved.&lt;/p&gt;

&lt;h3&gt;Overlapping gameplay modes&lt;/h3&gt;

&lt;p&gt;Fairies are a staple in the Zelda franchise and they usually come in two varieties: Regular fairies that can be used to restore heath, and Great Fairies that can upgrade some armor or weapons.&lt;/p&gt;

&lt;p&gt;In Breath of the Wild, regular fairies are found primarily at Great Fairy Fountains where the Great Fairies also reside, but also at other locations like atop the Deku Tree, at a pond on Ebon Mountain, and in Hyrule Field. They are always out in the open.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3aoqEeDmqfJlZPFBV9CwL06lGYnZ76Qc4zTAS3oBV311A8H4-1L0s6LGyAi3_tqNcE7zvBBy2XsPp450OLMuPy3wqmMu8Iy_e_RsFBWtcSq6dfrfwhVl59P_XGGpfoGplinB2wqFMTbU/s16000/Fairy.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3aoqEeDmqfJlZPFBV9CwL06lGYnZ76Qc4zTAS3oBV311A8H4-1L0s6LGyAi3_tqNcE7zvBBy2XsPp450OLMuPy3wqmMu8Iy_e_RsFBWtcSq6dfrfwhVl59P_XGGpfoGplinB2wqFMTbU/s16000/Fairy.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Fairies in Breath of the Wild can be collected at various spots out in the open world.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In A Link to the Past, regular fairies are found at Fairy Fountains located in a great variety of places. It’s normally in a cave or other inside area, but the entrances to these areas may be regular cave entrances, a staircase hidden below a rock, a hole in a hollow tree trunk, a hole under a bush, or behind a wall you have to blow up.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj966nKS80mKPFole0GPNnvChooUdLMXjLQ9ytWZEeRfGbs2hPTEH-QICk5Awt-EL_IXQahcupUanIc3zVYZyk1r8pppyQ0-IwMMc0HI9meOldHej4wSUVLZotwTGX7bGrwtm8WZF7d_KU/s16000/FairyLocations.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj966nKS80mKPFole0GPNnvChooUdLMXjLQ9ytWZEeRfGbs2hPTEH-QICk5Awt-EL_IXQahcupUanIc3zVYZyk1r8pppyQ0-IwMMc0HI9meOldHej4wSUVLZotwTGX7bGrwtm8WZF7d_KU/s16000/FairyLocations.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Fairy Fountains in A Link to the Past are hidden in a variety of ways.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Interestingly, these entrances are not only out in the open world. Notably, some fairy fountains are hidden away inside dungeons. In BOTW, finding fairies and clearing shrines are two entirely separate activities or &lt;i&gt;gameplay modes&lt;/i&gt; with no overlap - from a design perspective it’s very &lt;i&gt;clean&lt;/i&gt; - while in ALTTP there’s an overlap. Clearing a dungeon leading up to a boss is not a separate gameplay mode from searching for hidden secrets.&lt;/p&gt;

&lt;p&gt;It might seem like a moot point to highlight such an overlap of gameplay modes - &lt;i&gt;of course&lt;/i&gt; you can explore and find all kinds of secrets in dungeons just like in the outside world - why wouldn’t you? But the shrines in BOTW shows us that it’s not a given.&lt;/p&gt;

&lt;h4&gt;Spaces that serve multiple gameplay modes&lt;/h4&gt;

&lt;p&gt;In our comparison of BOTW and ALTTP we’ve found that a breakdown of clear separations between different gameplay modes enhances the sense of mystery because the player can’t form clear expectations of what to find where. Interesting things can be found &lt;i&gt;anywhere&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;A method we can use to determine if we are lacking overlap between different gameplay modes is:&lt;/p&gt;

&lt;blockquote&gt;Making a list of the different game activities or modes that exist in a game. Does certain locations or spaces in the game offer only few or a single gameplay mode to engage with?&lt;/blockquote&gt;

&lt;p&gt;And a strategy we can make use of to increase overlap of gameplay modes is:&lt;/p&gt;

&lt;blockquote&gt;Ensure spaces and locations in the game serve multiple different gameplay modes, though not all of them have to be equally obvious.&lt;/blockquote&gt;

&lt;p&gt;Let’s consider how we might apply this in Breath of the Wild. All over the outside world you can find various ingredients for recipes, some more rare than others. Why not be able to find those inside Ancient Shrines too? Not necessarily as a regular thing, but it could add a lot of sense of mystery to &lt;i&gt;all&lt;/i&gt; shrines if some rare ingredients could be found inside even just a few of them. This would create an overlap of the gameplay modes of finding ingredients and clearing shrines.&lt;/p&gt;

&lt;p&gt;And why stop at ingredients? Certain shrines could have fairies in them - just like certain dungeons do in ALTTP. Why, maybe you might even find a Korok Seed inside a shrine! Or certain side quests in the outside world might be initiated somewhere inside specific shrines. These design changes would break down the otherwise clean separation between Ancient Shrines and other gameplay systems and activities, and in the process contribute a bit to also making shrines feel like a more integrated part of the world.&lt;/p&gt;

&lt;h3&gt;Integrating the inside with the outside&lt;/h3&gt;

&lt;p&gt;We need to talk about caves. A Link to the Past is full of caves. Some cave entrances simply lead to a small cave room where you may find a reward like a treasure chest - possibly with a puzzle you need to solve first.&lt;br /&gt;&lt;br /&gt;Some caves have multiple entrances. Sometimes when you enter a cave you’re teased with a reward you can’t get, but you can get it if you enter via a different entrance. Other caves serve as a shortcut - or maybe as the &lt;i&gt;only&lt;/i&gt; route between two places. This makes the caves feel less like a space entirely separate from the world and more like a place that’s an integrated part of the world itself.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2QsIvdOWBVdW6GFZpc9FjFNo8Kn9orwwdrVOHG9I3pR4Onf-B3Qyvie_X5hT2oZNI3KhY-N1uKbXq_NqKOYBnK8DsyvKGil0RfidTRyXBiavN8R18ZiH6nmHO35sqIVf2P0FfHmcBb_E/s16000/CaveEntrances.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2QsIvdOWBVdW6GFZpc9FjFNo8Kn9orwwdrVOHG9I3pR4Onf-B3Qyvie_X5hT2oZNI3KhY-N1uKbXq_NqKOYBnK8DsyvKGil0RfidTRyXBiavN8R18ZiH6nmHO35sqIVf2P0FfHmcBb_E/s16000/CaveEntrances.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Cave entrances in A Link to the Past.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This all adds intrigue, because you have no idea what the nature of a given cave is before you explore it. It might be something trivial but could also be something critical to progress in the game.&lt;/p&gt;

&lt;p&gt;Now comes the extension to this I particularly like. It’s not only random &lt;i&gt;caves&lt;/i&gt; that can have multiple entrances. For a few of the dungeons, this is the case as well. For example, there’s a dungeon that you can exit through a different entrance and reach an area in the outside world that’s only accessible this way.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijRGrA3IItTS6B2T6O0rkvFK5zIS4sjgnykN0K6hsk94ruAuRnVEY2eEaXGdMN5Fyd8CWwxKznsdZczqFVJr2oisS-bRchg6vI2LOrwU0WeQEqCV5ksktPTT6OrI18LelW0W7kFbZhQ98/s16000/DungeonMultipleEntrances.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijRGrA3IItTS6B2T6O0rkvFK5zIS4sjgnykN0K6hsk94ruAuRnVEY2eEaXGdMN5Fyd8CWwxKznsdZczqFVJr2oisS-bRchg6vI2LOrwU0WeQEqCV5ksktPTT6OrI18LelW0W7kFbZhQ98/s16000/DungeonMultipleEntrances.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;The Desert Palace in A Link to the Past is a dungeon with multiple entrances.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This greatly enhances the sense of mystery for several reasons. One is, as noted for caves, that it makes it harder to predict what to expect when the boundaries between different systems and spaces are less strict. But another reason is that mystery thrives when it’s grounded. The more logical, tangible and real the places in the world feel, the better they support suspension of disbelief, and the more effective the sense of mystery becomes.&lt;/p&gt;

&lt;p&gt;Compare the dungeons and caves in A Link to the Past to the Ancient Shrines in Breath of the Wild. To get into an Ancient Shrine, you enter a small entrance above ground and soon find yourself in an enormous ornately decorated underground space. The first few times this feels super mysterious. How could this otherworldly space have been created deep underground? Astounding and unreal! But after seeing this repeatedly it begins to no longer feel unreal in a mystical way but rather in a gamey way. Is this space even located under the entrance at all? It might as well exist in a different dimension. And what difference does it even make? In the end, the game just transports you to a space entirely separate from the outside world - it’s a game thing; it’s what games &lt;i&gt;do&lt;/i&gt;. And so the suspension of disbelief is eroded, and the sense of mystery along with it.&lt;/p&gt;

&lt;h4&gt;The inside space as a continuation of the outside&lt;/h4&gt;

&lt;p&gt;Comparing caves and dungeons in ALTTP with the Ancient Shrines in BOTW shows us the importance of integrating inside spaces into the larger world.&lt;/p&gt;

&lt;p&gt;A question we can ask to determine if confined spaces in the game are disintegrated from the overall larger world is:&lt;/p&gt;

&lt;blockquote&gt;Does a given type of confined space in the game always have only a single connection to the larger world? Does navigation inside this type of space never affect navigation outside the space, and vice versa?&lt;/blockquote&gt;

&lt;p&gt;And a strategy we can make use of to increase integration is:&lt;/p&gt;

&lt;blockquote&gt;For a given type of confined space, design at least certain instances of it as a continuation of the outside space such that navigation inside and outside of the space affect each other.&lt;/blockquote&gt;

&lt;p&gt;This could be applied in Breath of the Wild to infuse a greater sense of mystery to Ancient Shrines by occasionally giving them a separate exit from the entrance. In these cases you’d emerge in the outside world somewhere else than where you entered the shrine. Maybe some spot off the beaten track, sometimes half hidden, but where it’s interesting for the player to end up?&lt;/p&gt;

&lt;p&gt;While we’re at it, we could also, rarely, have a secret entrance/exit in a shrine as well (a bit like the secret exits in Super Mario World). It could for example lead to a location in the outside world that’s &lt;i&gt;only&lt;/i&gt; accessible this way.&lt;/p&gt;

&lt;p&gt;A suggestion I’m &lt;i&gt;not&lt;/i&gt; making is to make the layout of the shrines physically match and integrate into the outside world. While it would undoubtedly be cool, it would be so much extra work to design them under that constraint that it wouldn’t be viable, when taking into account that there are hundreds of shrines in the game.&lt;/p&gt;

&lt;p&gt;Breath of the Wild already demonstrates that this kind of tight integration can be done, because the dungeon-like Hyrule Castle is designed exactly in such a tightly integrated way - and it’s awesome!&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4eex2I43yPhe030dAKqg6NTK6ffJtx_GmOw2_Qcs20t226b5p2K9vqhL9c3cw6UZgjoccDZG675fmOyGI6-J0ubz32EYA-V3cZvDLWcjy5GhHdFXmOYqVs4YamHGiTz_2tj1uhhyphenhyphenvp0Q/s16000/HyruleCastle.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4eex2I43yPhe030dAKqg6NTK6ffJtx_GmOw2_Qcs20t226b5p2K9vqhL9c3cw6UZgjoccDZG675fmOyGI6-J0ubz32EYA-V3cZvDLWcjy5GhHdFXmOYqVs4YamHGiTz_2tj1uhhyphenhyphenvp0Q/s16000/HyruleCastle.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Hyrule Castle is one of the few dungeons in Breath of the Wild that has a tight integration between the inside and outside areas.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;But there’s a difference between pulling it off once and pulling it off hundreds of times. That’s why the proposed design changes are ones I believe could have been pulled off without incurring too much extra work. In the end, a successful integration of the inside and outside of a space hinges more on the purpose and navigation of the space than on its aesthetics.&lt;/p&gt;

&lt;h3&gt;Clean design versus mystery&lt;/h3&gt;

&lt;p&gt;I’ve suggested four different strategies for increasing the sense of mystery and wonder. You’ve probably noticed they all relate in some way to reducing how formulaic and predictable a game is to the player.&lt;/p&gt;

&lt;p&gt;Classic system design wisdom that can help a large project stay manageable and maintainable is to make different systems have clear responsibilities with minimal overlap and interdependencies.&lt;/p&gt;

&lt;p&gt;In that light it’s easy to imagine that gameplay elements like Ancient Shines and Korok Seed puzzles have a sort of template that takes care of all the common elements so only unique content has to be filled in. And that makes a lot of sense from a production perspective. However, it may also inadvertently lead to a diminished sense of mystery.&lt;/p&gt;

&lt;p&gt;Ironically, I think it might be easier for designers not as experienced in making clean maintainable designs to stumble upon creating a sense of mystery, because a lack of clear consistencies in a world lends itself well to that. I even suspect that part of the reason A Link to the Past has a greater sense of mystery might be that the developers had not been forced to establish quite as efficient production processes and pipelines. After all, A Link to the Past, while large for its time, is a game of much smaller scope than Breath of the Wild.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFNMQUA7jWABTiJ1Rnj4OlLAtnRoiFMwpPihHQ3TgTuaTuCy-o-_bDp4UtSTKALb7HPmxX8vgyBwC9xcMv7h_Gizk1hR2NPHM1y6zIy71Nz1RFLYxneeP_0g2tFW77uLyQiQICJzNcfMo/s16000/WorldMap.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFNMQUA7jWABTiJ1Rnj4OlLAtnRoiFMwpPihHQ3TgTuaTuCy-o-_bDp4UtSTKALb7HPmxX8vgyBwC9xcMv7h_Gizk1hR2NPHM1y6zIy71Nz1RFLYxneeP_0g2tFW77uLyQiQICJzNcfMo/s16000/WorldMap.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;The world in A Link to the Past was large for its time, but small compared to Breath of the Wild.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The point is not to make less clean or less maintainable systems. But I think it’s worth considering whether clean and unambiguous systems (from a design and production perspective) should also be clean and unambiguous to the player. And if they shouldn’t, then applying the strategies for creating a sense of mystery can make the systems less transparent to the player.&lt;/p&gt;

&lt;h4&gt;Ambiguity versus usability&lt;/h4&gt;

&lt;p&gt;Now, more ambiguity is not always better, and the usability of a game should not be sacrificed to obtain it. For an interaction to be easy and efficient to engage with, the user needs to be able to predict the outcome of their actions. This is generally the opposite of what we need to create a sense of mystery and wonder.&lt;/p&gt;

&lt;p&gt;This means it’s important to be conscious about which elements of the game should aim for usability and which should aim for ambiguity. There is no one right way to determine that; rather, it depends on which kind of experience you want to evoke.&lt;/p&gt;

&lt;p&gt;One rule of thumb is to avoid unpredictability where it causes significant frustration for the player in a non-engaging way. In this article I’ve focused on a sense of mystery tied mostly to exploration, and I think that it’s rarely frustrating not to be able to predict what you’ll find when exploring a new area. An exception to this is if the exploration has a significant cost. For example, if a game has bottomless pits that kill you, but some secretly contain a bonus item instead, that might enhance a sense of mystery but would also be frustrating to search for. &lt;/p&gt;

&lt;p&gt;Another rule of thumb is to focus on unpredictability in gameplay elements that exist squarely within the game’s fiction, whereas focusing on usability makes sense for elements that form the interface between the player and the game. If the player can’t predict how to do something in the game (like how to jump, or how to dig a hole with a shovel) which the game’s protagonist would undoubtedly know how to do, then that leads the player’s attention to meta-elements of the game, which can diminish suspension of disbelief. On the other hand, things that are as unpredictable to the game’s protagonist within the fiction as it is to the player don’t compromise the immersion in the fiction.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpDrPLQ-qPagDjqHKJSFB-MicPRPG4zhl4ktqSUUUJXHAz0UYBSl1jGyz73fMuUc_DE16Xef1LOigZiapPr_unbFlM-GlVgNOgAImZ0DL2qly5Xnn4fv_NHFbC6rSjt6TStE_Cnlcvpww/s16000/Menu.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpDrPLQ-qPagDjqHKJSFB-MicPRPG4zhl4ktqSUUUJXHAz0UYBSl1jGyz73fMuUc_DE16Xef1LOigZiapPr_unbFlM-GlVgNOgAImZ0DL2qly5Xnn4fv_NHFbC6rSjt6TStE_Cnlcvpww/s16000/Menu.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;How to interact with a menu is rarely where you’ll want to prioritize mysterious ambiguity over usability.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Some cases are not as clear cut, for example games where the player has lots of weapons, and certain enemies are only vulnerable to certain weapons. If there are no tells and the player simply has to find out by trial and error (as happens to be the case in ALTTP), then that’s an element of unpredictability. Some people like this and feel it adds to the sense of mystery while other people consider it a case of frustratingly bad usability.&lt;/p&gt;

&lt;p&gt;Careful simultaneous attention to usability and unpredictability is also needed when it comes to puzzles. In a good puzzle it should typically be easy to predict how to interact with the elements of the puzzle, while it should be hard to predict how the individual elements in the puzzle combine into the correct solution.&lt;/p&gt;

&lt;p&gt;In general though, these rules of thumb can be bent and broken to good effect when done intentionally and for good reasons. The point is not to always optimize for one thing or the other, but to be aware of the tradeoffs and make design decisions with intentionality.&lt;/p&gt;

&lt;h3&gt;Pattern breaks&lt;/h3&gt;

&lt;p&gt;So far I’ve mostly discussed how to achieve a sense of mystery and wonder by designing systems that never get too formulaic and predictable, which keeps the player on their toes. We can call this pattern obfuscation. However, there’s an argument to be made for an alternative approach where we let things get predictable, only to then subvert the player’s expectations by breaking the established pattern. Some of the design proposals above arguably already fit that bill, but let’s take a closer look at this distinction now.&lt;/p&gt;

&lt;p&gt;While discussing a draft of this article, &lt;a href=&quot;https://bsky.app/profile/kickback.bsky.social&quot; target=&quot;_blank&quot;&gt;Nick Konstantoglou&lt;/a&gt; from KickBack said, “When the player stops seeing the world and starts seeing systems and to 100% know what to expect, the mystery dies. But it&#39;s really so easy to reintroduce the mystery element: Just break the pattern a few times. Making the player complacent and then pulling the rug under them completely resets expectations and I would argue it’s even more effective than if they never got complacent at all.” This is sometimes referred to as a pattern break.&lt;/p&gt;

&lt;p&gt;One pattern break that left a big impression on me was in Super Mario 64 when encountering the Boo ghosts in the castle. Up until this point, the castle had been strictly an “overworld” serving as a gradually expanding map giving access to the individual stages of the game. When dying in a stage, you’d be thrown out of it and back into the castle, whereas there were no enemies or dangers in the castle itself. That pattern was broken with the Boos, which pulled the rug under me and made me question my assumptions about the castle. As a side note, this pattern break also broke down one of the (assumed) distinctions that separated the stages and castle as two different classes of space. The castle made use of several other pattern breaks as well and successfully remained mysterious throughout the game.&lt;/p&gt;

&lt;figure&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT2t0nbU7RPhLYwYQu6ivSKtcJju_SfmTQ6GDDTqeWSsICDYBTvGMHznif5xOVJX_kbrLAQ645Pv4IaVdYgv653Qw6KhhMXm4o5pbY24NsjoHP7Ogie3jRxOHyxHTJBuYFZntWeZf3ZVg/s16000/MarioBoo.jpg&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT2t0nbU7RPhLYwYQu6ivSKtcJju_SfmTQ6GDDTqeWSsICDYBTvGMHznif5xOVJX_kbrLAQ645Pv4IaVdYgv653Qw6KhhMXm4o5pbY24NsjoHP7Ogie3jRxOHyxHTJBuYFZntWeZf3ZVg/s16000/MarioBoo.jpg&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Encountering Boo in the castle in Super Mario 64 subverts the otherwise safe nature of the castle.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h4&gt;To obfuscate or to break&lt;/h4&gt;

&lt;p&gt;The difference between pattern obfuscation and pattern breaks is mainly a matter of when and how frequently a pattern is mixed up and which feelings you want to evoke. Pattern obfuscation is more subtle, since the player may not become aware of a pattern in the first place but just experience an undefinable sense of mystery. On the other hand, the subversive nature of a pattern break may evoke a stronger emotion, especially if the subverted pattern was an obvious one that had gotten very predictable. This stronger feeling comes at the expense of a greater sense of boring predictability up until the pattern break happens though.&lt;/p&gt;

&lt;p&gt;The surprise of a pattern break itself is not the primary reason for its inclusion - it’s the increased sense of mystery from that point onward, due to the player no longer being sure of what to expect. As such, for a pattern break to be effective, it has to come late enough that the player has formed clear expectations based on a set pattern, but not so late that there isn’t much time for the post-break increased sense of mystery to pay off. Realistically you’ll need multiple different pattern breaks at different times to get the most out of it.&lt;/p&gt;

&lt;p&gt;From a production perspective, pattern breaks lend themselves well to be hand-crafted one-of-a-kind exceptions to a pattern, since in their nature they are infrequent. They still provide good mystery-mileage because the mystery rubs off on the remaining instances that follow the pattern. Pattern obfuscation on the other hand needs to be more systemic and often involves mixing up multiple systems, such as with the many-to-many relationship strategy.&lt;/p&gt;

&lt;p&gt;That said, there’s no hard line to be drawn between pattern obfuscation and pattern breaks. You can see it as two ends of a spectrum, and my design proposals in this article have been a bit all over that spectrum, really.&lt;/p&gt;

&lt;p&gt;In our toolset of mystery-creation, it’s good to be aware that the sense of predictability versus lack of predictability is something that can be manipulated over the course of the game and played with in various interesting ways, to different effect.&lt;/p&gt;

&lt;h3&gt;In conclusion&lt;/h3&gt;

&lt;p&gt;I’ve discussed four concrete strategies for getting more mystery-mileage out of different elements and spaces in a world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have a many-to-many relationship between the types of curiosities in the world and the types of outcomes.&lt;/li&gt;
&lt;li&gt;Reduce or eliminate signifiers that would otherwise clearly distinguish different classes of spaces from each other, or introduce exceptions that challenge or confuse simple classification.&lt;/li&gt;
&lt;li&gt;Ensure spaces and locations in the game serve multiple different gameplay modes, though not all of them have to be equally obvious.&lt;/li&gt;
&lt;li&gt;For a given type of confined space, design at least certain instances of it as a continuation of the outside space such that navigation inside and outside of the space affect each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These strategies are in no way exhaustive. They are merely examples, and don’t apply to every game. However, even if they don’t apply directly to a game, they might give you some ideas for similar strategies that do.&lt;/p&gt;

&lt;p&gt;At a more general level I’ve discussed the tradeoff between mystery and usability, and the rules of thumb to prioritize unpredictability mainly where it doesn’t cause too much frustration and where the unpredictability is situated within the world’s fiction rather than in the interface between player and game. And I’ve discussed the ways a sense of predictability versus mystery can be manipulated differently with pattern obfuscation and pattern breaks.&lt;/p&gt;

&lt;p&gt;By using these strategies and tools in our toolset, we can - without incurring significant extra costs in development - help prevent our worlds from getting predictable and formulaic, and in turn leave all the more room for players to experience a sense of mystery and wonder while exploring.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Writing an article on game design is new for me, and obviously many of the points I’ve made here are a lot more subjective than in my more technical articles. Whether you agree or disagree with them, I’d love to hear your thoughts! Let me know in the comments which games gave a particularly great sense of mystery for you when exploring them, and why you think that is.&lt;/p&gt;

&lt;h3&gt;Further reading and watching&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.gamasutra.com/view/news/353871/Game_Design_Deep_Dive_Crafting_mystery_through_gameplay_in_Nauticrawl.php&quot; target=&quot;_blank&quot;&gt;Crafting mystery through gameplay in Nauticrawl&lt;/a&gt; by Andrea Interguglielmi discusses mystery through gameplay in a very different kind of game than Zelda. It’s clear that the strategy of overlapping gameplay modes is central to this game.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=xnaXP98ioxA&quot; target=&quot;_blank&quot;&gt;Which Ocarina of Time Dungeon is the Absolute Worst One?&lt;/a&gt; by Ceave Gaming is a video (disguised as a simple listicle) that discusses how a sense of mystery and wonder is established in Ocarina of Time through pattern breaks. The video also references another video in which &lt;a href=&quot;https://youtu.be/gwsi7TEQxKc?t=2108&quot; target=&quot;_blank&quot;&gt;Jonathan Blow touches upon pattern breaks&lt;/a&gt; in a Braid commentary, though not very explicitly in relation to mystery and wonder.&lt;/p&gt;

&lt;p&gt;If you know of other writing or videos on the topic of designing for a sense of mystery and wonder, share the links below!&lt;/p&gt;

&lt;h3&gt;Update October 2024&lt;/h3&gt;

&lt;p&gt;I&#39;m honored that this article was quoted from and linked to by Mark Brown in Game Maker&#39;s Toolkit. Go watch the video, it&#39;s a good introduction to the topic of designing games to feel mysterious: &lt;a href=&quot;https://www.youtube.com/watch?v=ilnq1ZNmhoM&quot; target=&quot;_blank&quot;&gt;What Makes a Game Feel Mysterious?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Browsing the other resources referenced in that GMTK video, not many of them went to much analytical depth on the subject (or were even addressed to game designers), but this recent talk by Andrew Shouldice at GDC 2023 was excellent, with clear takeaway: &lt;a href=&quot;https://gdcvault.com/play/1029384/-TUNIC-This-Was-Here&quot; target=&quot;_blank&quot;&gt;&#39;TUNIC&#39;: This Was Here the Whole Time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Via that talk I also stumbled upon an old talk by Jim Crawford of Frog Fractions fame, which likewise has clear takeaway on the subject of mystery: &lt;a href=&quot;https://vimeo.com/91436410&quot; target=&quot;_blank&quot;&gt;Preserving a Sense of Discovery in the Age of Spoilers&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7136464973342061675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7136464973342061675' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7136464973342061675'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7136464973342061675'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2021/02/designing-for-sense-of-mystery-and.html' title='Designing for a Sense of Mystery and Wonder'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5IEG7kMLnUiddFuWKXGbyiOeru3y5twG1VrYjYBnL7UZ_X8b0Jd2mxdXyWwdprPxqFRfa-_AygDO5OGbmac0R6Imyxs6LJbicFe-d8e9U9x-tI6X7WNrdutr4TtwIRQNClleaSQW-W4E/s72-c/Cover.jpg" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-1606797486718946058</id><published>2020-12-09T12:40:00.006+01:00</published><updated>2025-05-04T20:43:52.057+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>Getting TortoiseHg on Windows to work with SourceHut&#39;s SSH authentication</title><content type='html'>&lt;p&gt;You can skip to the header below for the actual guide. Or stay here for a rambling preamble.&lt;/p&gt;

&lt;p&gt;I&#39;m a skilled programmer, but I&#39;m not a technical person. I&#39;m not &lt;i&gt;good with computers&lt;/i&gt;. Or at least I highly prefer if things just work, and I don&#39;t have to fiddle with settings and configurations.&lt;/p&gt;

&lt;p&gt;This is one reason I strongly prefer Mercurial for source control over Git. It has a higher degree of just working. (I don&#39;t want to get into an argument over this. You can question my assertion, but my preference is my preference in any case.)&lt;/p&gt;

&lt;p&gt;Unfortunately Mercurial has become a niche choice as Git has achieved overwhelming popularity, largely due to GitHub. I wouldn&#39;t really have cared about that, except it made BitBucket close down their support for Mercurial some time ago. And BitBucket was a hosting solution for Mercurial that was affordable and also &lt;i&gt;just worked&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;I and many other Mercurial lovers have then had to find alternative hosting. And I ended up with&amp;nbsp; choosing &lt;a href=&quot;https://sourcehut.org/&quot; target=&quot;_blank&quot;&gt;SourceHut&lt;/a&gt;. SourceHut is the opposite of &quot;it just works&quot;. It&#39;s made for people who identify with hacking and tinkering and knowing all the technical stuff. Why did I choose it then? The &quot;just works&quot; alternatives had pricing that just did not work for a game development use case.&lt;/p&gt;

&lt;p&gt;Now, SourceHut has been a pain to use in &lt;i&gt;many&lt;/i&gt; ways for a non-technical person like me, but I&#39;ve had the most pain at all trying to get SSH authentication to work. Unlike BitBucket, SourceHut does not allow HTTPS authentication, so you have to use SSH, and nobody ever sat down and made SSH easy to use on Windows.&lt;/p&gt;

&lt;p&gt;Getting SSH to work involved juggling things like multiple types of SSH keys and formats all placed in a hidden folder, many different helper tools, and reading dozens of half-baked how-to guides that all contradict each other, often assume prior knowledge, and that are all for slightly different use cases which means they didn&#39;t quite work for me.&lt;/p&gt;

&lt;p&gt;I got it all to work around a year ago, but I recently wiped my hard drive and needed to do it all over. I couldn&#39;t remember anything, so had to figure it all out all over again. So now I&#39;m writing my &lt;i&gt;own&lt;/i&gt; half-baked guide, mostly for my future self in case I need it again, but others might stumble over it and maybe find it useful too I guess.&lt;/p&gt;

&lt;p&gt;When you read this guide, you might think it doesn&#39;t sound that complicated after all. But remember the guide omits all the things I read I should do and which I thus attempted, but it didn&#39;t work, and eventually turned out not to be needed anyway. Like running the main PuTTy application, or running tortoiseplink, or editing your mercurial.ini file. Anyway, on to the guide.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;Getting TortoiseHg on Windows to work with SourceHut&#39;s SSH authentication&lt;/h3&gt;

&lt;p&gt;Use the instructions here to generate an SSH key and add it to sourcehut:&lt;br /&gt;&lt;a href=&quot;https://man.sr.ht/tutorials/set-up-account-and-hg.md&quot; target=&quot;_blank&quot;&gt;https://man.sr.ht/tutorials/set-up-account-and-hg.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ignore the rest, from &quot;Creating a Mercurial repository&quot; and forward. I assume you already have one, and in this guide we don&#39;t want to push with command line since we&#39;ll be using TortoiseHg.&lt;/p&gt;

&lt;p&gt;Now you should have a &lt;b&gt;id_rsa&lt;/b&gt; private key and &lt;b&gt;id_rsa.pub&lt;/b&gt; public key inside a folder called .ssh (inside your user folder), which is hidden by default. You can change Windows settings to show hidden files and folders if you want to be able to have a bit better overview.&lt;/p&gt;

&lt;p&gt;Download &lt;a href=&quot;https://www.putty.org/&quot; target=&quot;_blank&quot;&gt;PuTTY&lt;/a&gt;. Inside the PuTTY installation folder you&#39;ll also find PuTTyGen. Use PuTTyGen to create a &lt;b&gt;id_rsa.ppk&lt;/b&gt; key from the id_rsa key using the instructions here:&lt;br /&gt;
&lt;a href=&quot;https://devops.ionos.com/tutorials/use-ssh-keys-with-putty-on-windows/#use-existing-public-and-private-keys&quot; target=&quot;_blank&quot;&gt;https://devops.ionos.com/tutorials/use-ssh-keys-with-putty-on-windows/#use-existing-public-and-private-keys&lt;/a&gt;&lt;br /&gt;
Note: In the open dialog, you need to change the dialog to display &quot;all files&quot; in order to see the &lt;b&gt;id_rsa&lt;/b&gt; key. The guide above doesn&#39;t mention that. PuTTY can still import it even though it doesn&#39;t even display it by default. Save the file as &lt;b&gt;id_rsa.ppk&lt;/b&gt; inside the same .ssh folder the other keys are in. Ignore the rest of this guide. You don&#39;t need to run the main Putty application itself.&lt;/p&gt;

&lt;p&gt;Download TortoiseHg if you haven&#39;t already. In the TortoiseHg installation folder, you&#39;ll find a helper tool called Pageant. As explained in the tips and tricks section of &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty&quot; target=&quot;_blank&quot;&gt;this guide&lt;/a&gt;, we&#39;ll want Pageant to automatically load your key when it starts. I&#39;ll summarize here:&lt;/p&gt;

&lt;p&gt;Make a shortcut to Pageant if you don&#39;t have one already. Right click the shortcut and click &quot;Properties&quot;. In the Target field in the properties window, you need to keep what&#39;s already there but also add a space and then a path (in quotation marks) to your &lt;b&gt;id_rsa.pkk&lt;/b&gt; file at the end so it&#39;s automatically loaded when Pageant starts.&lt;/p&gt;

&lt;p&gt;Now, before you start up TortoiseHg you always need to run Pageant first, using the shortcut you made. Then you should be able to use TortoiseHg to pull and push with SSH authentication.&lt;/p&gt;

&lt;p&gt;However, optionally, you can automate this. You can make Windows run your Pageant shortcut on startup by moving the shortcut to the Windows startup folder: Open the “Run” dialog box by pressing the Windows key + R. Type “shell:startup” (without the quotes) in the “Open” edit box and click “OK.”. Copy the shortcut into this folder.&lt;/p&gt;

&lt;p&gt;Then you can always use Tortoise without having manually run Pageant first.&lt;/p&gt;

&lt;p&gt;That&#39;s it! If you have any issues or questions, don&#39;t hesitate to - um, to google your issues and try to figure it out. I really can&#39;t help you; I don&#39;t know what I&#39;m doing. I only barely got this to work myself, and don&#39;t really know why, or how it all works. Sorry!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/1606797486718946058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/1606797486718946058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1606797486718946058'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1606797486718946058'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2020/12/getting-tortoisehg-on-windows-to-work.html' title='Getting TortoiseHg on Windows to work with SourceHut&#39;s SSH authentication'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-1353091805875551220</id><published>2020-12-04T10:45:00.004+01:00</published><updated>2025-05-04T20:45:38.015+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="carreer"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><title type='text'>Goodbye Unity</title><content type='html'>&lt;p&gt;Today is my last day at Unity.&lt;/p&gt;

&lt;p&gt;It&#39;s been nearly 12 years since I joined the then-tiny startup with ~20 employees. Now there&#39;s over 3000 and it&#39;s been quite the ride to be part of this company while it has evolved, especially with the big role it has had in evolving the whole game industry too.&lt;/p&gt;

&lt;p&gt;Lately I&#39;ve been longing to do something smaller again, and so it&#39;s time for a new adventure in my work life to begin. Starting next week, I&#39;m a full time indie developer!&lt;/p&gt;

&lt;img border=&quot;0&quot; data-original-height=&quot;2048&quot; data-original-width=&quot;2048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY3x2lZyp0_0Pus8ycnf0ahz9lwdWuyeQWvg2rwUFVeOrnU3LX2GnVtoZNJg14Z5ZwQjgk6bj7CdB3VrhnUiqMh53RUtbmCNh2zJ8HPqdXe3IH0-QP-AOtstRlJCyUBJn0yjqPq4siIhE/s16000/rune_trees.jpg&quot; /&gt;

&lt;p&gt;For a start I&#39;ll be wrapping up my VR action-adventure game &lt;a href=&quot;https://store.steampowered.com/app/589940/Eye_of_the_Temple/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt; that I&#39;ve been working on part time for the past 4 years. There&#39;s a &lt;a href=&quot;https://store.steampowered.com/app/1365940/Eye_of_the_Temple_First_Steps/&quot; target=&quot;_blank&quot;&gt;demo on Steam&lt;/a&gt; already that has very positive reviews and I expect the full game can ship in early spring 2021.&lt;/p&gt;

&lt;p&gt;What I&#39;ll do after is not fully settled yet, but I have an idea for a (non-VR) game set in &lt;a href=&quot;https://www.youtube.com/watch?v=4ujnThRTxrQ&quot; target=&quot;_blank&quot;&gt;a big forest&lt;/a&gt; full of ruins, strange artifacts, pathways and mysteries that I might begin working on next year.&lt;/p&gt;

&lt;p&gt;My mental state at the moment is kind of a mixed bag. On the one hand I&#39;m very excited about future possibilities and being able to work on exactly what I want. On the other, my motivation and productivity is a bit flaky these days. I don&#39;t know the exact reasons, but possibilities could include:

&lt;ul style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;Uncertainty about what my everyday life will be like (though economically I&#39;ll be fine!).&lt;/li&gt;
  &lt;li&gt;Having felt unfulfilled work-wise for a good while before I quit.&lt;/li&gt;
  &lt;li&gt;Having moved to a new country this summer (from Denmark to Finland), in the middle of a pandemic where it&#39;s hard to meet new people.&lt;/li&gt;
  &lt;li&gt;Being in the end stretch of developing a game where it&#39;s mostly boring stuff left.&lt;/li&gt;
  &lt;li&gt;Dark winter setting in - that normally doesn&#39;t affect me much but could be a compounding factor still.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, I&#39;ll go easy on myself and just accept my productivity and motivation not being at its greatest right now. Perhaps I won&#39;t hit the ground running in my new indie life, but that&#39;s okay. I didn&#39;t have that much vacation this year either, so I&#39;ll see this as a chance to take it a bit easy for a little while while I adjust to my new life.&lt;/p&gt;

&lt;p&gt;All in all, not a bad place to be, and I&#39;m excited about the future!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/1353091805875551220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/1353091805875551220' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1353091805875551220'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1353091805875551220'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2020/12/goodbye-unity.html' title='Goodbye Unity'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY3x2lZyp0_0Pus8ycnf0ahz9lwdWuyeQWvg2rwUFVeOrnU3LX2GnVtoZNJg14Z5ZwQjgk6bj7CdB3VrhnUiqMh53RUtbmCNh2zJ8HPqdXe3IH0-QP-AOtstRlJCyUBJn0yjqPq4siIhE/s72-c/rune_trees.jpg" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-4780603242980071155</id><published>2019-12-31T13:47:00.008+01:00</published><updated>2025-05-07T12:42:18.939+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>Eye of the Temple in 2019</title><content type='html'>&lt;p&gt;I&#39;ve completely failed to keep up the posting in 2019, but it&#39;s not too late to write at least one post this year! Here&#39;s (almost) everything that happened with the development of &lt;a href=&quot;http://eyeofthetemple.com/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt; in 2019!&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8UMDX9il3QXfLlW_0wCyrYYJlCg7CxCvrDKPMluq82CYWW_wBy_RfeSZHidu7ei2GqQoBBr9vTzL-kLY9iEtkOf88GFVd03Vhf6yU0BZpYFrZIYLPVBkP39e60BiZ8dS0f2x3CT23FM/s1600/MonumentSquare.jpg&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8UMDX9il3QXfLlW_0wCyrYYJlCg7CxCvrDKPMluq82CYWW_wBy_RfeSZHidu7ei2GqQoBBr9vTzL-kLY9iEtkOf88GFVd03Vhf6yU0BZpYFrZIYLPVBkP39e60BiZ8dS0f2x3CT23FM/s1600/MonumentSquare.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;But first, let&#39;s look at what happened in the last part of 2018 after the previous post.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;Fall 2018&lt;/h3&gt;

&lt;p&gt;In September 2018 the game got a proper looking in-game menu replacing the old debug UI.&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/DaZllgs-fWU&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;It also got area names appearing when reaching a new area (or revisiting an old one).&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/CkweZeFYei4&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Lastly the speedrun mode got completely revamped. In the speedrun mode you can step onto platforms before timers run out to build up incredible speed - if your reactions are fast enough! This is not for the faint of heart, but if you&#39;re up for a bigger challenge than the base game provides, it&#39;s worth checking out. What&#39;s new in revamped speedrun mode is that it gives visual feedback that makes it clear how fast you need to step to rake up speed.&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/Q95jE2RVVBk&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;A big update hit in October 2018 with two new areas - Fiery Pass and Black Sanctum - as well as a whole new and rather cool-looking ability in the game which I won&#39;t reveal here.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH-YKa3qb6Jcx0fOmFSfYJk7PKNVUuFtCdByTwDJ_a0N0uxfEcmSTNSKMkuNYAjHmvICxzqsk5apPK0tK0jC5WCSZ6f1EUMameTvW8rv4RuYTXhth7GYA1f6Xtv6OEMfCcLq0Mzi0PYco/s1600/2018-10-24_FieryPass.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH-YKa3qb6Jcx0fOmFSfYJk7PKNVUuFtCdByTwDJ_a0N0uxfEcmSTNSKMkuNYAjHmvICxzqsk5apPK0tK0jC5WCSZ6f1EUMameTvW8rv4RuYTXhth7GYA1f6Xtv6OEMfCcLq0Mzi0PYco/s1600/2018-10-24_FieryPass.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;Okay, now let&#39;s look at 2019!&lt;/p&gt;

&lt;h3&gt;New area, new music, and Steam achievements&lt;/h3&gt;

&lt;p&gt;2019 started with an update in January that added a new area called The Wall as well as changes to the existing areas The Atrium, Monument Square, and The Cauldron. The temple got more &quot;tied together&quot;.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVt5gt_XICmadn3IHZ7V5Fm-eu_yWG8-bk0AqL5GSjj_G88_n8pRkvZjScXewT3PWjbqLU8vkZiI4BiKUxn-mH_HS3fetSWJkHip2nxVkbRehpl25UQ26GWu_bNWQFV-2224H-3oO5eA/s1600/2019-01-03_TheWall1.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVt5gt_XICmadn3IHZ7V5Fm-eu_yWG8-bk0AqL5GSjj_G88_n8pRkvZjScXewT3PWjbqLU8vkZiI4BiKUxn-mH_HS3fetSWJkHip2nxVkbRehpl25UQ26GWu_bNWQFV-2224H-3oO5eA/s1600/2019-01-03_TheWall1.png&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkmYSnWKf8iSoa7GaFd6AZZgiurgIFjaI7-F17CkYdpfLoOo9pOdZOLq8c4jn-yRTcpNaT12_kRGVLC2SeVOlvuFu3p6v6APwv-0Gc1AaxXXSv5YjyELmIyQ6cIgxQIELZwkR9LjZcFGY/s1600/2019-01-03_TheWall2.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkmYSnWKf8iSoa7GaFd6AZZgiurgIFjaI7-F17CkYdpfLoOo9pOdZOLq8c4jn-yRTcpNaT12_kRGVLC2SeVOlvuFu3p6v6APwv-0Gc1AaxXXSv5YjyELmIyQ6cIgxQIELZwkR9LjZcFGY/s1600/2019-01-03_TheWall2.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;January is also when the game got Steam Achievements implemented.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuusLErC1Got8Eq-G29iovX_UoImIYRO1SQ0WB4TkkNJKtgnpYP61YlGb0jgCM8rEHV0AlbknRq-S9LhemQwC7yMOEml_-zhn2zeJwwWbsZLqNZ9QkFQtDL9jsuOBDDq6Q2dG_zAJLj2s/s1600/Achievements.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuusLErC1Got8Eq-G29iovX_UoImIYRO1SQ0WB4TkkNJKtgnpYP61YlGb0jgCM8rEHV0AlbknRq-S9LhemQwC7yMOEml_-zhn2zeJwwWbsZLqNZ9QkFQtDL9jsuOBDDq6Q2dG_zAJLj2s/s1600/Achievements.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;And last but not least, a new dynamic music track was added, composed by &lt;a href=&quot;https://claudimartinez.com/&quot; target=&quot;_blank&quot;&gt;Claudio Martinez&lt;/a&gt; who&#39;s also behind the other music in the game. I implemented the track into the game such that it changes dynamically to match different moods in different areas of the game.&lt;/p&gt;

&lt;h3&gt;Satisfying combat and water splashes&lt;/h3&gt;

&lt;p&gt;In February the combat in the game was revamped to feel more satisfying. This was done based on lots of helpful feedback from the playtesters and various people on Twitter.&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/G5B0hzX-LsY&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;And water splashes were added to the areas with water for fun and immersion, though they have no effect on the gameplay as such.&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/cIanYp-PATs&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/-YOVd9swqQs&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;h3&gt;Big minecart update&lt;/h3&gt;

&lt;p&gt;A big update hit in May, where minecart rides were added to the game! To get access to it, you&#39;ll have to first get through a new added area called Creepstone Mine. A small new area was also added that&#39;s only accessible by minecart.&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/vDW11gXPbPM&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;This update also added a secret room in the game. To this day, none of the playtesters have found it yet.&lt;/p&gt;

&lt;h3&gt;New areas, and the game now has a story&lt;/h3&gt;

&lt;p&gt;An area Watergrave Arena was added in August, featuring more combat, and in October an area called Dark Ruins was added which culminates in a new kind of challenge with some tense moments. Afterwards you&#39;ll get to pick up an all new gadget.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoD68eaqvY9xAa5H-FFFkWEbuKdO_icknGNuyfuoNL25CaQQIHWLwa9CdaMZVoL9tULe8bQKJbRWDgN8SVkeIBITOSMzrlaib3GZOEgh1CABFhxE426hX08Uaai5v2VjNTJC58P17L_vM/s1600/2019-08-05_Watergrave-Arena.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoD68eaqvY9xAa5H-FFFkWEbuKdO_icknGNuyfuoNL25CaQQIHWLwa9CdaMZVoL9tULe8bQKJbRWDgN8SVkeIBITOSMzrlaib3GZOEgh1CABFhxE426hX08Uaai5v2VjNTJC58P17L_vM/s1600/2019-08-05_Watergrave-Arena.png&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdkaqhyphenhyphenDfdHnjPZCvLCTtiJzPVAwhCKaj1xtchdfchU7FCyiuM4Dl74ZE1JjuzqrrW9KAdabK6blZYm9oqQ6qxqV4nPQUQtppjXXH6SnJXyN6X0w90Yz9vaVo6KUokBGa1GDnydwU2sxM/s1600/2019-09-21_DarkRoom_exp.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdkaqhyphenhyphenDfdHnjPZCvLCTtiJzPVAwhCKaj1xtchdfchU7FCyiuM4Dl74ZE1JjuzqrrW9KAdabK6blZYm9oqQ6qxqV4nPQUQtppjXXH6SnJXyN6X0w90Yz9vaVo6KUokBGa1GDnydwU2sxM/s1600/2019-09-21_DarkRoom_exp.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;This update also added a new element to the game which is story. Bits of story can now be uncovered at a number of shrines throughout the temple. The overall story was developed in collaboration with &lt;a href=&quot;http://lexwilson.com&quot; target=&quot;_blank&quot;&gt;Lex Wilson&lt;/a&gt;. In the final game the story bits will be voice acted, but for now it&#39;s text only.&lt;/p&gt;

&lt;h3&gt;Reveal trailer&lt;/h3&gt;

&lt;p&gt;I released a reveal trailer for the game in November, which you can see here:&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/7gCnAIlqrhs&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;This was covered by &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-temple-puzzles/&quot; target=&quot;_blank&quot;&gt;UploadVR&lt;/a&gt; as well as by a few other outlets.&lt;/p&gt;

&lt;h3&gt;Looking to 2020&lt;/h3&gt;

&lt;p&gt;2020 is the year Eye of the Temple is released, unless things go terribly differently than I anticipate. (That said, I once thought it would come out in 2017.) There&#39;s one final area in the game left to do, apart from various fixes and improvements. That sounds manageable, but then, it&#39;s probably the most challenging area to design and get right, being the culmination of the game and all.&lt;/p&gt;

&lt;p&gt;If you&#39;re interested in Eye of the Temple, don&#39;t forget to add it to your wishlist on &lt;a href=&quot;https://store.steampowered.com/app/589940/Eye_of_the_Temple/&quot; target=&quot;_blank&quot;&gt;Steam&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Happy new year!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/4780603242980071155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/4780603242980071155' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4780603242980071155'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/4780603242980071155'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2019/12/eye-of-temple-in-2019.html' title='Eye of the Temple in 2019'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8UMDX9il3QXfLlW_0wCyrYYJlCg7CxCvrDKPMluq82CYWW_wBy_RfeSZHidu7ei2GqQoBBr9vTzL-kLY9iEtkOf88GFVd03Vhf6yU0BZpYFrZIYLPVBkP39e60BiZ8dS0f2x3CT23FM/s72-c/MonumentSquare.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-5451853689880072549</id><published>2018-09-17T21:38:00.009+02:00</published><updated>2025-05-14T16:21:18.982+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>Creaking Gorge and The Cauldron</title><content type='html'>&lt;p&gt;Since my &lt;a href=&quot;http://blog.runevision.com/2018/07/level-design-workflows.html&quot;&gt;last post&lt;/a&gt; in July where I finally got a vision down for the level design in Eye of the Temple, I&#39;ve been feeling super productive adding new areas and features to the game.&lt;/p&gt;

&lt;p&gt;In August I added two new areas and in September I&#39;ve been revamping the in-game UI and the speedrun mode. Only problem is I haven&#39;t kept up with these blog posts. To avoid this post getting too long, I&#39;ll cover the new areas here and save the UI work for a later post.&lt;/p&gt;

&lt;h3&gt;Creaking Gorge&lt;/h3&gt;

&lt;p&gt;Creaking Gorge is an area where you move along and into cliff sides and atop wooden scaffolding. It&#39;s by far the most vertical area in the game, spanning more than 50 meters vertically.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyqAUawsnl1PdBUWJDojkEpqemsOkNGmWhQPncsRK0rQSn_bxer19y7fgts-qztW_bEi1klsI-PrRiFgrvA6hdJX5kxzvLuOZYawNAmzumsEUvQ0b4T5Jq48bpojNqy5M2LQK0nacXmns/s1600/2018-08-04_TheGorge1.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyqAUawsnl1PdBUWJDojkEpqemsOkNGmWhQPncsRK0rQSn_bxer19y7fgts-qztW_bEi1klsI-PrRiFgrvA6hdJX5kxzvLuOZYawNAmzumsEUvQ0b4T5Jq48bpojNqy5M2LQK0nacXmns/s640/2018-08-04_TheGorge1.png&quot;&gt;&lt;/a&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;p&gt;It&#39;s a fairly non-linear area too with multiple paths that can be followed in an order you choose. The verticality combined with the fact that not all of the paths can be seen, since they carve into the cliffs, means that it can be a challenge to keep track of your orientation and where to go next.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghh1PfIF-Y4Sqt9E0HYCdupAmHiF24RoGK8GNrwf3ShFuSMxdBRh8-1jywWYotksXLSxWGooKNbvGqdRIXsiW4oIOClfgDDOioE4ewkh_MY2dcO0O9jI6TiTyezvigrfm49GQpUFkC1RM/s1600/2018-09-10_Editor_CreakingGorge.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghh1PfIF-Y4Sqt9E0HYCdupAmHiF24RoGK8GNrwf3ShFuSMxdBRh8-1jywWYotksXLSxWGooKNbvGqdRIXsiW4oIOClfgDDOioE4ewkh_MY2dcO0O9jI6TiTyezvigrfm49GQpUFkC1RM/s640/2018-09-10_Editor_CreakingGorge.png&quot;&gt;&lt;/a&gt;

&lt;p&gt;It&#39;s an area of contracts since the bright and wide open space of the gorge itself is interspersed with ventures into cliff caves with narrow corridors and dark suppressing chambers.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7U5ItNogFhSFuNqe0ky7RQcb7Z98lt1uLkIKyx3eOVCz00j_wa4x_QVY60DyaX-Ei9jWShnbLbscqo2xjn9En3pyR9kjZxoURKmdyFX9l78V-QSCJfmmftD-nvuthIIWCvcrJcogtFDI/s1600/2018-08-04_TheGorge2.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7U5ItNogFhSFuNqe0ky7RQcb7Z98lt1uLkIKyx3eOVCz00j_wa4x_QVY60DyaX-Ei9jWShnbLbscqo2xjn9En3pyR9kjZxoURKmdyFX9l78V-QSCJfmmftD-nvuthIIWCvcrJcogtFDI/s640/2018-08-04_TheGorge2.png&quot;&gt;&lt;/a&gt;

&lt;p&gt;Creating Creaking Gorge was mostly a level design job, as the elements and mechanics of it were already present in the game, apart from the wooden scaffolding which is purely visual.&lt;/p&gt;

&lt;h3&gt;The Cauldron&lt;/h3&gt;

&lt;p&gt;Following Creaking Gorge comes The Cauldron, a smaller area taking place over flowing lava and involving fire traps and puzzles.&lt;/p&gt;

&lt;p&gt;The first thing I did for The Cauldron was start working on the lava surface.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW4QFmYNFstnrotIAcjuQQUBj6GBSzwT688QcgkT9YpWfDcCb1PiZ8RPjTP-hHUglltwyuadHhGKxyvK5mtwtMcn-kRPmFHlo0XGFETfdC9jLp2UVN5teSnuFrTxke_uDZtEvqy1rzUvo/s1600/Lava.gif&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW4QFmYNFstnrotIAcjuQQUBj6GBSzwT688QcgkT9YpWfDcCb1PiZ8RPjTP-hHUglltwyuadHhGKxyvK5mtwtMcn-kRPmFHlo0XGFETfdC9jLp2UVN5teSnuFrTxke_uDZtEvqy1rzUvo/s1600/Lava.gif&quot; /&gt;&lt;/a&gt;

&lt;p&gt;I looked at existing solutions like this &lt;a href=&quot;https://assetstore.unity.com/packages/vfx/shaders/lava-flowing-shader-33635&quot; target=&quot;_blank&quot;&gt;Lava Flowing Shader&lt;/a&gt;, but its unidirectional flow is more suited to a lava river than the kind of lava pools I have.&lt;/p&gt;

&lt;p&gt;I ended up offsetting texture look-ups in two directions according to some sinus and co-sinus functions. Additionally there&#39;s a texture that maps distance to walls, so the flow can be slowed there and the lava also be darker. Here&#39;s that texture, and its effect on the lava.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifOZvwtyo3zL79bseluUCcS4uS66sAzePvVIbRiC69el8j64peMIM9wZhyphenhyphenoU1QNZhJCLowI4_qHpCwNAZZN6CjaV0fFlAV0PI1y6pJFHQSr0ZsAeN6EPdrm7tGXdiSNofVGRVn3hQs3os/s1600/RoomMap.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifOZvwtyo3zL79bseluUCcS4uS66sAzePvVIbRiC69el8j64peMIM9wZhyphenhyphenoU1QNZhJCLowI4_qHpCwNAZZN6CjaV0fFlAV0PI1y6pJFHQSr0ZsAeN6EPdrm7tGXdiSNofVGRVn3hQs3os/s640/RoomMap.png&quot; class=&quot;smallimage&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz5zlNndu29PC_0Vy9CFJeUQeL4fgHMiJxGWKO2Fve4yB3yrBSu_gpVUuFMEccGCpmdOoABU-D1w61SMs7LQrVsMCK2w-qKcLMykaoMkviWVoQD1xDd5CCRkRE3LwuH0IZAJ6uPbOAWPU/s1600/LavaMap.png&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz5zlNndu29PC_0Vy9CFJeUQeL4fgHMiJxGWKO2Fve4yB3yrBSu_gpVUuFMEccGCpmdOoABU-D1w61SMs7LQrVsMCK2w-qKcLMykaoMkviWVoQD1xDd5CCRkRE3LwuH0IZAJ6uPbOAWPU/s640/LavaMap.png&quot;&gt;&lt;/a&gt;

&lt;p&gt;The bubbles are made with a particle system emitting sphere meshes, but they looked bad when I just gave them fixed or random colors. I ended up making the regular lava texture based fully on world space look-ups, not UVs, so the bubbles could be mapped identically.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnmILQ7jVFGRPHRWQvfnhTG5i3quID_1e-deOVm5GhK3oRacS5S3OeJmeq053gRxiAnQKKbeR1mdU4SQWQaxiM6Q83b92ca7I1GwW3Un8FFvtqSAE2qy_TXTmDF0uTetEjA9YVQnKNETs/s1600/Bubbles.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnmILQ7jVFGRPHRWQvfnhTG5i3quID_1e-deOVm5GhK3oRacS5S3OeJmeq053gRxiAnQKKbeR1mdU4SQWQaxiM6Q83b92ca7I1GwW3Un8FFvtqSAE2qy_TXTmDF0uTetEjA9YVQnKNETs/s640/Bubbles.png&quot;&gt;&lt;/a&gt;

&lt;p&gt;After adding steam particles, a better lava pattern, and baked lightmaps, the result looked like this:&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVqqh7wn5hadez5K68eX8dDnuRn2hvjcXxJ-ZuA-vyRRUw6_WdlFWpaLYHkNJKoFwPl4l6kZfzSvaaVSKj-n1s9C_f8BFRiI-gzSLa7Sae4J1pfRnGx33jE9VIio2u8Ttfl0D_65aFhMI/s1600/Lava2.gif&quot; &gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVqqh7wn5hadez5K68eX8dDnuRn2hvjcXxJ-ZuA-vyRRUw6_WdlFWpaLYHkNJKoFwPl4l6kZfzSvaaVSKj-n1s9C_f8BFRiI-gzSLa7Sae4J1pfRnGx33jE9VIio2u8Ttfl0D_65aFhMI/s640/Lava2.gif&quot;&gt;&lt;/a&gt;

&lt;p&gt;After getting the lava into shape (which frankly is purely visual too but adds a lot to the feeling of the area), I got cracking working out the puzzles. For the fire-based puzzles here, I had to generalize a bit how fire propagation worked so that anything that can catch fire can be lit up by any fire source. The result is some simple puzzles where the player has to use fire in new ways than previously.&lt;/p&gt;

&lt;p&gt;Two distinct new areas done in one month! I&#39;ll have a hard time beating that in the future I think, but here&#39;s to hoping.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/5451853689880072549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/5451853689880072549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5451853689880072549'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/5451853689880072549'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2018/09/creaking-gorge-and-cauldron.html' title='Creaking Gorge and The Cauldron'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyqAUawsnl1PdBUWJDojkEpqemsOkNGmWhQPncsRK0rQSn_bxer19y7fgts-qztW_bEi1klsI-PrRiFgrvA6hdJX5kxzvLuOZYawNAmzumsEUvQ0b4T5Jq48bpojNqy5M2LQK0nacXmns/s72-c/2018-08-04_TheGorge1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-1412305303709100035</id><published>2018-07-14T23:20:00.006+02:00</published><updated>2025-05-14T16:21:36.065+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>Level design workflows</title><content type='html'>&lt;p&gt;Let me talk a bit about my workflows for doing level design in Eye of the Temple since I recently had some progress in that area.&lt;/p&gt;

&lt;p&gt;I&#39;ve been in something akin to a level design writer&#39;s block for a long time, being able to rework individual small areas, but unable to start the major world redesign that I&#39;ve been intending for over a year.&lt;/p&gt;

&lt;p&gt;Maybe calling it writer&#39;s block is pretentious - the fact is that I&#39;ve never done this sort of work before, so I may just not have developed the necessary workflows to deal with it. Anyway, I think I might have finally cracked the nut.&lt;/p&gt;

&lt;p&gt;I&#39;ve had plenty of ideas, but fragmented and not crystallized enough to get down on paper. How do you start planning a non-linear world meant to be highly interconnected and interdependent? I can talk about what eventually worked for me.&lt;/p&gt;

&lt;p&gt;I&#39;ve long pondered what type of document could help me get ideas down on paper in a quick way. In addition to text documents (glorified to-do lists) I&#39;ve been using tilemaps for sketching level designs.&lt;/p&gt;

&lt;blockquote&gt;I&amp;#39;ve been experimenting with using Unity Tilemaps as a digital replacement for pencil level design sketches. Some success so far, although I&amp;#39;m really missing rotation/flipping of selection and proper multi-selection. &lt;br /&gt;&amp;mdash; Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/935207711737860096?ref_src=twsrc%5Etfw&quot; target=&quot;_blank&quot;&gt;November 27, 2017&lt;/a&gt;&lt;/blockquote&gt;

&lt;img src=&quot;https://runevision.com/blog/twitter/tilemaps1.jpg&quot; /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;img src=&quot;https://runevision.com/blog/twitter/tilemaps2.jpg&quot; /&gt;

&lt;p&gt;These tilemaps naturally lead to obsess over details though. What recently helped me move on was allowing myself to draw free-hand inaccurate lines and gloss over the contents of rooms.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioaNAI2RVUpsQPZyBUYUR2xqiIzGzDhJikfxfHk0iHfvxMJ1GS8Ye6ibNLuD34EYJiEmcrsniw4zXoFR9gBttxm5s35U9YAinTB0i5CFIOo4XV8u8HtIjlPpcYOZo72qEi15JDQaLTMek/s1600/leveldesign-map.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;It&#39;s difficult because I have ideas for the rooms that are important and which informs their shapes. The fear of forgetting those details if I don&#39;t put them down right away is there, but have to be ignored to get on with the broader strokes.&lt;/p&gt;

&lt;p&gt;In order to inform what to draw in those broader strokes, I consult my documents with intended progression of a given section of the game. What puzzles are encountered, what abilities are learned and used. This is an iterative process where both documents are altered.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz6lRm7aJqv8POp2htgVg9-b9fKDky0BkDP0SnFaqCss7raNtpmIzvczpmJ4el5LIVQN1Vpp4ZGiEAwClZtia-U9psWDSESSWpHxbucUCYZdWEwC1R1siOKs0rRhoQsB00cSdW_MUBbMU/s1600/leveldesign-progression.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;Finally, after watching &lt;a href=&quot;https://www.youtube.com/playlist?list=PLc38fcMFcV_ul4D6OChdWhsNsYY3NA5B2&quot; target=&quot;_blank&quot;&gt;Boss Keys&lt;/a&gt; episodes by Mark Brown, I tried using his dungeon graph notation to document, then refine, how dependencies in the world works. I already had loosely these ideas in my head, but getting things into the right document form can help immensely.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjrB05MC9-cSGMOE6j7Ujvh0VpRphYJY4P7P2edXpX_UhjqBA3SSWmKIABwwleMGRttZhx3NC99OuDeiHWMQyjmRjdvMMknuuS7Y3c1DNfXNBVE6tN0bKzOnZHx7uNoKVxLH0Fsj7JzdI/s1600/leveldesign-diagram.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;These 3 document types, progressions described in text, a world map sketch, and a dependency diagram, each make certain aspects of the creative process easier, and iteratively refining them all in a complimentary manner now helps me plan out the complex world.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibC1XBMqO8RWCwzW_4sOQ88eCY1eAzTrPsA3RWvLN3bGR5oymOWm0dgCQRQydio5Z-0EblQAQ3fc83alqYxh1wSiP1FQgu4fkz37yoIeKqu50uhtVn9lv5_HBemjnvR5xXNvXRkoQ0Vpo/s1600/leveldesign-combo.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;The tilemaps are convenient in that the rough sketches can be refined into more detailed plans over individual rooms where each tile is planned, but my lesson was to only do this later, as necessary.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi-uA_rPeq0svre42d6ViQJ9O1woaDhc7v-s9FNgM0iMAZ5N5vZMAbjpq0LJKT6DVllUWhTwhJUrUzUBkGF20sZUZWa7cHluYSOD5BX9SxHc1MeR3n92-i2N3JHEp4BMKWV1EMfSd6hjQ/s1600/leveldesign-rooms.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;This is not to say that these will be the only document types I use for planning out the world. None of them capture the three-dimensionality of the world well, and white-boxing may well be the next thing I look into.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAVJt7xDzILP3CzR48d0BkZ0KgXIXXektLFuJ43Mo0mfvKL6n5A7ptJXM9yuTZ7u2WY0MToYVoQerzrb7MUZW3TCm3vyseZNIr7Oyil1BBWInjVSG3GjRuUfc24xsQkx2vK5VgfF8zwqc/s1600/leveldesign-whiteboxing.png&quot; data-original-width=&quot;1280&quot; data-original-height=&quot;720&quot; /&gt;

&lt;p&gt;That&#39;s it. A lesson learned in using various forms of documents that fit various aspects of the job in order to be able to get on with &quot;getting things down on paper&quot;.&lt;/p&gt;

&lt;p&gt;P.S. Be sure to check out Mark Brown&#39;s awesome &lt;a href=&quot;https://www.patreon.com/posts/13801754&quot; target=&quot;_blank&quot;&gt;dungeon graph template&lt;/a&gt; on his Patreon.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/1412305303709100035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/1412305303709100035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1412305303709100035'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/1412305303709100035'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2018/07/level-design-workflows.html' title='Level design workflows'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioaNAI2RVUpsQPZyBUYUR2xqiIzGzDhJikfxfHk0iHfvxMJ1GS8Ye6ibNLuD34EYJiEmcrsniw4zXoFR9gBttxm5s35U9YAinTB0i5CFIOo4XV8u8HtIjlPpcYOZo72qEi15JDQaLTMek/s72-c/leveldesign-map.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7829355925404496274</id><published>2018-04-22T11:37:00.012+02:00</published><updated>2025-05-08T16:00:49.636+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="gdc"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>New pots feature, mixed reality, Discord server, Yonderplay event </title><content type='html'>&lt;p&gt;It&#39;s time for a new update on the development of Eye of the Temple.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgK_Jo9ny0U5AgHhl44mGf0dqcfnZPTc8eKtn9FSp8i1TAv-Aqj1Z8OOR3Nvka79I75pdhB0eDivaHup3HnLumqeaKWmrPAnI1lnqJ6LLVqPtRCrjk5IFn_Hr4MtCJDVW51BnscWKc2Mo/s320/Pots.gif&quot;&gt;

&lt;h3&gt;Events&lt;/h3&gt;

&lt;p&gt;GDC in March is well behind us and I had a great time there. Among other things, I got to show off Eye of the Temple at the &lt;a href=&quot;https://soops.net/selected-games-european-game-showcase-2018/&quot; target=&quot;_blank&quot;&gt;European Game Showcase&lt;/a&gt; (and saw a lot of other cool games too). This was a private event for specially invited people from the network of the organizers.&lt;/p&gt;

&lt;p&gt;Now, Eye of the Temple has been selected for &lt;a href=&quot;http://www.copenhagengamecollective.org/2018/04/15/yonderplay-nominees/&quot; target=&quot;_blank&quot;&gt;Yonderplay&lt;/a&gt;, an event that&#39;s part of the Nordic Game Conference in Malmö in Sweden and open to everyone at the conference. This will go down on May 25, the last day of the conference. This is the most public showing of the game yet, and I&#39;m very excited about it! If you&#39;ll be at Nordic Game Conference yourself, come by and say hi and give the game a try.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgylHv9h4HcHJGkLRS3G-UP76SUWaQ1sI-HW-LRffNxh-uPNDeB3weHebWSapaz2VByRccJaYMYDLE8I6k99zYiUWV83SgSauZjDtnhYAGboIH_Ai05WKPIR6ptB_snH-gI61C_V6MdHBI/s320/Yonderplay.jpg&quot; class=&quot;smallimage&quot;&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;Mixed reality&lt;/h3&gt;

&lt;p&gt;At GDC I also met some of the fine people from &lt;a href=&quot;https://liv.tv/&quot; target=&quot;_blank&quot;&gt;LIV&lt;/a&gt;, a platform for mixed reality recording (and more) for VR content. I&#39;ve been integrating support for LIV in Eye of the Temple (it&#39;s very easy) and a handful of people from their community has been helping me test the game both with focus on mixed reality and in general.&lt;/p&gt;

&lt;p&gt;Apart from testing and feedback, I&#39;ve also been allowed to create and use some gifs from their recordings. Being able to show Eye of the Temple in mixed reality is very exciting to me, since it shows the physical nature of stepping around in the game in a way that&#39;s been impossible with regular purely virtual footage. Here&#39;s a few examples:&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI2p9CxO4HZATDEg3qjC0BlzbM5h8Y9brr19EgByHMMjVfiqo6aUIbeC2qo1svlVwsEeKA-7_n4NHG5t4qefkfunH03plxe303xssTb7fVrTkWdm18bP9HSHkKLkuET3ksk4T8z9rtm_Q/s320/rolling4.gif&quot;&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkv8NGiBigzPK1jj0XmOYLnIDek5cvyXt9LDl02lm_Ob0MhemOjLylOgUn2tLJnraCQGYD4TuyK4OrAxJzUnwHRBEuB8EBcGRMzarthYnrq6Mvux-GmDOThaTnCGox7MjWYQ7J4-8UwEM/s320/rolling5.gif&quot;&gt;

&lt;p&gt;These gifs are featuring ThreeDee from &lt;a href=&quot;https://www.facebook.com/comedypipe&quot; target=&quot;_blank&quot;&gt;ComedyPipe&lt;/a&gt;. I tweeted them &lt;a href=&quot;https://twitter.com/eyeofthetemple/status/984448098234757120&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/eyeofthetemple/status/987029474943406081&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would love to have mixed reality gifs with others playing the game as well. If you have Vive or Oculus Rift with a mixed reality setup and is up for it, please get in touch!&lt;/p&gt;

&lt;h3&gt;Discord server&lt;/h3&gt;

&lt;p&gt;For a long time I&#39;ve been using itch&#39;s forum feature to talk with early testers of the game, but I&#39;m now beginning to move more towards Discord. I&#39;ve only just learned about Discord recently, but have been happy with it so far. Feel free to join!&lt;/p&gt;

&lt;a href=&quot;https://discord.gg/yGN7bDQ&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiASFQaGWILDtRnqE_YtyO_BSA3OJCzqaydLtnNp7uz5wbCMC1L8C2OEZh66aNNYDLA23_0-2CkSALfyqSq1CKPbxfEoUJq0a8EVzI6jGa80NP3AMhDhgVizLdLgkA43SyICGx_F-eoo4w/s320/Discord.png&quot; class=&quot;noshadow smallimage&quot;&gt;&lt;/a&gt;

&lt;p&gt;&lt;a href=&quot;https://discord.gg/yGN7bDQ&quot; target=&quot;_blank&quot;&gt;Here&#39;s an invite link to the Eye of the Temple Discord server&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Pots&lt;/h3&gt;

&lt;p&gt;Last but not least, I just implemented a new feature in the game: Pots!&lt;/p&gt;

&lt;p&gt;Pots contain gems. You can tap the pots gently to get the gems out a few at a time or just smash the pots with your whip or torch to get all the gems all at once. But that would be a shame for such antique and rare pottery, now wouldn&#39;t it?&lt;/p&gt;

&lt;p&gt;The pots give players more opportunities to use the whip, which I think was much needed. They also add more physicality to the game, since the pots (and the shards if they&#39;re smashed) are physics-driven objects. Hopefully it also adds just a bit of player expressiveness potential and unpredictability to the game.&lt;/p&gt;

&lt;p&gt;A player can intentionally smash a pot, or intend to just brush it softly with the whip to tease out gems in a non-destructive way. This can however still accidentally make it topple over and fall down and get smashed way below. Players could set goals for themselves to smash all pots or avoid smashing any. Whether this will happen in practice is yet to be seen but it at least feels nice to me to allow for different approaches like this.&lt;/p&gt;

&lt;p&gt;I made this silly and crudely acted video showcasing the new pots. Do you enjoy pottery too? Let me know in the comments!&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/xzc_JGI75OA?rel=0&quot; allowfullscreen&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7829355925404496274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7829355925404496274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7829355925404496274'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7829355925404496274'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2018/04/new-pots-feature-mixed-reality-discord.html' title='New pots feature, mixed reality, Discord server, Yonderplay event '/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgK_Jo9ny0U5AgHhl44mGf0dqcfnZPTc8eKtn9FSp8i1TAv-Aqj1Z8OOR3Nvka79I75pdhB0eDivaHup3HnLumqeaKWmrPAnI1lnqJ6LLVqPtRCrjk5IFn_Hr4MtCJDVW51BnscWKc2Mo/s72-c/Pots.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-6056152287759941815</id><published>2018-03-20T02:20:00.002+01:00</published><updated>2025-05-07T12:48:58.219+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="gdc"/><category scheme="http://www.blogger.com/atom/ns#" term="press"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>New trailer, public Steam page and Eye of the Temple in the press!</title><content type='html'>&lt;p&gt;Last week I took a dive into the world of PR with Eye of the Temple.&lt;/p&gt;

&lt;p&gt;There is a new trailer you can see on the website &lt;a href=&quot;http://eyeofthetemple.com/&quot; target=&quot;_blank&quot;&gt;eyeofthetemple.com&lt;/a&gt; or right here below.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube.com/embed/EFSlcqJKqIs?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;And Eye of the Temple now has a Steam page: &lt;a href=&quot;http://store.steampowered.com/app/589940/Eye_of_the_Temple/&quot; target=&quot;_blank&quot;&gt;Eye of the Temple on Steam&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a Vive or Oculus Rift, and think Eye of the Temple looks interesting, you can totally add it to your wishlist on Steam now! ;)&lt;/p&gt;

&lt;p&gt;After that I took my first stab at contacting the press with a press release. The story got picked up by &lt;a href=&quot;https://uploadvr.com/eye-of-the-temple-vr-game-requires-room-scale-locomotion/&quot; target=&quot;_blank&quot;&gt;UploadVR&lt;/a&gt; and a handful of smaller outlets (see list on the &lt;a href=&quot;http://eyeofthetemple.com/sanctumdreams/&quot; target=&quot;_blank&quot;&gt;Sanctum Dreams&lt;/a&gt; website). Considering I&#39;m an unknown small indie developer with no experience with the press, I&#39;m pretty happy with the results.&lt;/p&gt;

&lt;p&gt;This week I&#39;m at Game Developers Conference in San Francisco. I&#39;m mostly here with Unity, but I&#39;ll also be showing Eye of the Temple at the &lt;a href=&quot;https://soops.net/selected-games-european-game-showcase-2018/&quot; target=&quot;_blank&quot;&gt;European Game Showcase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Exciting times!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/6056152287759941815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/6056152287759941815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6056152287759941815'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/6056152287759941815'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2018/03/new-trailer-and-public-steam-page.html' title='New trailer, public Steam page and Eye of the Temple in the press!'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/EFSlcqJKqIs/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-134098166691976585</id><published>2018-01-30T21:59:00.002+01:00</published><updated>2025-05-07T12:49:34.195+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>January 2018 update</title><content type='html'>&lt;p&gt;It seems like I didn&#39;t blog since July. How scandalous! Well, here&#39;s an update on what I worked on for &lt;a href=&quot;http://EyeOfTheTemple.com&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt; since then.&lt;/p&gt;

&lt;p&gt;Presented as a series of tweets, because that&#39;s what I have time for.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Add blockers seem to sometimes randomly block some of the embedded tweets for some reason.&lt;/p&gt;

&lt;h3&gt;Prettier background environment&lt;/h3&gt;

&lt;p&gt;The cold snowy mountains didn&#39;t give the feeling I was aiming for. Failing to find anything ready-made that fit the bill, I created my own lush, mountainous environment.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;What do you think of this new environment art for the backdrop of the temple that we&amp;#39;ve been working on? &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCvive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCvive&lt;/a&gt; &lt;a href=&quot;https://t.co/ASGxGCeG3p&quot;&gt;pic.twitter.com/ASGxGCeG3p&lt;/a&gt;&lt;/p&gt;&amp;mdash; Eye of the Temple (@eyeofthetemple) &lt;a href=&quot;https://twitter.com/eyeofthetemple/status/910535662939643906?ref_src=twsrc%5Etfw&quot;&gt;September 20, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Another shot of the mountains surrounding the temple. &lt;a href=&quot;https://twitter.com/hashtag/screenshotsaturday?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#screenshotsaturday&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCvive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCvive&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/madewithunity?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#madewithunity&lt;/a&gt; &lt;a href=&quot;https://t.co/GmfAwyzPvp&quot;&gt;pic.twitter.com/GmfAwyzPvp&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/911583284097961985?ref_src=twsrc%5Etfw&quot;&gt;September 23, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Failed attempts at mixed reality capture with StereoLabs ZED stereo camera&lt;/h3&gt;

&lt;p&gt;I think a mixed reality video would be the ideal way to show off Eye of the Temple, so I invested a bit in this. Unfortunately it didn&#39;t go well due to a combination of a bad choice of immature tech, and an insufficient green-screen setup. I might revisit this in the future though.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/Stereolabs3D?ref_src=twsrc%5Etfw&quot;&gt;@stereolabs3D&lt;/a&gt; Could you show how this 3D printed mount is meant to be used with a Vive controller and tracker respectively? &lt;a href=&quot;https://t.co/UqoEm0E77v&quot;&gt;pic.twitter.com/UqoEm0E77v&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/909038642693328896?ref_src=twsrc%5Etfw&quot;&gt;September 16, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p dir=&quot;ltr&quot; lang=&quot;en&quot;&gt;It&#39;s designed to hold a Vive controller, a tracker and even an oculus touch. &lt;a href=&quot;https://t.co/yc4fC2J5ZJ&quot;&gt;pic.twitter.com/yc4fC2J5ZJ&lt;/a&gt;&lt;/p&gt;
— Stereolabs (@Stereolabs3D) &lt;a href=&quot;https://twitter.com/Stereolabs3D/status/909045843835187200?ref_src=twsrc%5Etfw&quot;&gt;September 16, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I posted a video here with my troubles. See tracking issue at 8:04. I mailed your support with more details. &lt;a href=&quot;https://t.co/DCk6KeRO0O&quot;&gt;https://t.co/DCk6KeRO0O&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/911656554012737537?ref_src=twsrc%5Etfw&quot;&gt;September 23, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Argh! Mixed reality recording is hard! &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/mixedreality?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#mixedreality&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://t.co/YWVH6oFgc9&quot;&gt;pic.twitter.com/YWVH6oFgc9&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/912787665795330049?ref_src=twsrc%5Etfw&quot;&gt;September 26, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Glowy light for certain platforms&lt;/h3&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Any Unity shader experts who might know why I get heavy banding on alpha of frag function output on Windows (but not Mac)? &lt;a href=&quot;https://t.co/Xrq8CliYNo&quot;&gt;pic.twitter.com/Xrq8CliYNo&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/919896403530436608?ref_src=twsrc%5Etfw&quot;&gt;October 16, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I made a spiky glow for this platform. Helps a bit with awareness of edges without having to look down all the time. &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://t.co/I9ScvbmzZL&quot;&gt;pic.twitter.com/I9ScvbmzZL&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/920382787361890305?ref_src=twsrc%5Etfw&quot;&gt;October 17, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;New build for testers with whip and other improvements&lt;/h3&gt;

&lt;p&gt;I finally finished developing the whip and got a build out to the testers.&lt;/p&gt;

&lt;iframe allowfullscreen src=&quot;https://www.youtube.com/embed/Z8Nl_KKb-WQ?rel=0&quot;&gt;&lt;/iframe&gt;

&lt;h3&gt;Trying to recruit people to test the speedrun mode (never had any luck!)&lt;/h3&gt;

&lt;p&gt;The speedrun mode is super fun and challenging to me, but nobody else seem interested in it. Besides asking on twitter I also contacted some of the notable VR speedrunners and people who has posted about VR speedrunning on Reddit, but got nothing out of it. If anyone reading this have a Vive and would like to try it, do let me know!&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/hashtag/speedrunning?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#speedrunning&lt;/a&gt; in &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; with &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt;? Anyone want to give the speedrun mode of &lt;a href=&quot;https://twitter.com/eyeofthetemple?ref_src=twsrc%5Etfw&quot;&gt;@eyeofthetemple&lt;/a&gt; a go? &lt;a href=&quot;https://t.co/6g2WSQ2jnT&quot;&gt;https://t.co/6g2WSQ2jnT&lt;/a&gt; &lt;a href=&quot;https://t.co/MtVtMKdLC0&quot;&gt;pic.twitter.com/MtVtMKdLC0&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/923491604593348608?ref_src=twsrc%5Etfw&quot;&gt;October 26, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Implemented a new type of dangerous rooms for the temple&lt;/h3&gt;

&lt;p&gt;The reviews for this feature are through the roof.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Watch out! Working on a new type of danger in &lt;a href=&quot;https://twitter.com/eyeofthetemple?ref_src=twsrc%5Etfw&quot;&gt;@eyeofthetemple&lt;/a&gt;... &lt;a href=&quot;https://twitter.com/hashtag/screenshotsaturday?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#screenshotsaturday&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://t.co/95uYeL3b86&quot;&gt;pic.twitter.com/95uYeL3b86&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/924254910694248448?ref_src=twsrc%5Etfw&quot;&gt;October 28, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;It&#39;s getting tight in here. &lt;a href=&quot;https://twitter.com/eyeofthetemple?ref_src=twsrc%5Etfw&quot;&gt;@eyeofthetemple&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/screenshotsaturday?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#screenshotsaturday&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://t.co/Tvrd3OcWk2&quot;&gt;pic.twitter.com/Tvrd3OcWk2&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/924256694959558657?ref_src=twsrc%5Etfw&quot;&gt;October 28, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&quot;What do you mean I have to get in there!?&quot; New room in &lt;a href=&quot;https://twitter.com/eyeofthetemple?ref_src=twsrc%5Etfw&quot;&gt;@eyeofthetemple&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/screenshotsaturday?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#screenshotsaturday&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://t.co/7lE2iqorVD&quot;&gt;pic.twitter.com/7lE2iqorVD&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/924260512657002496?ref_src=twsrc%5Etfw&quot;&gt;October 28, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Got serious working on the big level design overhaul&lt;/h3&gt;

&lt;p&gt;Still far from finished with this one.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I&#39;ve been experimenting with using Unity Tilemaps as a digital replacement for pencil level design sketches. Some success so far, although I&#39;m really missing rotation/flipping of selection and proper multi-selection. &lt;a href=&quot;https://t.co/jT2PZloAYE&quot;&gt;pic.twitter.com/jT2PZloAYE&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/935207711737860096?ref_src=twsrc%5Etfw&quot;&gt;November 27, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I&#39;m using &lt;a href=&quot;https://twitter.com/hashtag/unity3d?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#unity3d&lt;/a&gt; tilemaps for level design planning of multi-story structures. Moving things around becomes a pain though; having to do it separately for each layer. Any better alternatives? &lt;a href=&quot;https://t.co/STSb8AarvB&quot;&gt;pic.twitter.com/STSb8AarvB&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/946715450020368385?ref_src=twsrc%5Etfw&quot;&gt;December 29, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Worked on a texture tool &quot;Bricker&quot; to easily create bricks and carved shapes&lt;/h3&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I&#39;ve been continuing refining my tool for generating textures+normals from simple color masks. Output quality is getting there... &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://t.co/jWzCUdc6Oz&quot;&gt;pic.twitter.com/jWzCUdc6Oz&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/940280055669972992?ref_src=twsrc%5Etfw&quot;&gt;December 11, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;More on that in another post.&lt;/p&gt;

&lt;h3&gt;Contracted a few pieces of concept art to get inspiration for improving the visual look of the game&lt;/h3&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I&#39;ve had decent progress towards realizing the concept art vision for &lt;a href=&quot;https://twitter.com/eyeofthetemple?ref_src=twsrc%5Etfw&quot;&gt;@eyeofthetemple&lt;/a&gt;. I&#39;ll put further work on that on hold for now and focus again on a level design overhaul. &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/screenshotsaturday?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#screenshotsaturday&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCvive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCvive&lt;/a&gt; &lt;a href=&quot;https://t.co/csUc4C5o7p&quot;&gt;pic.twitter.com/csUc4C5o7p&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/944619388036149248?ref_src=twsrc%5Etfw&quot;&gt;December 23, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;And finally, introduced this little birdy&lt;/h3&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Bird spotted by the temple. &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/birds?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#birds&lt;/a&gt; &lt;a href=&quot;https://t.co/x8W7IRm54g&quot;&gt;pic.twitter.com/x8W7IRm54g&lt;/a&gt;&lt;/p&gt;
— Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/952936529806192640?ref_src=twsrc%5Etfw&quot;&gt;January 15, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;https://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;That&#39;s it for now. Hope you enjoyed this glimpse into the development, and see you soon. Back to working on the game for me!&lt;/p&gt;

&lt;p&gt;Remember you can also follow the development as it happens following &lt;a href=&quot;https://twitter.com/EyeOfTheTemple&quot; target=&quot;_blank&quot;&gt;@EyeOfTheTemple&lt;/a&gt; or &lt;a href=&quot;https://twitter.com/runevision&quot; target=&quot;_blank&quot;&gt;@runevision&lt;/a&gt; on twitter.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/134098166691976585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/134098166691976585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/134098166691976585'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/134098166691976585'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2018/01/january-2018-update.html' title='January 2018 update'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/Z8Nl_KKb-WQ/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7837371485369054479</id><published>2017-08-03T00:26:00.005+02:00</published><updated>2025-05-14T16:23:28.100+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="modeling"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>July update: Trials and triumphs of whips and levers</title><content type='html'>&lt;p&gt;Here&#39;s the latest updates on the development of my Vive VR game &lt;a href=&quot;http://blog.runevision.com/search/label/Eye%20of%20the%20Temple&quot;&gt;Eye of the Temple&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the past several months I&#39;ve been working on improving the whip I prototyped last year. In the &lt;a href=&quot;http://blog.runevision.com/2017/06/june-update-verticality-puzzles-whip.html&quot;&gt;last post&lt;/a&gt;, I showed how it could grab levers, but there were a lot of issues and the whip and lever didn&#39;t exactly look pretty. Now see what it looks like now:&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/RUMls6J6drY?rel=0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;This feels really good to use now. It didn&#39;t get to this point without a lot of issues on the way though.&lt;/p&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93JdvOdH-HshkO6ZGX0CPlTfcOwMGcaTDpITTzowKeGkCPqmxhV7ycsw6i5SdDSmyTPzdExenzQe8bc7ELLurM5QfZLBdqOUZEUvwXMqGEUQkkK7cS5MZ-kDjgiIPKYyqKmdA_ci31Co/s1600/HingeJointIssues.gif&quot; style=&quot;display: none;&quot;&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;h3&gt;The whip&lt;/h3&gt;

&lt;p&gt;A bit of background on how the whip is implemented in broad strokes. Using physics joints etc. quickly turned out infeasible when I did the prototype last fall. Instead, I’m keeping track of positions and velocities of “links” in arrays in my own scripts and doing very custom simulation with lots of tweaks and workarounds. One of the needed things to make it behave whip-like is that in the spring code that maintains distance between adjacent links, one link should affect the other slightly more than the other affects the first. This is to simulate the fact that the whip gets thinner towards the end, which is critical for whip-like behavior.&lt;/p&gt;

&lt;p&gt;Collisions with level geometry works by doing sphere-casts, one per whip link per frame, which is around 30. The spherecasts are from the previous position of a segment to its new position, and if anything was hit, I move the new position to the intersection point, which should be in between the old and the original new position. That&#39;s the basics.&lt;/p&gt;

&lt;p&gt;There&#39;s special logic that makes the stick of the levers &quot;sticky&quot; and &quot;unsticky&quot; at specific times, which aids the behavior, but the way the whip curls around the stick (or fails to curl, sometimes) is still driven by the regular simulation apart from that. For all other surfaces, there&#39;s no special logic. It uses the sphere-cast based collision avoidance I mentioned above.&lt;/p&gt;

&lt;p&gt;I should say there&#39;s a glaring issue in my collision approach which isn&#39;t shown in the video, which is that collision fails against moving surfaces, such as the moving platforms. I&#39;m not quite sure if I want to solve that, because it&#39;s going to add tons of complexity to the code, while probably also degrade performance significantly. I&#39;ve chosen to ignore this for now, since there&#39;s no lack of other things that need to be done that are more critical.&lt;/p&gt;

&lt;h3&gt;The lever&lt;/h3&gt;

&lt;p&gt;The lever has caused me all kinds of problems. Doing a lever that works properly, particularly for VR, is apparently a complicated problem. I made a video about my woes here:&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/lq7oFo2wJ74?rel=0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;I found out that levers could be made to avoid sliding out of their joints given three criteria are met:&lt;/p&gt;

&lt;p&gt;First, the collider of the lever handle must not overlap with any other colliders in the world. The tricky thing here is that it&#39;s not easy to see that overlapping colliders might affect the handle, since the handle is firmly locked in place. But they do affect it in very non-obvious ways. So I ensured the handle collider doesn&#39;t overlap with any other colliders.&lt;/p&gt;

&lt;p&gt;Secondly, the rigidbody must have its position set to locked.&lt;/p&gt;

&lt;p&gt;Thirdly, the center of mass of the rigidbody must be overwritten in script to be set to the pivot that the handle should rotate around.&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93JdvOdH-HshkO6ZGX0CPlTfcOwMGcaTDpITTzowKeGkCPqmxhV7ycsw6i5SdDSmyTPzdExenzQe8bc7ELLurM5QfZLBdqOUZEUvwXMqGEUQkkK7cS5MZ-kDjgiIPKYyqKmdA_ci31Co/s1600/HingeJointIssues.gif&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93JdvOdH-HshkO6ZGX0CPlTfcOwMGcaTDpITTzowKeGkCPqmxhV7ycsw6i5SdDSmyTPzdExenzQe8bc7ELLurM5QfZLBdqOUZEUvwXMqGEUQkkK7cS5MZ-kDjgiIPKYyqKmdA_ci31Co/s1600/HingeJointIssues.gif&quot;/&gt;&lt;/a&gt;

&lt;p&gt;Unfortunately, this leads to another problem. Sometimes the lever handle would get completely stuck, in which case no amount of forces would make it move one bit. After some experimentation, this seemed to happen if the handle is exerted to forces while the connected rigidbody (which is kinematic) simultaneously move. (Some levers in my game sometimes get moved around.) I worked around this by disabling the rigidbody position locking at strategic times and then reenabling it again. This seemed to fix the issue.&lt;/p&gt;

&lt;h3&gt;Polishing it up&lt;/h3&gt;

&lt;p&gt;After I had gotten most of the technical issues resolved, I set out to create proper 3d models for the whip and lever to replace the simple cylinder placeholders I had before.&lt;/p&gt;

&lt;p&gt;And as the last step, I added the ability for the whip to be rolled up (which it now is by default). The whip is still fully simulated while rolled up, which is what gives the rolled up whip its nice juicy appearance. There&#39;s no animation or pre-canned movements involved in the whip at all.&lt;/p&gt;

&lt;p&gt;The transition where the whip gets rolled up is done by pulling at specific segments of the whip towards a specific point on the handle. This happens to also be how the whip remains rolled up in general.&lt;/p&gt;

&lt;p&gt;In the video I do a little upwards flick and then the whip rolls up. This is purely &quot;role playing&quot; though. The rolling up is actually triggered just by pressing a button on the controller. ;)&lt;/p&gt;

&lt;p&gt;If you&#39;ve been following the development of Eye of the Temple, does the whip related gameplay change how you view the game? What do you think it adds to it?&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7837371485369054479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7837371485369054479' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7837371485369054479'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7837371485369054479'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2017/08/july-update-trials-and-triumphs-of.html' title='July update: Trials and triumphs of whips and levers'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/RUMls6J6drY/default.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1667313809239009473.post-7077323238186534736</id><published>2017-06-13T19:36:00.001+02:00</published><updated>2025-05-05T13:28:40.495+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="Eye of the Temple"/><category scheme="http://www.blogger.com/atom/ns#" term="game design"/><category scheme="http://www.blogger.com/atom/ns#" term="game development"/><category scheme="http://www.blogger.com/atom/ns#" term="unity"/><category scheme="http://www.blogger.com/atom/ns#" term="video"/><category scheme="http://www.blogger.com/atom/ns#" term="vr"/><title type='text'>June update: Verticality, puzzles, whip</title><content type='html'>&lt;p&gt;Here&#39;s the latest updates on the development of my Vive VR game &lt;a href=&quot;http://blog.runevision.com/search/label/Eye%20of%20the%20Temple&quot; target=&quot;_blank&quot;&gt;Eye of the Temple&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the past month I&#39;ve been mainly working on improving the whip I prototyped last year. It can now be used to grab levers at a distance, and then you can yank the whip backwards to activate the lever.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Testing whip and lever in Eye of the Temple. Still some way to go, but getting there. &lt;a href=&quot;https://twitter.com/hashtag/gamedev?src=hash&quot;&gt;#gamedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/indiedev?src=hash&quot;&gt;#indiedev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/vr?src=hash&quot;&gt;#vr&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCvive?src=hash&quot;&gt;#HTCvive&lt;/a&gt; &lt;a href=&quot;https://t.co/8TZHflQnM2&quot;&gt;pic.twitter.com/8TZHflQnM2&lt;/a&gt;&lt;/p&gt;&amp;mdash; Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/865945952988934144&quot;&gt;May 20, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;There&#39;s still some way to go, especially with getting the audio cues right. The physics will never be quite like a real whip, but making it satisfying to use is the top priority.&lt;/p&gt;

&lt;p&gt;Apart from this I&#39;ve been looking into designing more puzzles for the game. I&#39;m no expert puzzle designer, but bit by bit I come up with some that I think work well. The latest involve tall rotating towers, activated by levers (no whip use necessary for this one) where you need to step around on and in them at two different levels.&lt;/p&gt;

&lt;p&gt;This also marks my increased effort in making better use of verticality in the level design. Experiencing the great heights is a draw of the game, and I&#39;m figuring out how to use that optimally.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&amp;quot;Add more verticality&amp;quot; they said, and I agree! New puzzle elements in &lt;a href=&quot;https://twitter.com/eyeofthetemple&quot;&gt;@eyeofthetemple&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/VR?src=hash&quot;&gt;#VR&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/HTCVive?src=hash&quot;&gt;#HTCVive&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/madewithunity?src=hash&quot;&gt;#madewithunity&lt;/a&gt; &lt;a href=&quot;https://t.co/hvxgYxW0uR&quot;&gt;https://t.co/hvxgYxW0uR&lt;/a&gt; &lt;a href=&quot;https://t.co/tjDuCk2ufo&quot;&gt;pic.twitter.com/tjDuCk2ufo&lt;/a&gt;&lt;/p&gt;&amp;mdash; Rune Skovbo Johansen (@runevision) &lt;a href=&quot;https://twitter.com/runevision/status/874672280848261121&quot;&gt;June 13, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;I don&#39;t have a new build with these new things yet. The work right now is on smaller isolated pieces and puzzles, and once I have a set of those that fit nicely together, I&#39;ll begin integrating it all back into the overall world design.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.runevision.com/feeds/7077323238186534736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/1667313809239009473/7077323238186534736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7077323238186534736'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/1667313809239009473/posts/default/7077323238186534736'/><link rel='alternate' type='text/html' href='https://blog.runevision.com/2017/06/june-update-verticality-puzzles-whip.html' title='June update: Verticality, puzzles, whip'/><author><name>Rune Skovbo Johansen</name><uri>http://www.blogger.com/profile/10793811736803423054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8j3N5S7St2YrS4MexwRChJXSMRg73oyI2vJujrrkpFrHOasaFPCcr-wiYIUZSo5MqqYww_-aFJ0dqM7ryHZooJsOTQCAuGOcoZkSaSdf8_hM9Whyphenhyphen-9a-k4iknw2upN_0Ng2otPK1-FZl48yoGzqe3U9FV9NynYLyL4Q2O_sUFDrZGEA/s220/rune_2024_lookupleft.png'/></author><thr:total>0</thr:total></entry></feed>