<?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>INC $D021 &#8211; INCD021</title>
	<atom:link href="https://incd021.com/author/incd021/feed/" rel="self" type="application/rss+xml" />
	<link>https://incd021.com</link>
	<description>Programming, thoughts, life  and art.</description>
	<lastBuildDate>Tue, 01 Apr 2025 18:40:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>
	<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" data-code="nano ~/Desktop/Godot.desktop" style="color:#d8dee9ff;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="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" data-code="[Desktop Entry]
Type=Application
Name=Godot
Exec=/home/nope/Applications/Godot_v4.4-stable_mono_linux.x86_64
Icon=/home/nope/Applications/GodotIcon.png
Terminal=false" style="color:#d8dee9ff;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="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">[</span><span style="color: #D8DEE9FF">Desktop Entry</span><span style="color: #ECEFF4">]</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" data-code="chmod +x ~/Desktop/Godot.desktop" style="color:#d8dee9ff;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="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" data-code="[user]
  email = workEmail@work.com
  name = workName
[core]
  autocrlf = input
[credential]
  helper = store" style="color:#d8dee9ff;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="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">[</span><span style="color: #D8DEE9FF">user</span><span style="color: #ECEFF4">]</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">[</span><span style="color: #D8DEE9FF">core</span><span style="color: #ECEFF4">]</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">[</span><span style="color: #D8DEE9FF">credential</span><span style="color: #ECEFF4">]</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" data-code="[user]
  email = privateEmail@private.com
  name = privateName
[core]
  autocrlf = input
[credential]
  helper = store" style="color:#d8dee9ff;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="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">[</span><span style="color: #D8DEE9FF">user</span><span style="color: #ECEFF4">]</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">[</span><span style="color: #D8DEE9FF">core</span><span style="color: #ECEFF4">]</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">[</span><span style="color: #D8DEE9FF">credential</span><span style="color: #ECEFF4">]</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" data-code="[includeIf &quot;gitdir:~/workFolder/&quot;]
path = ~/.gitconfig-work

[includeIf &quot;gitdir:~/privateFolder/&quot;]
path = ~/.gitconfig-private" style="color:#d8dee9ff;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="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">[</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">]</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">[</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">]</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="2MqDv7FtSS"><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=jxDRWgSQKJ#?secret=2MqDv7FtSS" data-secret="2MqDv7FtSS" 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" data-code="@Serializable
data class RuleSet(val rules: Map&lt;String, String&gt;, val axiom: String)" 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: #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" data-code="{
  &quot;rules&quot;: {
    &quot;L&quot;: &quot;L-L++L-L&quot;
  },
  &quot;axiom&quot;: &quot;L&quot;
}" 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: #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" data-code="class LSystem(private val ruleSet: RuleSet)" 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: #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" data-code="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(&quot;Time to generate iteration ${i + 1}${endTime-startTime}ns - With a size of ${expression.length}&quot;)
    }
}" 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: #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" data-code="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[pattern.key])
                break
            }
        }
    
        if (!matched) {
            newExpression.append(expression[position])
            position++ // Move to the next position if no pattern matched
        }
    }
    
    return newExpression
}" 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: #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[pattern.key])</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[position])</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" data-code="  private fun matchesPattern(input: StringBuilder, position: Int, pattern: String): Boolean {
    for (index in pattern.indices) {
        if (input[position + index] != pattern[index]) {
            return false // Return false if any character doesn't match
        }
    }
    
    return true // Return true if all characters match
}" 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: #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[position </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> index] </span><span style="color: #F286C4">!=</span><span style="color: #F6F6F4"> pattern[index]) {</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" data-code="class Visualizer(
    private val expression: StringBuilder,
    private val imageSize: Vector2,
    private var padding: Float,
    private var filename: String
) " 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: #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" data-code="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' -&gt; drawLine(state, canvas, aPen, draw)
        '+' -&gt; state.angle += 45
        '-' -&gt; state.angle -= 45
    }
}" 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: #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" data-code="private fun calcArea(): Rectangle {
    val state = SystemState(
        angle = 0f,
        length = 1f,
        position = Vector2(0f, 0f)
    ) hosted 
    
    expression.toString().forEach { c -&gt;
        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())
}" 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: #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" data-code="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))
    )
" 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: #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" data-code="    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)" 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: #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" data-code="    expression.toString().forEach { c -&gt; 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(&quot;$filename.png&quot;).writeBytes(data!!.bytes)
}" 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: #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="http://192.168.2.128/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="KUvuAtgB9J"><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=PIIRGl3WlH#?secret=KUvuAtgB9J" data-secret="KUvuAtgB9J" 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>
		<item>
		<title>LD46 &#8211; The Unicorn and the need for coffee..!</title>
		<link>https://incd021.com/2020/04/22/ld46-the-unicorn-and-the-need-for-coffee/</link>
					<comments>https://incd021.com/2020/04/22/ld46-the-unicorn-and-the-need-for-coffee/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Wed, 22 Apr 2020 20:31:59 +0000</pubDate>
				<category><![CDATA[Game development]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=754</guid>

					<description><![CDATA[So Ludum Dare 46 happened, and this time I attended, and actually made a game. 😀I just remembered that I have this site, and haven&#8217;t posted anything here in years,....]]></description>
										<content:encoded><![CDATA[
<p>So Ludum Dare 46 happened, and this time I attended, and actually made a game. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>I just remembered that I have this site, and haven&#8217;t posted anything here in years, so I thought &#8220;I host my game here, so why not write about it here.&#8221;</p>



<p>The game is a simple <em>item fetch</em> game, with a few small jokes in there. It is heavily inspired by the amazing over polisher of all, the one, the only <a href="https://twitter.com/PixelProphecy">Pixel Prophecy</a>! Also know as Phil Strahl. <br>He really likes his coffee, so the game needed coffee, and then he has a thing with unicorns, so again the game had to have at least one unicorn.<br>The gameplay is simple; the unicorn tells you what it want&#8217;s to eat, and you fetch it, and the unicorn poops a delicious, huge, coffee bean. The coffee beans can be taken to the coffee machine and made into a hot cup of coffee, giving you a 10% boost in the amount of coffee you contain. At 100% you have won the game. At 0% you have lost.<br>There are two other ways to loos the game, but that is for you to find out by playing it.<br>I hope you will spend a few minutes playing, and hopefully enjoy it. Thanks.<br><br> &#8211; H</p>



<p>Links to the  <a href="https://ldjam.com/events/ludum-dare/46/the-unicorn-and-the-need-for-coffee">Ludum Dare page</a>, and the <a href="https://incd021.com/LD46/index.html">HTML5 version</a>.</p>



<p><br></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2020/04/22/ld46-the-unicorn-and-the-need-for-coffee/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Don&#8217;t Stub Your Big Toe</title>
		<link>https://incd021.com/2014/10/20/dont-stub-big-toe/</link>
					<comments>https://incd021.com/2014/10/20/dont-stub-big-toe/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Mon, 20 Oct 2014 09:29:14 +0000</pubDate>
				<category><![CDATA[#30daydev]]></category>
		<category><![CDATA[Game]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=603</guid>

					<description><![CDATA[@INCD021 We wrote a poem about your game Don&#39;t Stub Your Big Toe! http://t.co/9NPdGVe8Q1 &#8212; Poems About Games (@PoemsAboutGames) October 20, 2014]]></description>
										<content:encoded><![CDATA[<blockquote class="twitter-tweet" lang="en">
<p><a href="https://twitter.com/INCD021">@INCD021</a> We wrote a poem about your game Don&#39;t Stub Your Big Toe! <a href="http://t.co/9NPdGVe8Q1">http://t.co/9NPdGVe8Q1</a></p>
<p>&mdash; Poems About Games (@PoemsAboutGames) <a href="https://twitter.com/PoemsAboutGames/status/524026811706257408">October 20, 2014</a></p></blockquote>
<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/10/20/dont-stub-big-toe/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ladders Unity and #30daydev</title>
		<link>https://incd021.com/2014/10/08/ladders-unity-30daydev/</link>
					<comments>https://incd021.com/2014/10/08/ladders-unity-30daydev/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Wed, 08 Oct 2014 08:44:14 +0000</pubDate>
				<category><![CDATA[#30daydev]]></category>
		<category><![CDATA[Game]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=598</guid>

					<description><![CDATA[Making a lot of small games, and only thinking about making it work and not on optimization and correct structures, have made a lot of old problems vanish. 🙂 For....]]></description>
										<content:encoded><![CDATA[<p>Making a lot of small games, and only thinking about making it work and not on optimization and correct structures, have made a lot of old problems vanish. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> For instance, months back I spend days on a small problem with a character and detecting when he was on a ladder, it ended with me shelving the project.. It should have been soooo simple, but my character was made up of 3 colliders, and they where animated, so using OnTriggerEnter2d didn&#8217;t work as I got an &#8220;enter&#8221; on one collider and another &#8220;enter&#8221; for the next and so on, and the same when one collider would &#8220;exit&#8221; the ladder collider. But now doing other small projects and optimization isn&#8217;t in focus, I wanted to revisit it, and as clear as it should have been back months ago, the solution was clear. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Just make a child GameObject add a small collider on a layer that only interacts with ladders and a small script detection OnTriggerEnter/Exit2d and send the information to the parent script. I haven&#8217;t tested it yet, but can&#8217;t see why it shouldn&#8217;t work <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The <a href="http://jams.gamejolt.io/30daydev/games">#30daydev</a> have already given me so much, and I&#8217;m only halfway there. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I&#8217;ll keep learning..</p>
<p>Now, go make games! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/10/08/ladders-unity-30daydev/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Paper Racer</title>
		<link>https://incd021.com/2014/09/16/paper-racer/</link>
					<comments>https://incd021.com/2014/09/16/paper-racer/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Tue, 16 Sep 2014 21:13:25 +0000</pubDate>
				<category><![CDATA[#30daydev]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=593</guid>

					<description><![CDATA[Did it, after to many hours.. My 7th ‪#‎30daydev‬ game done! Hope you enjoy &#8220;Paper Racer&#8220;, a very slow paced game. It&#8217;s an old turn based racing game we used....]]></description>
										<content:encoded><![CDATA[<p>Did it, after to many hours.. My 7th ‪<a href="http://jams.gamejolt.io/30daydev/games">#‎30daydev</a>‬ game done! Hope you enjoy &#8220;<a href="http://gamejolt.com/games/strategy-sim/paper-race/34513/">Paper Racer</a>&#8220;, a very slow paced game.</p>
<p>It&#8217;s an old turn based racing game we used to play on paper when I was a kid.<br />
You have to select one of 8 possible moves, the next move will start by moving the same amount as you did last move.</p>
<p>So if you moved 1 step forward as your first move, the next 8 possible moves will be around 1 step forward from your current position.</p>
<p><a href="https://incd021.com/wp-content/uploads/2014/09/PRThumb.png"><img fetchpriority="high" decoding="async" class="aligncenter size-medium wp-image-595" src="https://incd021.com/wp-content/uploads/2014/09/PRThumb-300x168.png" alt="PRThumb" width="300" height="168" /></a></p>
<p>The hard part is trying to gain maximum speed and to remember to brake in do time. 70% of the time you gain to much speed and won&#8217;t be able to turn in time. BOOM!</p>
<p>Again it took waaay to long to develop. This time caused by a small oversight on my part that took hours to find I missed some coliders/layer in my raycast</p>
<p>Now it&#8217;s time for ZZzzzzzzzz&#8230;&#8230;&#8230;</p>
<p>Now, go make games!</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/09/16/paper-racer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Yell At It..!</title>
		<link>https://incd021.com/2014/09/13/yell/</link>
					<comments>https://incd021.com/2014/09/13/yell/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sat, 13 Sep 2014 14:03:04 +0000</pubDate>
				<category><![CDATA[#30daydev]]></category>
		<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=587</guid>

					<description><![CDATA[Yet another #30daydev game.My son Jesper Bergmann (7) allowed me to make another #30daydev game today, 5th so far. He did the level design. Dad is so proud 😀 As....]]></description>
										<content:encoded><![CDATA[<p>Yet another <a href="http://jams.gamejolt.io/30daydev/games">#30daydev</a> game.My son Jesper Bergmann (7) allowed me to make another <a href="http://jams.gamejolt.io/30daydev/games">#30daydev</a> game today, 5th so far.<br />
He did the level design. Dad is so proud <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><a href="https://incd021.com/wp-content/uploads/2014/09/YellSS.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-588" src="https://incd021.com/wp-content/uploads/2014/09/YellSS-300x168.png" alt="YellSS" width="300" height="168" /></a><br />
As the name sugests you have you yell at the game, to move. The louder you yell the further the player objects move apart.</p>
<p>I added a sencitivity slider to adjust the needed sound volumen to move, so you don&#8217;t really have to yell at the game.</p>
<p><strong>The game only works if you allow it to use the default microphone of your computer, so if you don&#8217;t want to, then sorry you won&#8217;t be able to play.</strong></p>
<p>Have fun yelling at <a title="Late update, POC’s and current work" href="http://gamejolt.com/dashboard/developer/games/view/34320/">gamejolt</a></p>
<p>Now, go make games!<br />
&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/09/13/yell/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>LD30 &#8211; LD48 &#8211; Join Us!</title>
		<link>https://incd021.com/2014/08/24/ld30-ld48-join-us/</link>
					<comments>https://incd021.com/2014/08/24/ld30-ld48-join-us/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 24 Aug 2014 19:15:31 +0000</pubDate>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[48 hours]]></category>
		<category><![CDATA[Game development]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=580</guid>

					<description><![CDATA[Ok, so I entered my first Ludum Dare, with expectations set high.  When the theme was announced (3 am here in Denmartk) I was a bit disappointed.. It was the....]]></description>
										<content:encoded><![CDATA[<p>Ok, so I entered my first Ludum Dare, with expectations set high.  When the theme was announced (3 am here in Denmartk) I was a bit disappointed.. It was the one theme I really didn&#8217;t like &#8220;Connected Worlds&#8221;. I wanted &#8220;Potato Salat&#8221; I wanted to make a game with a potato running from forks and knifes, NOT to become part of the &#8220;Potato Salat&#8221;.</p>
<p>I had to think of something? Sleeping until 7 and didn&#8217;t help, food and a shower.. Now an idea started to form. The void ship from the Dr. Who series and the hunt for the Maquis from Star Trek, void ship = between worlds,  hunt for the Maquis = turbulent and violent space.. hmmm. To the blackboard, and draw 3D, draw 2.5D, ok then 2d.. Couldn&#8217;t figure out how I wanted the game to look, as I would like to do it in 2d (haven&#8217;t done 3d since unity came out with their 2d support), I just couldn&#8217;t squash the 3D into 2D.</p>
<p>Remembering that I only had 48 hours and 5 was gone sleeping, eating and showering already. I had to keep it simple. So why not having two universes, one on top of the screen and one on the bottom, and having to fight invaders from the other universe. So I set out to do so.</p>
<p>What I have ended up with is almost that. Only change is that the enemy ships are wormhole generators that you have to shoot down before they can open a wormhole, and there by destroying the other universe (I have allowed myself some freedoms as I do not know how wormhole from a universe with other lawn of nature would impact our universe or it&#8217;s even possible).</p>
<p>You can play the game <a href="https://incd021.com/Games/LD30/LD30.html">Join Us!</a> online, or download the <a href="https://incd021.com/Games/LD30/JoinUs.zip" target="_blank" rel="noopener">PC version here</a>.</p>
<p><a href="https://incd021.com/wp-content/uploads/2014/08/JoinUsScreenShot.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-582" src="https://incd021.com/wp-content/uploads/2014/08/JoinUsScreenShot-300x168.png" alt="JoinUsScreenShot" width="300" height="168" /></a></p>
<p>Learned a lot, especially not to optimize as much as I do. I have done some things where I thought, this will be slow, but it&#8217;s micro seconds, so doesn&#8217;t matter. Ended up with at most 10 draw calls which is nothing. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Now I have uploaded the PC version and the web version to <a href="http://ludumdare.com">Ludum Dare</a> I don&#8217;t really wan&#8217;t to work on it any more, I&#8217;m mentally tired and just want to relax and not think about &#8220;Join Us!&#8221; anymore,  for now&#8230;</p>
<p>It&#8217;s been fun and amazing to see how much you can do, when you don&#8217;t focus on having to deliver something amazing and super polished, but just a game someone would enjoy <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> So hope you will play it, enjoy it, and rate it on <a href="http://ludumdare.com">Ludum Dare</a>.</p>
<p>Now, go make games <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/08/24/ld30-ld48-join-us/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Page Caching using Disk: Enhanced 

Served from: incd021.com @ 2025-05-13 15:54:24 by W3 Total Cache
-->