<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>INCD021</title>
	<atom:link href="https://incd021.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://incd021.com</link>
	<description>Programming, thoughts, life  and art.</description>
	<lastBuildDate>Tue, 07 Apr 2026 08:08:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Simulator-driven Emergence</title>
		<link>https://incd021.com/2025/11/19/simulator-driven-emergence/</link>
					<comments>https://incd021.com/2025/11/19/simulator-driven-emergence/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 16:52:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[GeneratedArt]]></category>
		<category><![CDATA[JustForFun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[POC]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=878</guid>

					<description><![CDATA[Simulator.cs doesn’t drive the scene with hand-authored animation or fancy shaders. It spawns four families of particles, A, B, C, and D, and lets the math of their pairwise attraction/repulsion....]]></description>
										<content:encoded><![CDATA[
<p>Simulator.cs doesn’t drive the scene with hand-authored animation or fancy shaders. It spawns four families of particles, A, B, C, and D, and lets the math of their pairwise attraction/repulsion rules decide what the frame looks like. Every frame recomputes those forces, so the visible motion is the sum of tiny decisions instead of a scripted path.</p>



<h2 class="wp-block-heading">Particle families and setup</h2>



<p>Each family owns numberOfParticles lightweight Particle instances with positions, velocities, and a max speed limit. They spawn inside a circle and receive randomized velocities before Unity instantiates a prefab for each one. The simulator also generates a unique AnimationCurve plus [minDist, maxDist] for every ordered pair (A->B, B->C, etc.), so every run uses a fresh rule set.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C#</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void Start()
{
  // allocate particles/transforms per family
  ParticlesA = new Particle&#91;numberOfParticles&#93;;
  ParticlesB = new Particle&#91;numberOfParticles&#93;;
  ParticlesC = new Particle&#91;numberOfParticles&#93;;
  ParticlesD = new Particle&#91;numberOfParticles&#93;;
   TransformsA = new Transform&#91;numberOfParticles&#93;;
  TransformsB = new Transform&#91;numberOfParticles&#93;;
  TransformsC = new Transform&#91;numberOfParticles&#93;;
  TransformsD = new Transform&#91;numberOfParticles&#93;;
    // spawn each family with random position/velocity, then instantiate
  for (int j = 0; j &lt; numberOfParticles; j++)
  {
    ParticlesA&#91;j&#93; = new Particle(RandomPosition(), RandomVelosity(), VelosityMax);
    ParticlesB&#91;j&#93; = new Particle(RandomPosition(), RandomVelosity(), VelosityMax);
    ParticlesC&#91;j&#93; = new Particle(RandomPosition(), RandomVelosity(), VelosityMax);
    ParticlesD&#91;j&#93; = new Particle(RandomPosition(), RandomVelosity(), VelosityMax);
      TransformsA&#91;j&#93; = Instantiate(particlePrefabA, ParticlesA&#91;j&#93;.position, Quaternion.identity, null).transform;
    TransformsB&#91;j&#93; = Instantiate(particlePrefabB, ParticlesB&#91;j&#93;.position, Quaternion.identity, null).transform;
    TransformsC&#91;j&#93; = Instantiate(particlePrefabC, ParticlesC&#91;j&#93;.position, Quaternion.identity, null).transform;
    TransformsD&#91;j&#93; = Instantiate(particlePrefabD, ParticlesD&#91;j&#93;.position, Quaternion.identity, null).transform;
  }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Start</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// allocate particles/transforms per family</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ParticlesA</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ParticlesB</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ParticlesC</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ParticlesD</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">TransformsA</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Transform</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">TransformsB</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Transform</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">TransformsC</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Transform</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">TransformsD</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Transform</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #ECEFF4">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// spawn each family with random position/velocity, then instantiate</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> j </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">numberOfParticles</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #81A1C1">++</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ParticlesA</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">RandomPosition</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">RandomVelosity</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">VelosityMax</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ParticlesB</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">RandomPosition</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">RandomVelosity</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">VelosityMax</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ParticlesC</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">RandomPosition</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">RandomVelosity</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">VelosityMax</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ParticlesD</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">RandomPosition</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">RandomVelosity</span><span style="color: #ECEFF4">(),</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">VelosityMax</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #D8DEE9">TransformsA</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Instantiate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">particlePrefabA</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ParticlesA</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;.</span><span style="color: #D8DEE9">position</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quaternion</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">identity</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null</span><span style="color: #ECEFF4">).</span><span style="color: #D8DEE9">transform</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">TransformsB</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Instantiate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">particlePrefabB</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ParticlesB</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;.</span><span style="color: #D8DEE9">position</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quaternion</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">identity</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null</span><span style="color: #ECEFF4">).</span><span style="color: #D8DEE9">transform</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">TransformsC</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Instantiate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">particlePrefabC</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ParticlesC</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;.</span><span style="color: #D8DEE9">position</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quaternion</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">identity</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null</span><span style="color: #ECEFF4">).</span><span style="color: #D8DEE9">transform</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">TransformsD</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Instantiate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">particlePrefabD</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ParticlesD</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #ECEFF4">&#93;.</span><span style="color: #D8DEE9">position</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quaternion</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">identity</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null</span><span style="color: #ECEFF4">).</span><span style="color: #D8DEE9">transform</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<h2 class="wp-block-heading"> How it works</h2>



<ul class="wp-block-list">
<li>Each frame recomputes the force on every particle by summing contributions from the other three families. GetForceA/GetForceB/… just call the shared CalculateForce helper with the corresponding SpatialGrid, Particle[], and InteractionConfig.</li>



<li>CalculateForce only visits nearby particles by hashing them into a grid whose cell size matches the longest interaction radius. It loops over neighboring cells up to cellRadius, so it never misses an influencer without scanning the whole population.</li>



<li>Only distances within [minDist², maxDist²] participate. The code normalizes the true distance to [0, 1] via (distance &#8211; minDist) / (maxDist &#8211; minDist) and samples the cached AnimationCurve, multiplying the scalar by forceScaler and the normalized displacement direction.</li>



<li>Every computed force is scaled by Time.deltaTime, passed to Particle.ApplyForce, and then the particle’s position is updated and bounded (the current Wrap is a no-op, so the bounds are more aspirational for now).</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C#</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Private Vector2 CalculateForce(Particle source, SpatialGrid grid, Particle[] targets, InteractionConfig config)
  if (source == null || grid == null || targets == null || config.maxDist &lt;= config.minDist)
    return Vector2.zero;
  
  grid.GetCell(source.position, out int x, out int y);
  Vector2 force = Vector2.zero;
  for (int offsetX = -config.cellRadius; offsetX &lt;= config.cellRadius; offsetX++)
  {
    for (int offsetY = -config.cellRadius; offsetY &lt;= config.cellRadius; offsetY++)
    {
      if (!grid.TryGetCell(x + offsetX, y + offsetY, out var cell))
      continue;
      foreach (int targetIndex in cell)
      {
        Vector2 displacement = source.position - targets&#91;targetIndex&#93;.position;
        float distanceSquared = displacement.sqrMagnitude;
        if (distanceSquared &lt; config.minDistSq || distanceSquared > config.maxDistSq)
          continue;
         float distance = Mathf.Sqrt(distanceSquared);
      if (distance &lt; 0.0001f)
        continue;
      float normalized = config.inverseRange > 0f ? (distance - config.minDist) * config.inverseRange : 0f;
      float curveValue = config.sampler.Evaluate(normalized);
      force += (displacement / distance) * (curveValue * forceScaler);
      }
    }
  }
    return force;
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">Private</span><span style="color: #D8DEE9FF"> Vector2 </span><span style="color: #88C0D0">CalculateForce</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">Particle source</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> SpatialGrid grid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> Particle</span><span style="color: #ECEFF4">[]</span><span style="color: #D8DEE9FF"> targets</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> InteractionConfig config</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  if </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">source == null || grid == null || targets == null || config.maxDist &lt;</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">minDist</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    return Vector2.zero</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">grid</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">GetCell</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">source</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">position</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">out</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> x</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">out</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> y</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  Vector2 force </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Vector2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">zero</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> offsetX </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cellRadius</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetX</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cellRadius</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetX</span><span style="color: #81A1C1">++</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> offsetY </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cellRadius</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetY</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cellRadius</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetY</span><span style="color: #81A1C1">++</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">!</span><span style="color: #D8DEE9">grid</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">TryGetCell</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetX</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">offsetY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">out</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF"> cell</span><span style="color: #ECEFF4">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">continue;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">foreach</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> targetIndex </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cell</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        Vector2 displacement </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">source</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">position</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">targets</span><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9">targetIndex</span><span style="color: #ECEFF4">&#93;.</span><span style="color: #D8DEE9">position</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">float</span><span style="color: #D8DEE9FF"> distanceSquared </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displacement</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">sqrMagnitude</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">distanceSquared</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">minDistSq</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">||</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">distanceSquared</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">maxDistSq</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">continue;</span></span>
<span class="line"><span style="color: #D8DEE9FF">         </span><span style="color: #81A1C1">float</span><span style="color: #D8DEE9FF"> distance </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Mathf</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">Sqrt</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">distanceSquared</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">distance</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0001f</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">continue;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">float</span><span style="color: #D8DEE9FF"> normalized </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">inverseRange</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">distance</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">minDist</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">inverseRange</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">float</span><span style="color: #D8DEE9FF"> curveValue </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">sampler</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">Evaluate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">normalized</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #D8DEE9">force</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">displacement</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">distance</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">curveValue</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">forceScaler</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">force</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span></code></pre></div>



<h2 class="wp-block-heading"> Why you see those patterns</h2>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="735" height="557" src="https://incd021.com/wp-content/uploads/2025/11/Artificial-Life-Screenshot-From-2025-11-18-21-12-32.png" alt="" class="wp-image-879" srcset="https://incd021.com/wp-content/uploads/2025/11/Artificial-Life-Screenshot-From-2025-11-18-21-12-32.png 735w, https://incd021.com/wp-content/uploads/2025/11/Artificial-Life-Screenshot-From-2025-11-18-21-12-32-300x227.png 300w" sizes="(max-width: 735px) 100vw, 735px" /></figure>



<p> Why you see those patterns<br>Every ordered pair (A->B, B->A, etc.) contributes a term to a coupled-looking differential system:<br>F₁ = Σ ((source − target).normalized × curve((|d| − min)/range) × forceScaler)<br> The direction comes from the normalized displacement, while the magnitude comes from whatever curve you provided, positive values attract, negative repel. Smooth curves produce soft clustering; sharp peaks trigger energetic oscillations and shells. Opposing curves create orbiting equilibria around their zero crossings. Because all curves and ranges are randomized on startup, the system behaves like a live experiment in emergent particle art every time.</p>



<h2 class="wp-block-heading">What to expect</h2>



<p>Visual output varies run-to-run, but common motifs are:</p>



<ul class="wp-block-list">
<li>Swirling filaments where one family chases another.</li>



<li>Drifting, layered shells where attraction balances repulsion.</li>



<li>Momentary clumps that form, burst, and reform as the curves fluctuate.</li>
</ul>



<p>The damping parameter keeps the kinetic energy in check, and the spatial grid keeps the update loop fast even with thousands of particles.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/11/19/simulator-driven-emergence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Unity Async Scene Loading with Progress Bar</title>
		<link>https://incd021.com/2025/11/16/unity-async-scene-loading-with-progress-bar/</link>
					<comments>https://incd021.com/2025/11/16/unity-async-scene-loading-with-progress-bar/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 13:08:37 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[script]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=869</guid>

					<description><![CDATA[In Unity, loading large scenes synchronously can freeze the game. To fix this, you can load scenes asynchronously and show a loading progress bar. Here&#8217;s a simple script that demonstrates....]]></description>
										<content:encoded><![CDATA[
<p>In Unity, loading large scenes synchronously can freeze the game. To fix this, you can load scenes asynchronously and show a loading progress bar. Here&#8217;s a simple script that demonstrates the concept:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C#</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;

public class AsyncLoadScene : MonoBehaviour
{
    public Image bar;
    private AsyncOperation asyncOperation = null;

    void Start()
    {
        bar.fillAmount = 0f;
        StartCoroutine(LoadScene());
    }

    IEnumerator LoadScene()
    {
        yield return asyncOperation = SceneManager.LoadSceneAsync("Main");
    }

    void Update()
    {
        if (asyncOperation != null)
            bar.fillAmount = asyncOperation.progress;
    }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">using</span><span style="color: #D8DEE9FF"> UnityEngine</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">using</span><span style="color: #D8DEE9FF"> UnityEngine</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">UI</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">using</span><span style="color: #D8DEE9FF"> System</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">Collections</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">using</span><span style="color: #D8DEE9FF"> UnityEngine</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">SceneManagement</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">AsyncLoadScene</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> MonoBehaviour</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> Image bar</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">private</span><span style="color: #D8DEE9FF"> AsyncOperation asyncOperation </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Start</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">bar</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">fillAmount</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">StartCoroutine</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">LoadScene</span><span style="color: #ECEFF4">())</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    IEnumerator </span><span style="color: #88C0D0">LoadScene</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">yield</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">asyncOperation</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SceneManager</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">LoadSceneAsync</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Main</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Update</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">asyncOperation</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">bar</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">fillAmount</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">asyncOperation</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">progress</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">How it works:</h2>



<ul class="wp-block-list">
<li>It uses <code>SceneManager.LoadSceneAsync</code> to load a scene called &#8220;Main&#8221; without freezing the game.</li>



<li>A <code>UI.Image</code> (used as a fillable bar) visually displays the progress via <code>asyncOperation.progress</code>.</li>
</ul>



<h2 class="wp-block-heading">Note:</h2>



<p>This is just a test/demo to show how asynchronous scene loading works in Unity. In a production setup, you would never hardcode the name of the scene. Instead, you&#8217;d pass it dynamically, via a variable, a game manager, or a menu system.</p>



<h2 class="wp-block-heading">To test:</h2>



<p>Just assign the <code>bar</code> in the inspector, and this script handles the rest.</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-incd-021 wp-block-embed-incd-021"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="ailhmfE6CH"><a href="https://incd021.com/disclaimer/">Disclaimer!</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Disclaimer!&#8221; &#8212; INCD021" src="https://incd021.com/disclaimer/embed/#?secret=3WFfQca3mQ#?secret=ailhmfE6CH" data-secret="ailhmfE6CH" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/11/16/unity-async-scene-loading-with-progress-bar/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>First new project in 2 years!</title>
		<link>https://incd021.com/2025/10/12/first-new-project-in-2-years/</link>
					<comments>https://incd021.com/2025/10/12/first-new-project-in-2-years/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 12 Oct 2025 12:00:22 +0000</pubDate>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Game development]]></category>
		<category><![CDATA[Ludum Dare]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Indie Game]]></category>
		<category><![CDATA[Unity3D]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=864</guid>

					<description><![CDATA[After Ludum Dare 58 I hit a wall.I had poured energy into that jam game and ended up feeling drained and oddly disconnected from it afterward. There were so many....]]></description>
										<content:encoded><![CDATA[
<p>After Ludum Dare 58 I hit a wall.<br>I had poured energy into that jam game and ended up feeling drained and oddly disconnected from it afterward. There were so many ideas I wanted to include, but with limited time I had to cut features that actually made the game fun. It is always a strange balance in game jams, deciding between finishing something and making something you actually enjoy. This time, finishing won.</p>



<p>Once I stepped back, I realized I had actually enjoyed the process more than I thought. I remembered how much I love building systems, experimenting with mechanics, and watching things come to life on the screen. That feeling reminded me why I started making games in the first place.</p>



<p>I have had this idea floating around for a clicker or idle game, something simple but satisfying. After not doing any real game development for about two years, I finally feel like I have a concept worth pursuing. Right now I am building a small proof of concept to test the core loop, to see if it is as fun as it seems in my head or if it falls flat.</p>



<p>This will not be a short project. My time for game development is limited, and I am not expecting to finish in a few months. But hopefully it will not take years either. If the prototype feels right, I might actually plan things out properly this time and aim for a Steam release. That would be a first for me.</p>



<p>I am a programmer at heart, not an artist or composer, so I will probably look for help when it comes to visuals, sound effects, and music. I can make placeholder art, but it is not something anyone would want to look at for long.</p>



<p>So, long story short, I have a new project for the first time in two years, and it feels good. I do not know where it will go yet, but for the first time in a long while, I am genuinely excited to find out.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/10/12/first-new-project-in-2-years/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C++ const keyword.</title>
		<link>https://incd021.com/2025/08/11/c-const-keyword/</link>
					<comments>https://incd021.com/2025/08/11/c-const-keyword/#comments</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Mon, 11 Aug 2025 19:40:13 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[const]]></category>
		<category><![CDATA[Learning]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=852</guid>

					<description><![CDATA[TL;DR const in C++ is a promise. Use it on parameters or functions to say, “I’m not changing this.” It makes your intent clear, prevents accidental changes, and improves code....]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading"><strong>TL;DR</strong></h4>



<p>const in C++ is a promise. Use it on parameters or functions to say, “I’m not changing this.” It makes your intent clear, prevents accidental changes, and improves code readability.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>There are two main ways you can use const:</p>



<ol class="wp-block-list">
<li><strong>const Parameters</strong></li>
</ol>



<p>If you have a parameter that you don’t intend to modify, mark it as <strong>const</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C++</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void process(const std::string&amp; text);</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">process</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> std</span><span style="color: #ECEFF4">::</span><span style="color: #D8DEE9FF">string</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">text</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p>Here, text is read-only. If you try to modify it, the compiler will stop you. This is especially useful for references and pointers, where you could otherwise accidentally change the original object.</p>



<ol start="2" class="wp-block-list">
<li><strong>const Member Functions</strong></li>
</ol>



<p>When you add <strong>const</strong> to the end of a member function, you’re telling the compiler that this function won’t change the object’s state.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C++</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class Example {
public:
int getValue() const; // Won’t modify member variables
};</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Example</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #81A1C1">public</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">getValue</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const;</span><span style="color: #616E88"> // Won’t modify member variables</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p>Inside such a function, this becomes a pointer to a <strong>const</strong> object, so you can only call other <strong>const</strong> member functions (unless a member is marked mutable).</p>



<ol start="3" class="wp-block-list">
<li><strong>Combine multiple uses of const</strong></li>
</ol>



<p>You can make both the parameter and the function itself <strong>const</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">C++</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>int compare(const Example&amp; other) const;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">compare</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> Example</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">other</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const;</span></span></code></pre></div>



<p>Now neither this nor other can be modified in the function.</p>



<h4 class="wp-block-heading">Why bother?</h4>



<ul class="wp-block-list">
<li>Makes your intent explicit.</li>



<li>Helps the compiler catch mistakes.</li>



<li>Makes your API easier to understand.</li>
</ul>



<p>So this is something I&#8217;ll have to keep in mind moving forward with my C++ re-learning journey. </p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/08/11/c-const-keyword/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>CachyOS for Gaming</title>
		<link>https://incd021.com/2025/08/01/cachyos-for-gaming/</link>
					<comments>https://incd021.com/2025/08/01/cachyos-for-gaming/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Fri, 01 Aug 2025 20:58:00 +0000</pubDate>
				<category><![CDATA[AMDgpu]]></category>
		<category><![CDATA[CachyOS]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=835</guid>

					<description><![CDATA[TL;DR: Pop!_OS was outdated and couldn’t handle my new AMD GPU. I tried alternatives like SteamOS, but that failed too. Eventually found CachyOS, an Arch-based, but plug-and-play distro. Now everything....]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading"><strong>TL;DR:</strong></h4>



<p>Pop!_OS was outdated and couldn’t handle my new AMD GPU. I tried alternatives like SteamOS, but that failed too. Eventually found <a href="https://cachyos.org/" data-type="link" data-id="https://cachyos.org/">CachyOS</a>, an Arch-based, but plug-and-play distro. Now everything works perfectly. If you&#8217;re gaming on Linux, I highly recommend it.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>A few days ago, I accidentally messed up my computer so badly I couldn’t recover the OS. In my desperation to reinstall, I figured, why not fix a few other things too?</p>



<p>I’ve been gaming on Pop!_OS, but with my new AMD graphics card, it’s been a challenge to get it working. Pop is still stuck on 22.04, with an old kernel, and I had all sorts of issues getting my new AMD graphics card to work.</p>



<p>I eventually got it running by updating to <a href="https://xanmod.org/" data-type="link" data-id="https://xanmod.org/">XanMod</a> kernel, manually updating Mesa to 25+ and downloading form firmware files that should be able to better connect the two. And I got it working.. sort of. I could play <em>Dune Awakening</em>, but the game had a hole in the terrain around the player, not ideal when you&#8217;re jumping around on cliffs.</p>



<p>So I started looking elsewhere.</p>



<p>I had me eye set on Ubuntu, as I knew that the official AMD driver for my card should be able to be installed without any problems. But when I mentioned it to my CTO friend, he almost chocked on his coffee. He suggested SteamOS. So I tried. But the installer just got stuck at a black screen. Dead end.</p>



<p>Then I stumbled on another distro called <strong><strong>CachyOS</strong></strong>. Never heard of it before, but figured why not? It’s Arch-based (which I actually had tried before), and it looked to be a fast implementer of new kernels, so why not try. I just want things to work.</p>



<p>I picked the GNOME desktop as that&#8217;s what I&#8217;m used to, and got CachyOS  installed. And everything <strong>just worked</strong> out of the box. No messing with kernels. No driver downloads. So I installed Steam, launched <em>Dune Awakening</em>, hit &#8220;play&#8221;, and it ran perfectly, high framerate, and best of all no holes in the sandy floor.</p>



<p>So, if you&#8217;re on Linux and having trouble gaming, give CachyOS a try. Or if you are on Windows and had enough of forced updates, endless telemetry, or hardware demand changes.</p>



<p><strong>CachyOS</strong> just works. Massive thanks to the contributors and maintainers, you&#8217;re doing an amazing job.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/08/01/cachyos-for-gaming/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Being a Programmer</title>
		<link>https://incd021.com/2025/08/01/being-a-programmer-is-kind-of-weird/</link>
					<comments>https://incd021.com/2025/08/01/being-a-programmer-is-kind-of-weird/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Fri, 01 Aug 2025 17:32:00 +0000</pubDate>
				<category><![CDATA[Developer Thoughts]]></category>
		<category><![CDATA[Impostersyndrome]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=833</guid>

					<description><![CDATA[TL;DR: Being a programmer is weird. Sometimes you solve tough problems and feel amazing. Other times you spend 8 hours hunting a missing semicolon. You can feel exhausted, yet have....]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading"><strong>TL;DR:</strong></h4>



<p>Being a programmer is weird. Sometimes you solve tough problems and feel amazing. Other times you spend 8 hours hunting a missing semicolon. You can feel exhausted, yet have nothing concrete to show. It’s a job full of mental gymnastics, and it’s both deeply rewarding and utterly frustrating.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>I&#8217;ve multiple times been confronted by blue-collar workers who joke that we, programmers, &#8220;just sit behind a screen all day not doing nothing.&#8221; And I get it. They work hard, physically. But our jobs are hard in a different way.</p>



<p>Programming can be deeply satisfying. On good days, you solve tricky problems, feel productive, and walk away energized. Other days? You stare at the screen for eight hours and the only thing you accomplished was finding the missing semicolon.</p>



<p>It’s also mentally exhausting. Especially when you&#8217;re trying to keep good chunk of logic flow in your head, to solve something or just to understand the code, and then you are interrupted by a meeting, a college or an email notification. Then it takes forever to rebuild that mental image again. And sometimes, it’s not only interruptions, sometimes your brain just loses the thread &#8211; you’re in the zone, holding five different logical states in your head, nearly at a breakthrough&#8230; and then poof, it’s gone. That mental toll is real. I end some days completely drained.</p>



<p>Meanwhile, physical workers come home and collapse on the couch. We do the same, but not because we’ve lifted anything heavier than a coffee mug.</p>



<p>What frustrates me most about working as a software developer, is spending a full day debugging, changing maybe three lines of code, and having nothing that feels tangible to show for it. You look at your commit history:<br><strong>“fix typo, fix bug, cleanup”</strong> — and you’re like, <em>“That’s it?”</em></p>



<p>And sure, I&#8217;ve had great mentors who reminded me that it&#8217;s not about how many lines you write, it&#8217;s about writing the <em>right</em> ones. I know they&#8217;re right. But there&#8217;s a difference between <em>knowing</em>, and <em>feeling</em> it.</p>



<p>Some days, I feel like an imposter. Like if someone reviewed my output, they’d go, “Why the hell are we paying this guy?” And yet, I’ve built real things, fixed real bugs, shipped actual features.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/08/01/being-a-programmer-is-kind-of-weird/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Adding desktop icon to applications on Pop!_OS</title>
		<link>https://incd021.com/2025/04/01/adding-desktop-icon-to-applications-on-pop_os/</link>
					<comments>https://incd021.com/2025/04/01/adding-desktop-icon-to-applications-on-pop_os/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Tue, 01 Apr 2025 18:33:23 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[icon]]></category>
		<category><![CDATA[Pop!_OS]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=813</guid>

					<description><![CDATA[Something that should be quite easy — but since there are multiple ways to install applications on Linux, not all of them add an icon for you. So here is....]]></description>
										<content:encoded><![CDATA[
<p>Something that should be quite easy — but since there are multiple ways to install applications on Linux, not all of them add an icon for you. So here is the bare minimum you need to do to add an icon to an application.</p>



<p>First create a .desktop file on your desktop.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>nano ~/Desktop/Godot.desktop</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">nano</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">~/Desktop/Godot.desktop</span></span></code></pre></div>



<p>Now add the following code, and adjust the location to match your application and icon location. Here I&#8217;ve downloaded and copied Godot to Applications in my home directory.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&#91;Desktop Entry&#93;
Type=Application
Name=Godot
Exec=/home/nope/Applications/Godot_v4.4-stable_mono_linux.x86_64
Icon=/home/nope/Applications/GodotIcon.png
Terminal=false</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">Desktop Entry</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9">Type</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">Application</span></span>
<span class="line"><span style="color: #D8DEE9">Name</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">Godot</span></span>
<span class="line"><span style="color: #D8DEE9">Exec</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">/home/nope/Applications/Godot_v4.4-stable_mono_linux.x86_64</span></span>
<span class="line"><span style="color: #D8DEE9">Icon</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">/home/nope/Applications/GodotIcon.png</span></span>
<span class="line"><span style="color: #D8DEE9">Terminal</span><span style="color: #81A1C1">=</span><span style="color: #81A1C1">false</span></span></code></pre></div>



<p>After saving the file, we need to make it executable, to be able to run the application by clicking the icon.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>chmod +x ~/Desktop/Godot.desktop</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">chmod</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">~/Desktop/Godot.desktop</span></span></code></pre></div>



<p>Before you can just start the application by clicking it, you need to right-click the icon and select &#8220;Allow Launching&#8221;.</p>



<p>That&#8217;s it! You can now run the application by simply clicking the icon.</p>



<h2 class="wp-block-heading">Optional</h2>



<p>If you want to add the application to the application menu. You just have to copy the .desktop file to <strong>~/.local/share/applications/</strong> and the application will show up in the application menu.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/04/01/adding-desktop-icon-to-applications-on-pop_os/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Different git user names for different repository folders</title>
		<link>https://incd021.com/2025/03/27/different-names-for-different-repository-folders/</link>
					<comments>https://incd021.com/2025/03/27/different-names-for-different-repository-folders/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Thu, 27 Mar 2025 16:14:00 +0000</pubDate>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitconfig]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=803</guid>

					<description><![CDATA[I&#8217;m using the same computer for development on multiple projects, some private, some not, but I can&#8217;t use the same git user name for all the different repositories, so I....]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;m using the same computer for development on multiple projects, some private, some not, but I can&#8217;t use the same git user name for all the different repositories, so I found out you can have different .gitconfig files, based on which folder you repository is located in.</p>



<p>Here is how to do it;<br>First create the different config files, one for each folder.</p>



<p><strong>.gitconfig-work</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&#91;user&#93;
  email = workEmail@work.com
  name = workName
&#91;core&#93;
  autocrlf = input
&#91;credential&#93;
  helper = store</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">user</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">workEmail@work.com</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">workName</span></span>
<span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">core</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">autocrlf</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">input</span></span>
<span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">credential</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">helper</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">store</span></span></code></pre></div>



<p><strong><strong>.gitconfig-private</strong></strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&#91;user&#93;
  email = privateEmail@private.com
  name = privateName
&#91;core&#93;
  autocrlf = input
&#91;credential&#93;
  helper = store</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">user</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">privateEmail@private.com</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">privateName</span></span>
<span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">core</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">autocrlf</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">input</span></span>
<span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">credential</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">helper</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">store</span></span></code></pre></div>



<p>And now the <strong>.gitconfig</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#39404f;color:#c8d0e0">Bash</span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&#91;includeIf "gitdir:~/workFolder/"&#93;
path = ~/.gitconfig-work

&#91;includeIf "gitdir:~/privateFolder/"&#93;
path = ~/.gitconfig-private</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">includeIf </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">gitdir:~/workFolder/</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #88C0D0">path</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">~/.gitconfig-work</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">&#91;</span><span style="color: #D8DEE9FF">includeIf </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">gitdir:~/privateFolder/</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #88C0D0">path</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">~/.gitconfig-private</span></span></code></pre></div>



<p>When you now push to repositories located in <strong>privateFolder</strong> the name <strong>privateName</strong> will be used, and for the folder <strong>workFolder</strong> the name <strong>workName</strong> is used.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2025/03/27/different-names-for-different-repository-folders/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Using Git -bare to create local hosted repos</title>
		<link>https://incd021.com/2024/10/27/using-git-bare-to-create-local-hosted-repos/</link>
					<comments>https://incd021.com/2024/10/27/using-git-bare-to-create-local-hosted-repos/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 27 Oct 2024 17:58:59 +0000</pubDate>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[bare]]></category>
		<category><![CDATA[git]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=775</guid>

					<description><![CDATA[Intro Have you ever wanted to just host your repositories at home instead of handing over everything to some lesser trustworthy third-party site? Then this might be a simple solution....]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Intro</h3>



<p>Have you ever wanted to just host your repositories at home instead of handing over everything to some lesser trustworthy third-party site? Then this might be a simple solution for you.</p>



<h3 class="wp-block-heading">Setup</h3>



<p>To create the local hosted git repository.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Markdown</span><span role="button" tabindex="0" data-code="&gt;cd location_for_the_repository
&gt;git init --bare new_local_hosted_repo.git" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #E7EE98; font-style: italic">&gt;cd location_for_the_repository</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git init --bare new_local_hosted_repo.git</span></span></code></pre></div>



<p></p>



<p>This will create a folder ending in .git<br>Now to use it, navigate to where you want to checkout your working directory</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Markdown</span><span role="button" tabindex="0" data-code="&gt;cd working_directory" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #E7EE98; font-style: italic">&gt;cd working_directory</span></span></code></pre></div>



<p></p>



<p>and clone the newly created repository</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Markdown</span><span role="button" tabindex="0" data-code="&gt;git clone full_path_to_new_local_hosted_repo.git" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git clone full_path_to_new_local_hosted_repo.git</span></span></code></pre></div>



<p></p>



<p>The workspace is now ready to use, and you can do all the same things you would normally do, using GitHub, Bitbucket or any other online repository.</p>



<h3 class="wp-block-heading">A Full example:</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Markdown</span><span role="button" tabindex="0" data-code="&gt;mkdir ~/repositories
&gt;cd ~/repositories
&gt;git init --bare best_game_ever.git
&gt;mkdir ~/workDirectory
&gt;cd ~/workDirectory
&gt;git clone ~/repositories/best_game_ever.git
&gt;cd best_game_ever
&gt;touch ./note.txt
&gt;git add *
&gt;git commit -m &quot;initial commit&quot;
&gt;git push" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #E7EE98; font-style: italic">&gt;mkdir ~/repositories</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;cd ~/repositories</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git init --bare best_game_ever.git</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;mkdir ~/workDirectory</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;cd ~/workDirectory</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git clone ~/repositories/best_game_ever.git</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;cd best_game_ever</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;touch ./note.txt</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git add *</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git commit -m &quot;initial commit&quot;</span></span>
<span class="line"><span style="color: #E7EE98; font-style: italic">&gt;git push</span></span></code></pre></div>



<p></p>



<p><strong>Note</strong>: Remember to backup ~/repositories</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-incd-021 wp-block-embed-incd-021"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="ETcmfpilAs"><a href="https://incd021.com/disclaimer/">Disclaimer!</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Disclaimer!&#8221; &#8212; INCD021" src="https://incd021.com/disclaimer/embed/#?secret=nDU875fEXD#?secret=ETcmfpilAs" data-secret="ETcmfpilAs" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2024/10/27/using-git-bare-to-create-local-hosted-repos/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Implementing simple L-System in Kotlin</title>
		<link>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/</link>
					<comments>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 27 Oct 2024 17:58:44 +0000</pubDate>
				<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[L-System]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=773</guid>

					<description><![CDATA[Intro L-systems were introduced and developed by Aristid Lindenmayer back in 1968 and are often used to produce fractals or images of flowers, as the repeating nature of some flowers....]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Intro</h3>



<p>L-systems were introduced and developed by Aristid Lindenmayer back in 1968 and are often used to produce fractals or images of flowers, as the repeating nature of some flowers is very easy to reproduce using L-systems. L-systems consist of four parts: <strong>variables</strong>, <strong>constants</strong>, <strong>Axiom</strong>, and <strong>rules</strong>. The rules describe how the axiom, or start expression, evolves from iteration to iteration.</p>



<h3 class="wp-block-heading">Let’s look at a classical example:</h3>



<ul class="wp-block-list">
<li>Variables: <strong>L</strong></li>



<li>Constants: <strong>+</strong>, <strong>−</strong></li>



<li>Axiom: <strong>L</strong></li>



<li>Rules: <strong>L =&gt; L-L++L-L</strong></li>
</ul>



<p>How the different symbols are interpreted is entirely up to us, but in this example, we define:</p>



<ul class="wp-block-list">
<li><strong>L</strong> to mean &#8220;draw line forward&#8221;</li>



<li><strong>+</strong> to mean &#8220;turn left&#8221;</li>



<li><strong>−</strong> to mean &#8220;turn right&#8221;</li>
</ul>



<p>So the algorithm is a simple search and replace. We go through the axiom or start string L and replace it according to the rule, resulting in the following strings:</p>



<ul class="wp-block-list">
<li><em>Iteration 1</em>: L =&gt; <strong>L-L++L-L </strong></li>



<li><em>Iteration 2</em>: L-L++L-L =&gt; <strong>L-L++L-L-L-L++L-L++L-L++L-L-L-L++L-L </strong></li>



<li><em>Iteration 3</em>: L-L++L-L-L-L++L-L++L-L++L-L-L-L++L-L =&gt; <strong>L-L++L-L-L-L++L-L++L-L++L-L-L-L …</strong></li>
</ul>



<p>and we can keep going for as many iterations as we like, but as we can already see, the resulting string grows very raptly because of the “long” rule for <strong>L</strong>. If the rule for <strong>L</strong> was simpler, the resulting string of cause wouldn’t grow as fast.<br></p>



<p>Repeatedly applying the rules increases structure and complexity.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://incd021.com/wp-content/uploads/2024/09/L-System-Iterations-1.png" alt="L-System Iterations" class="wp-image-164"/><figcaption class="wp-element-caption">Basic L-System iterations</figcaption></figure>



<p>But enough theory; If you want more information, you can read an in-depth explanation of <a href="https://en.wikipedia.org/wiki/L-system">L-systems on Wikipedia</a>.</p>



<h2 class="wp-block-heading">Implementing the L-system.</h2>



<p>We’ll be use strings for variables, constants, and axiom, a <strong>StringBuilder</strong> for building up the result, and a simple <strong>Map&lt;string, string&gt;</strong> for the rule(s), defining the string to search for and what to replace it with.</p>



<p>First we define the <strong>RuleSet</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@Serializable
data class RuleSet(val rules: Map&lt;String, String>, val axiom: String)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #97E1F1; font-style: italic">@Serializable</span></span>
<span class="line"><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">RuleSet</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> rules: </span><span style="color: #97E1F1; font-style: italic">Map</span><span style="color: #F6F6F4">&lt;</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">&gt;, </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> axiom: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<p>As simple as can be, simple data class containing the axiom and the Map containing the rules.<br>We need the annotation @Serializable as we will be reading the rules from a JSON file.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">JSON</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>{
  "rules": {
    "L": "L-L++L-L"
  },
  "axiom": "L"
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">rules</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">L</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">L-L++L-L</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  },</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">axiom</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">L</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>This is the simple rule for creating the image displayed above.</p>



<p>The simple constructor for the <strong>LSystem</strong> class is only taking a <strong>RuleSet</strong> as parameter:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class LSystem(private val ruleSet: RuleSet)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">LSystem</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> ruleSet: </span><span style="color: #97E1F1; font-style: italic">RuleSet</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<p><br>The <strong>generate</strong> function takes in the number of iterations to run and calls the <strong>generateExpression</strong> that number of time. It also times how long each generation takes in nanoseconds.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>fun generate(iterations: Int) {
    expression.append(ruleSet.axiom)
    
    var startTime: Long
    var endTime: Long
    
    for (i in 0 until iterations) {
        startTime = System.nanoTime()
        expression = generateExpression(expression)
    
        endTime = System.nanoTime()
        println("Time to generate iteration ${i + 1}${endTime-startTime}ns - With a size of ${expression.length}")
    }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generate</span><span style="color: #F6F6F4">(iterations: </span><span style="color: #97E1F1; font-style: italic">Int</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(ruleSet.axiom)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> startTime: </span><span style="color: #97E1F1; font-style: italic">Long</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> endTime: </span><span style="color: #97E1F1; font-style: italic">Long</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (i </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span><span style="color: #F6F6F4"> until iterations) {</span></span>
<span class="line"><span style="color: #F6F6F4">        startTime </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> System.</span><span style="color: #62E884">nanoTime</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">        expression </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generateExpression</span><span style="color: #F6F6F4">(expression)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        endTime </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> System.</span><span style="color: #62E884">nanoTime</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #E7EE98">&quot;Time to generate iteration </span><span style="color: #F286C4">${</span><span style="color: #E7EE98">i </span><span style="color: #F286C4">+</span><span style="color: #E7EE98"> </span><span style="color: #BF9EEE">1</span><span style="color: #F286C4">}${</span><span style="color: #E7EE98">endTime</span><span style="color: #F286C4">-</span><span style="color: #E7EE98">startTime</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">ns - With a size of </span><span style="color: #F286C4">${</span><span style="color: #E7EE98">expression.length</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">&quot;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><br>The <strong>generateExpression</strong> function is the heart of the L-System. It goes through the current expression character by character and tries to match up the rules with the upcoming characters using the <strong>matchesPattern</strong> helper function. When a match is found, the resulting string from the rule is appended to the new expression. If no match is found, the current character is appended to the new expression. This approach avoids the need for rules that don&#8217;t replace anything, such as <strong>&#8220;-&#8221; =&gt; &#8220;-&#8220;</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>private fun generateExpression(expression: StringBuilder) : StringBuilder {
    val newExpression = StringBuilder()
    
    var position = 0
    while (position &lt; expression.length) {
        var matched = false
    
        // Check each pattern in order
        for (pattern in ruleSet.rules) {
            if (position + pattern.key.length &lt;= expression.length &amp;&amp; // check we are not matching outside the expression
                matchesPattern(this.expression, position, pattern.key)
            ) {
                matched = true
                position += pattern.key.length // Move the position forward after matching
                newExpression.append(ruleSet.rules&#91;pattern.key&#93;)
                break
            }
        }
    
        if (!matched) {
            newExpression.append(expression&#91;position&#93;)
            position++ // Move to the next position if no pattern matched
        }
    }
    
    return newExpression
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generateExpression</span><span style="color: #F6F6F4">(expression: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">) : </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> newExpression </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">StringBuilder</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> position </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">while</span><span style="color: #F6F6F4"> (position </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> expression.length) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> matched </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// Check each pattern in order</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (pattern </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> ruleSet.rules) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (position </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> pattern.key.length </span><span style="color: #F286C4">&lt;=</span><span style="color: #F6F6F4"> expression.length </span><span style="color: #F286C4">&amp;&amp;</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// check we are not matching outside the expression</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #62E884">matchesPattern</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.expression, position, pattern.key)</span></span>
<span class="line"><span style="color: #F6F6F4">            ) {</span></span>
<span class="line"><span style="color: #F6F6F4">                matched </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span></span>
<span class="line"><span style="color: #F6F6F4">                position </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> pattern.key.length </span><span style="color: #7B7F8B">// Move the position forward after matching</span></span>
<span class="line"><span style="color: #F6F6F4">                newExpression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(ruleSet.rules&#91;pattern.key&#93;)</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">break</span></span>
<span class="line"><span style="color: #F6F6F4">            }</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">!</span><span style="color: #F6F6F4">matched) {</span></span>
<span class="line"><span style="color: #F6F6F4">            newExpression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(expression&#91;position&#93;)</span></span>
<span class="line"><span style="color: #F6F6F4">            position</span><span style="color: #F286C4">++</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Move to the next position if no pattern matched</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> newExpression</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><br>The helper function <strong>matchesPattern</strong> goes through the characters in the pattern and tries to match them with the next characters in the input <strong>StringBuilder</strong>. This is a greedy approach, so the order of the rules matters. For instance, if we have the two rules <strong>&#8220;-&#8221; =&gt; &#8220;L&#8221;</strong> and <strong>&#8220;&#8211;&#8221; =&gt; &#8220;L&#8221;</strong> in that order, the second rule will never be applied because the first rule always matches first. Therefore, place the longer rules first.</p>



<p>We could pre-sort the rules, but for this introduction, we just have to keep the order in mind.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>  private fun matchesPattern(input: StringBuilder, position: Int, pattern: String): Boolean {
    for (index in pattern.indices) {
        if (input&#91;position + index&#93; != pattern&#91;index&#93;) {
            return false // Return false if any character doesn't match
        }
    }
    
    return true // Return true if all characters match
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">matchesPattern</span><span style="color: #F6F6F4">(input: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">, position: </span><span style="color: #97E1F1; font-style: italic">Int</span><span style="color: #F6F6F4">, pattern: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">): </span><span style="color: #97E1F1; font-style: italic">Boolean</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (index </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> pattern.indices) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (input&#91;position </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> index&#93; </span><span style="color: #F286C4">!=</span><span style="color: #F6F6F4"> pattern&#91;index&#93;) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Return false if any character doesn&#39;t match</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Return true if all characters match</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<h2 class="wp-block-heading"><br>Implementing the Visualizer</h2>



<p>So now we have a long string of characters, but we need to interpret in some way. This is where the visualizer comes in. <br>We started by defining the variables and constants <strong>&#8211;</strong>, <strong>+</strong>, and <strong>L</strong>, so now we just have to draw from the expression.</p>



<p> The <strong>Visualizer</strong> constructor takes a few parameters:</p>



<ul class="wp-block-list">
<li><strong>expression</strong>, the expression to be interpreted</li>



<li><strong>imageSize</strong>, the size for the output image</li>



<li><strong>padding</strong>, the padding around the figure to the edge of the image, in pixels</li>



<li><strong>filename</strong>, the filename for the output file.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class Visualizer(
    private val expression: StringBuilder,
    private val imageSize: Vector2,
    private var padding: Float,
    private var filename: String
) </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Visualizer</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> expression: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> imageSize: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> padding: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> filename: </span><span style="color: #97E1F1; font-style: italic">String</span></span>
<span class="line"><span style="color: #F6F6F4">) </span></span></code></pre></div>



<p>Let&#8217;s start with the rules and the drawing function <strong>doTurtleAction</strong>. But for that to make sense, we&#8217;ll also have to look at the <strong>SystemState</strong> data class.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>data class SystemState(
    var position: Vector2,
    var angle: Float,
    var length: Float,
)

fun doTurtleAction(c: Char, state: SystemState, canvas: Canvas? = null, draw : Boolean = true) {
    when (c) {
        'L' -> drawLine(state, canvas, aPen, draw)
        '+' -> state.angle += 45
        '-' -> state.angle -= 45
    }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> position: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> angle: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> length: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c: </span><span style="color: #97E1F1; font-style: italic">Char</span><span style="color: #F6F6F4">, state: </span><span style="color: #97E1F1; font-style: italic">SystemState</span><span style="color: #F6F6F4">, canvas: </span><span style="color: #97E1F1; font-style: italic">Canvas</span><span style="color: #F6F6F4">? </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">, draw : </span><span style="color: #97E1F1; font-style: italic">Boolean</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">when</span><span style="color: #F6F6F4"> (c) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;L&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">drawLine</span><span style="color: #F6F6F4">(state, canvas, aPen, draw)</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;+&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> state.angle </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">45</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;-&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> state.angle </span><span style="color: #F286C4">-=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">45</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>The <strong>SystemState</strong> class keeps track of the current position of the pen drawing the figure, the current angle in degrees, and the length. This can be extended to keep a stack of positions that can be pushed and popped so that when drawing, it can store a position, draw something, and return to that position. However, this isn&#8217;t implemented in this simple version.</p>



<p>In <strong>doTurtleAction</strong>, using Kotlin&#8217;s <em>when</em> function makes interpreting the character very straightforward. Here, we define what we want the different variables and constants to do. We use 45 degrees for <strong>+</strong> and <strong>&#8211;</strong> because this will create a nice Koch fractal, but you can set it to whatever you like. <strong>L</strong> draws a line based on the length and angle in <strong>state</strong>.</p>



<p>I added some extra steps in the <strong>Visualizer</strong> to help always output a nice image of the whole figure. That is, I go through the entire algorithm without drawing anything; I only log the minimum and maximum positions. This allows me to scale the lines to draw and set the starting position so the figure is centered and fills the given image size, excluding the padding.</p>



<p>Calculating the area of the figure with the line at size 1 is done using the <strong>calcArea</strong> function.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>private fun calcArea(): Rectangle {
    val state = SystemState(
        angle = 0f,
        length = 1f,
        position = Vector2(0f, 0f)
    ) hosted 
    
    expression.toString().forEach { c ->
        doTurtleAction(c, state, null,false)
        updateAreaData(state)
    }
    
    val x = floor(minXPosition)
    val y = floor(minYPosition)
    val w = ceil(maxXPosition) - x
    val h = ceil(maxYPosition) - y
    return Rectangle(x.toInt(), y.toInt(), w.toInt(), h.toInt())
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">calcArea</span><span style="color: #F6F6F4">(): </span><span style="color: #97E1F1; font-style: italic">Rectangle</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> state </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">        angle </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        length </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        position </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Vector2</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    ) hosted </span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">toString</span><span style="color: #F6F6F4">().</span><span style="color: #62E884">forEach</span><span style="color: #F6F6F4"> { c </span><span style="color: #F286C4">-&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c, state, </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">updateAreaData</span><span style="color: #F6F6F4">(state)</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> x </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">floor</span><span style="color: #F6F6F4">(minXPosition)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> y </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">floor</span><span style="color: #F6F6F4">(minYPosition)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> w </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ceil</span><span style="color: #F6F6F4">(maxXPosition) </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> x</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> h </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ceil</span><span style="color: #F6F6F4">(maxYPosition) </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> y</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Rectangle</span><span style="color: #F6F6F4">(x.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), y.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), w.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), h.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">())</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>When outputting the image, we start by getting the area and performing some calculations to get the scale and the starting point to use.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>private fun outputAsImage(maxImageSize: Vector2, filename: String) {
    val area = calcArea()
     
    val xScale = (maxImageSize.x - padding) / area.width
    val yScale = (maxImageSize.y - padding) / area.height
    val scale = if (xScale &lt; yScale) xScale else yScale
    
    val state = SystemState(
        angle = 0f,
        length = scale,
        posi hosted tion = Vector2(minXPosition * (-scale) + (padding / 2), minYPosition * (-scale) + (padding / 2))
    )
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">outputAsImage</span><span style="color: #F6F6F4">(maxImageSize: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">, filename: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> area </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">calcArea</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">     </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> xScale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (maxImageSize.x </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> padding) </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> area.width</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> yScale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (maxImageSize.y </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> padding) </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> area.height</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> scale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (xScale </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> yScale) xScale </span><span style="color: #F286C4">else</span><span style="color: #F6F6F4"> yScale</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> state </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">        angle </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        length </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> scale,</span></span>
<span class="line"><span style="color: #F6F6F4">        posi hosted tion </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Vector2</span><span style="color: #F6F6F4">(minXPosition </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">scale) </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> (padding </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">), minYPosition </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">scale) </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> (padding </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">))</span></span>
<span class="line"><span style="color: #F6F6F4">    )</span></span>
<span class="line"></span></code></pre></div>



<p>Now we setup the canvas to draw on. Here we use the Kotlin wrapper for the <a href="https://skia.org/">Skia</a> 2d graphics library called <a href="https://github.com/JetBrains/skiko">skiko</a>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>    val surface = Surface.makeRaster(ImageInfo.makeN32(maxImageSize.x.toInt(), maxImageSize.y.toInt(), ColorAlphaType.OPAQUE))
    
    // Get the canvas from the surface
    val canvas = surface.canvas
    // Clear the canvas with a white background
    canvas.clear(Color.TRANSPARENT)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> surface </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> Surface.</span><span style="color: #62E884">makeRaster</span><span style="color: #F6F6F4">(ImageInfo.</span><span style="color: #62E884">makeN32</span><span style="color: #F6F6F4">(maxImageSize.x.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), maxImageSize.y.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), ColorAlphaType.OPAQUE))</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Get the canvas from the surface</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> canvas </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> surface.canvas</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Clear the canvas with a white background</span></span>
<span class="line"><span style="color: #F6F6F4">    canvas.</span><span style="color: #62E884">clear</span><span style="color: #F6F6F4">(Color.TRANSPARENT)</span></span></code></pre></div>



<p><em>Note</em>: The Kotlin wrapper for Skia doesn&#8217;t use the same naming for classes and functions, which makes it challenging to use the documentation for Skia. After a lot of searching, I got it working, but without a deeper understanding of why, so I&#8217;m not sure if it&#8217;s the right way of using it. But it works.</p>



<p>Now we draw the figure and output the image to a file.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>    expression.toString().forEach { c -> doTurtleAction(c, state, canvas) }
    
    // Get the snapshot of the surface
    val image = surface.makeImageSnapshot()
    
    // Encode the image as a PNG
    val data = image.encodeToData(EncodedImageFormat.PNG, 100)
    
    // Save the PNG to a file
    File("$filename.png").writeBytes(data!!.bytes)
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">toString</span><span style="color: #F6F6F4">().</span><span style="color: #62E884">forEach</span><span style="color: #F6F6F4"> { c </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c, state, canvas) }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Get the snapshot of the surface</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> image </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> surface.</span><span style="color: #62E884">makeImageSnapshot</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Encode the image as a PNG</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> image.</span><span style="color: #62E884">encodeToData</span><span style="color: #F6F6F4">(EncodedImageFormat.PNG, </span><span style="color: #BF9EEE">100</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Save the PNG to a file</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">File</span><span style="color: #F6F6F4">(</span><span style="color: #E7EE98">&quot;</span><span style="color: #F6F6F4">$filename</span><span style="color: #E7EE98">.png&quot;</span><span style="color: #F6F6F4">).</span><span style="color: #62E884">writeBytes</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">data!!</span><span style="color: #F6F6F4">.bytes)</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><strong>That&#8217;s it!</strong><br>I&#8217;ve added the full project code here, for <a href="https://incd021.com/wp-content/uploads/2024/09/L-System-Kotlin.zip">free download</a>.</p>



<h3 class="wp-block-heading">Thoughts:</h3>



<p>However, nothing says we must use repetitive rules; we can do whatever we want. We could alternate between differenthosted rules, shift rules when a specific pattern is seen, reverse parts based on other triggers, or use any approach that could yield an interesting result. I like to add randomness to the constants, so instead of turning exactly 90 degrees, we turn 90 degrees plus or minus some small random value to introduce variation. Create different weighted rules, allowing multiple rules for the same pattern with different probabilities! &#8220;Barney Codes&#8221; has already implemented this, as seen in <a href="https://www.youtube.com/watch?v=TOPxa1xIG5Q">YouTube video</a>.</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-incd-021 wp-block-embed-incd-021"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="8b6QHh5SIB"><a href="https://incd021.com/disclaimer/">Disclaimer!</a></blockquote><iframe loading="lazy" class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Disclaimer!&#8221; &#8212; INCD021" src="https://incd021.com/disclaimer/embed/#?secret=WLzI3GCQ2J#?secret=8b6QHh5SIB" data-secret="8b6QHh5SIB" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Page Caching using Disk: Enhanced 

Served from: incd021.com @ 2026-04-10 08:06:25 by W3 Total Cache
-->