<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://moldling.com/</id>
    <title>Moldling Dev Blog</title>
    <updated>2026-10-17T20:58:48.647Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <author>
        <name>soraslove</name>
        <email>contact@soras.love</email>
        <uri>https://soras.love/</uri>
    </author>
    <link rel="alternate" href="https://moldling.com/"/>
    <link rel="self" href="https://moldling.com/api/atom.xml"/>
    <subtitle>A feed containing the latest blog posts about the development of the game Moldling.</subtitle>
    <icon>https://moldling.com/favicon.ico</icon>
    <rights>all rights reserved 2025 - 2026, soraslove</rights>
    <entry>
        <title type="html"><![CDATA[Dev-Log: Ray Traced Shadows]]></title>
        <id>https://moldling.com/blog/2026-06-06-ray-traced-shadows</id>
        <link href="https://moldling.com/blog/2026-06-06-ray-traced-shadows"/>
        <link rel="enclosure" href="https://moldling.com/blog/2026-06-06-ray-traced-shadows/thumbnail.png" type="image/png"/>
        <updated>2026-06-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Implementation of real time ray traced shadows.]]></summary>
        <content type="html"><![CDATA[<p>Every now and then I try to experiment with the visuals of my game to see if there&#39;s anything I can improve on. This
time I wanted to see if I could implement dynamic shadows to make my game look a little less flat.</p>
<p>This was hugely inspired by the shadows
in <a href="https://rainworldgame.com/" target="_blank" rel="noopener noreferrer">Rain World</a>
and <a href="https://ironbramble.com/" target="_blank" rel="noopener noreferrer">Iron Bramble</a>.</p>
<p><strong>First:</strong> Results!</p>
<p>The top video is the before and below is the after.</p>
<p><video src="https://moldling.com/blog/2026-06-06-ray-traced-shadows/before.mp4" controls></video>
<video src="https://moldling.com/blog/2026-06-06-ray-traced-shadows/after.mp4" controls></video></p>
<p>It&#39;s a very subtle change, but I think it achieves my goal of giving my world more visual depth.</p>
<p>First of all, my game is made in (my custom fork of) Godot so some of the implementation details will be specific to
that, but the general idea can be applied to other environments.</p>
<p>Alright, onto how I made this. Since I was inspired by Rain World I first tried to see if there were any resources on
how they implemented their shadows. I found
this <a href="https://x.com/joar_lj/status/1525445116789497856" target="_blank" rel="noopener noreferrer">Twitter
thread</a> which explains nicely how they approached their implementation. I used this as a starting point, but ended
up diverging from it and working on my own approach.</p>
<h2>Rendering the depth map(s)</h2>
<p>The first thing we need is a depth map of our scene. I did this by assigning each object (CanvasItem) in my scene a
depth value and an optional depth texture in case I want the depth to vary across the object. Each object also has a
boolean called <code>is_solid</code> which decides if the object is solid (meaning that no light rays can pass behind the
object), or if the object is flat (meaning that light can pass behind the object, just not through the object). Things
like doors are solid since I don&#39;t want any light to pass through them. Additionally, every light source also has a
depth, which comes into play later.</p>
<p>Then I create two additional render passes (using SubViewports in Godot) which render my depth maps. They use the
aforementioned depth values and textures and calculate the objects total depth based on those (depth value +/- depth in
the texture). The first pass renders all the solid objects, the second one all the flat (non-solid) ones. These get
stored in textures and are used in my shader.</p>
<details>
    <summary>Technical Note</summary>
    <div>
        <p>
        The depth value was implemented by adding a depth property
        to the CanvasItem node.<br/>The depth texture was done by adding a depth texture property to the CanvasTexture
        resource.<br/>Both of these properties get passed onto the canvas shader.
        </p>
        <hr/>
        <p>
        The render passes were done by
        adding an overwrite material property to Viewports. This overwrite material gets applied to all elements rendered in the
        viewport and handles the depth.
        </p>
    </div>
</details>

<p>The depth maps end up looking something like this:</p>
<p>First the solid one, second the flat one.</p>
<img src="https://moldling.com/blog/2026-06-06-ray-traced-shadows/depth-map-solid.png">
<img src="https://moldling.com/blog/2026-06-06-ray-traced-shadows/depth-map-thin.png">

<h2>Rendering the shadows</h2>
<p>Now that we have depth maps &quot;all&quot; that is left is to actually calculate the shadows. This is done in my main shader
which is used for every CanvasElement. I have a function in my fragment shader that gets executed for every fragment of
every light source.</p>
<p>The basic idea is this: We shoot a ray from our current position to the light&#39;s position and if we hit anything, then we
are in shade.</p>
<p>In detail this means the following:</p>
<ol>
<li>We get the lights depth value. If the depth value is 0.0 then no shadows will be drawn (we don't want this light to draw shadows).</li>
<li>Then we get the current position by taking the <code>SCREEN_UV</code>.</li>
<li>Then we sample both depth maps (the solid one and the thin one) at the current position and save the higher depth as our start depth value.</li>
<li>If our start depth is higher than the light depth no shadows will be drawn (the object is in front of the light).</li>
<li>We then assemble two vec3s one is the spatial start position <code>(start_pos.xy, start_depth)</code>, and one is the spatial light position <code>(light_pos.xy, light_depth)</code>.</li>
<li>We then step from the spacial start position to the spacial light position in increments of a constant step size (This step size determines how well we catch every shadow caster. A step size of half a pixel has worked well for me).</li>
<li>At every interpolated position we first sample the solid depth map and check if our current interpolated depth is less than the sampled depth. If it is smaller, then that means there is a solid object casting a shadow on us, and we can break out of the loop.</li>
<li>After not finding a solid object casting a shadow on us, we sample the thin depth map. If our current interpolated depth is within a small error margin of our sampled depth, then that means there is a thin object casting a shadow on us, and we can also break out of the loop.</li>
<li>If we don't find either a solid or a thin object casting a shadow on us, we continue stepping towards the light.</li>
<li>If we reach the light without finding any shadow casters, then that means that we are in view of the light and we are fully lit.</li>
<li>Finally, we multiply the current Light color based on if we found a shadow or not. Multiplying it with <code>0.0</code> would mean that things in shade are fully unlit. I've also found that interpolating the factor based on how far away the shadow caster is gives a nice decaying shadow effect.</li>
</ol>

<p>That&#39;s basically it. As you can imagine tracing a ray for every fragment can get quite expensive and only works since my
games resolution is so small (<code>320x180</code>). I&#39;ve also included an option to disable ray traced shadows in case weaker
machines struggle doing all of those calculations.</p>
<details>
    <summary>Technical Note</summary>
    <div>
        <p>
        I added a custom function to the base canvas shader that I can overwrite in my shaders that gets called for every light. It is similar to the light function but does not overwrite any default light behaviour, so a similar implementation could definitely be implemented using the default light function.
        </p>
    </div>
</details>]]></content>
        <author>
            <name>soraslove</name>
            <email>contact@soras.love</email>
            <uri>https://soras.love/</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Dev-Log: Screen Transition Improvements]]></title>
        <id>https://moldling.com/blog/2026-03-26-screen-transition-improvements</id>
        <link href="https://moldling.com/blog/2026-03-26-screen-transition-improvements"/>
        <link rel="enclosure" href="https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.png" type="image/png"/>
        <updated>2026-03-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reduction of lag caused by screen transitions.]]></summary>
        <content type="html"><![CDATA[<p>I&#39;ve been able to improve screen transition performance drastically. Moving into a big screen used to have stutters of
up to 50ms, meaning that the frame that you go into a screen would take 50ms. This is much longer than a frame should
take. Now there is no additional frame delay when going into screens of any size, meaning that the frame rate stays a
constant smooth rate.</p>
<p><strong>First:</strong> Results!</p>
<p>This is before. First is the screen transition frame itself. In the top graph you can see the red bar being the frame,
and you can see that the frame takes 54ms. Below you can see the game in action and the stutter when moving between the
large screen.</p>
<img src="https://moldling.com/blog/2026-03-26-screen-transition-improvements/before.png">
<video src="https://moldling.com/blog/2026-03-26-screen-transition-improvements/before.mp4" controls></video>

<p>Now after my changes! As you can see the frame now takes as much time as any other frame (around 15ms in this case) and
the stutter in the game footage is gone!</p>
<img src="https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.png">
<video src="https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.mp4" controls></video>

<p>Now onto how I achieved this.</p>
<p>First of all, some necessary details on how my game works. My game is made in Godot so the implementation details will
be specific to that. My game loads neighboring screens in a separate thread whenever you enter a new screen. The loaded
screens get stored for later use.</p>
<p>My previous setup was that I have a SubViewport that renders my game and a list of inactive nodes that store the
neighboring screens. Whenever the player moved into a new screen the previous screen would be removed from the
SubViewport and the new screen would be moved into the SV. Moving these large screens around was what caused the
hiccups.</p>
<p>My new solution inverts this approach. I have a list SubViewports. The active screen is in one of them and the
neighboring screens are in the other ones. Only the one SV with the active screen renders anything the other ones are
disabled (meaning they have their Update Mode set to &#39;Disabled&#39;). Whenever the player moves into a neighboring, screen
instead of the screen being moved, I now only move the player. The player gets put into the SV of the screen and the SV
gets set as the active one. Thats all that needs to happen now. This is much more performant since the player is a lot
less complex than the screens, so moving it around in the scene tree is much simpler.</p>
<p>That&#39;s it, thanks for reading. I&#39;m happy with how smooth my game runs now :)</p>
]]></content>
        <author>
            <name>soraslove</name>
            <email>contact@soras.love</email>
            <uri>https://soras.love/</uri>
        </author>
    </entry>
</feed>