<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>leblog</title>
    <link>https://devlog.lejulien.link/</link>
    <description></description>
    <pubDate>Sat, 22 Aug 2026 17:14:11 +0000</pubDate>
    <item>
      <title>Learning A New Keyboard Layout : Workman</title>
      <link>https://devlog.lejulien.link/learning-a-new-keyboard-layout-workman</link>
      <description>&lt;![CDATA[workman layout&#xA;&#xA;  The quick brown fox jumps over the lazy dog.&#xA;&#xA;Introduction&#xA;I was thinking for a long time about changing my keyboard layout&#xA;I realized that it will take a significant amount of time to get used to it.&#xA;So choosing the correct one for my usage was key.&#xA;&#xA;Back-story&#xA;During high-school, I was going back and forth between QWERTY and AZERTY, due to the fact that every keyboards of my school were QWERTY and I&#39;ve been taught computers in France so the layout was AZERTY...&#xA;At 16, I got a surgery for a rupture of the flexor tendons of my index finger.&#xA;So finding a way to avoid typing stress pain was always in my mind.&#xA;I did search for convenient keyboard layouts, moving from staggered to matrix and ergonomic keyboards, there was always something that were creating stress and pain to my tendons. &#xA;I kept the previous QWERTY layout for years until now though.&#xA;I&#39;ve ended up choosing workman as the new layout but this choice results from trials and errors that I&#39;ll explain in the following section. &#xA;&#xA;Reflection&#xA;This post is the first time I&#39;m using the workman layout as a full commitment, and I must say, I still struggle with it, usual thing that happened before when I tried Colemak. &#xA;But I think it will be beneficial in the long run, as it is designed to reduce finger movement.&#xA;Even though my typing speed as decreased, I can feel this the typing became less painful for my tendons.&#xA;Workman is specifically optimized for typing English and code, though I am French,&#xA;I still am able to type accents using Linux&#39;s compose key.&#xA;I&#39;ll see how it goes in the future.&#xA;&#xA;Resources&#xA;The official workman website&#xA;FUTO the android keyboard&#xA;keybr an awesome progressive touch typing practice website ]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://github.com/kdeloach/workman/raw/gh-pages/images/workman_layout.png" alt="workman layout"></p>

<blockquote><p>The quick brown fox jumps over the lazy dog.</p></blockquote>

<h2 id="introduction">Introduction</h2>

<p>I was thinking for a long time about changing my keyboard layout
I realized that it will take a significant amount of time to get used to it.
So choosing the correct one for my usage was key.</p>

<h2 id="back-story">Back-story</h2>

<p>During high-school, I was going back and forth between QWERTY and AZERTY, due to the fact that every keyboards of my school were QWERTY and I&#39;ve been taught computers in France so the layout was AZERTY...
At 16, I got a surgery for a rupture of the flexor tendons of my index finger.
So finding a way to avoid typing stress pain was always in my mind.
I did search for convenient keyboard layouts, moving from staggered to matrix and ergonomic keyboards, there was always something that were creating stress and pain to my tendons.
I kept the previous QWERTY layout for years until now though.
I&#39;ve ended up choosing workman as the new layout but this choice results from trials and errors that I&#39;ll explain in the following section.</p>

<h2 id="reflection">Reflection</h2>

<p>This post is the first time I&#39;m using the workman layout as a full commitment, and I must say, I still struggle with it, usual thing that happened before when I tried Colemak.
But I think it will be beneficial in the long run, as it is designed to reduce finger movement.
Even though my typing speed as decreased, I can feel this the typing became less painful for my tendons.
Workman is specifically optimized for typing English and code, though I am French,
I still am able to type accents using Linux&#39;s compose key.
I&#39;ll see how it goes in the future.</p>

<h2 id="resources">Resources</h2>
<ul><li><a href="https://workmanlayout.org/">The official workman website</a></li>
<li><a href="https://keyboard.futo.tech/">FUTO the android keyboard</a></li>
<li><a href="https://www.keybr.com">keybr an awesome progressive touch typing practice website</a></li></ul>
]]></content:encoded>
      <guid>https://devlog.lejulien.link/learning-a-new-keyboard-layout-workman</guid>
      <pubDate>Wed, 19 Aug 2026 11:55:39 +0000</pubDate>
    </item>
    <item>
      <title>Language learning and simplified complexity</title>
      <link>https://devlog.lejulien.link/language-learning-and-simplified-complexity</link>
      <description>&lt;![CDATA[Summary&#xA;&#xA;I was always fond of learning new languages, got to learn Spanish and English at school. Those were tedious to learn and tend to take a long time to get used to and perfect the usage.&#xA;With time, I ended up loosing most of my Spanish and daily-using the English, but I was always thirsty of learning new languages. The issue was that having engineering studies and then a full time job doesn&#39;t let me a lot of time to have a professor in a new language. But non the less, I&#39;ve tried some other languages, Russian, Japanese, Portuguese and no cigar.&#xA;But one day while I was doom-scrolling on Youtube, I&#39;ve ended up looking a video of a random developer that was sharing it&#39;s process of making a quiz for a language that I have no idea it existed.&#xA;Toki pona.&#xA;And this is about this language that I want to talk you about.&#xA;It&#39;s name can be translated by the language of good, and what caught my attention was it&#39;s small learning curve and it&#39;s simplicity, it&#39;s dictionary is composed of 131 words as the date of today.&#xA;&#xA;short history&#xA;&#xA;The language was created in 2001 by Sonja Lang a linguist and translator whilst she were is depression.&#xA;The language is minimalist by design and offers wide variations of writing is making it a fun language.&#xA;&#xA;learning process&#xA;&#xA;I was surprised how many references and instructional there was on a language that doesn&#39;t have that many interlocutors.&#xA;The thing is that since it has the same ideas as the Esperanto and it&#39;s words origins are wider spread, a lot of persons have found interest in it through time.&#xA;Some of the main resources I&#39;ve found allowed me to learn the basic vocabulary in the span of a week and a half.&#xA;Here is some of my recommendations if the adventure tempts you :&#xA;wasona : A simple but mostly complete site that allows you to learn how to form sentences and learn the words in an interactive manner. This site is available in multiple languages (and french was there !!!)&#xA;jan Kekan San&#39;s courses : An English Toki Pona teacher that provides well made lessons that allow you to form vague sentences to conversations with more complex and precise subjects.&#xA;The Toki Pona android APK : This one is good to train vocabulary or search for pre-made sentences, I&#39;ve seen it being more and more complete with features.&#xA;&#xA;mi tawa.]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="summary">Summary</h2>

<p>I was always fond of learning new languages, got to learn Spanish and English at school. Those were tedious to learn and tend to take a long time to get used to and perfect the usage.
With time, I ended up loosing most of my Spanish and daily-using the English, but I was always thirsty of learning new languages. The issue was that having engineering studies and then a full time job doesn&#39;t let me a lot of time to have a professor in a new language. But non the less, I&#39;ve tried some other languages, Russian, Japanese, Portuguese and no cigar.
But one day while I was doom-scrolling on Youtube, I&#39;ve ended up looking a <a href="https://youtu.be/yKJO4hsSY8c?si=xZMkmPcEF4xQXYjM">video</a> of a random developer that was sharing it&#39;s process of making a quiz for a language that I have no idea it existed.
Toki pona.
And this is about this language that I want to talk you about.
It&#39;s name can be translated by the language of good, and what caught my attention was it&#39;s small learning curve and it&#39;s simplicity, it&#39;s dictionary is composed of 131 words as the date of today.</p>

<h2 id="short-history">short history</h2>

<p>The language was created in 2001 by Sonja Lang a linguist and translator whilst she were is depression.
The language is minimalist by design and offers wide variations of writing is making it a fun language.</p>

<h2 id="learning-process">learning process</h2>

<p>I was surprised how many references and instructional there was on a language that doesn&#39;t have that many interlocutors.
The thing is that since it has the same ideas as the Esperanto and it&#39;s words origins are wider spread, a lot of persons have found interest in it through time.
Some of the main resources I&#39;ve found allowed me to learn the basic vocabulary in the span of a week and a half.
Here is some of my recommendations if the adventure tempts you :
– <a href="https://wasona.com/">wasona</a> : A simple but mostly complete site that allows you to learn how to form sentences and learn the words in an interactive manner. This site is available in multiple languages (and french was there !!!)
– <a href="https://www.youtube.com/watch?v=J93GWOMbgdg&amp;list=PLoLQoll2U6WEeCO7C2oc1LTWgkoBC8rvT&amp;pp=0gcJCf4COCosWNin">jan Kekan San&#39;s courses</a> : An English Toki Pona teacher that provides well made lessons that allow you to form vague sentences to conversations with more complex and precise subjects.
– <a href="https://play.google.com/store/apps/details?id=com.seralto.tokipona">The Toki Pona android APK</a> : This one is good to train vocabulary or search for pre-made sentences, I&#39;ve seen it being more and more complete with features.</p>

<p>mi tawa.</p>
]]></content:encoded>
      <guid>https://devlog.lejulien.link/language-learning-and-simplified-complexity</guid>
      <pubDate>Mon, 17 Aug 2026 13:25:41 +0000</pubDate>
    </item>
    <item>
      <title>💻 Kernel dev light setup</title>
      <link>https://devlog.lejulien.link/kernel-dev-light-setup</link>
      <description>&lt;![CDATA[Summary&#xA;&#xA;This explains my steps into creating a “lightweight” Linux kernel development environment using qemu. &#xA;&#xA;Setup base system&#xA;&#xA;Create the installation image&#xA;&#xA;qemu-img create -f qcow2 image-name.qcow2 size&#xA;&#xA;Install an Operating system of choice ( I use debian for this )&#xA;&#xA;qemu-system-x8664 -cpu host     \&#xA;                    -vga virtio  \&#xA;                    -enable-kvm  \&#xA;                    -usb -device usb-tablet \&#xA;                    -hda qemu image -boot d \&#xA;                    -cdrom debian iso file \&#xA;                    -serial stdio -m ram \&#xA;                    -smp cpu&#xA;&#xA;Perform os installation then reboot using this command&#xA;&#xA;qemu-system-x8664 -nic user,hostfwd=tcp::1234-:22 \&#xA;                    -cpu host \&#xA;                    -vga virtio \&#xA;                    -enable-kvm \&#xA;                    -usb -device usb-tablet \&#xA;                    -hda qemu image -boot d \&#xA;                    -serial stdio \&#xA;                    -m ram -smp cpu&#xA;&#xA;Prepare the system&#xA;&#xA;On the graphical output do this&#xA;&#xA;su&#xA;input root password&#xA;apt install ssh&#xA;&#xA;You can now ssh into the vm to setup the required packages&#xA;&#xA;ssh -p 1234 username@localhost&#xA;apt update&#xA;apt install build-essential \&#xA;&#x9;&#x9;&#x9;neovim \&#xA;  &#x9;&#x9;&#x9;libncurses-dev \&#xA;    &#x9;&#x9;libssl-dev \&#xA;     &#x9;&#x9;bc \&#xA;&#x9;&#x9;&#x9;libelf-dev \&#xA;  &#x9;&#x9;&#x9;git \&#xA;    &#x9;&#x9;flex \&#xA;     &#x9;&#x9;bison \&#xA;      &#x9;&#x9;fakeroot \&#xA;       &#x9;&#x9;libperl-dev \&#xA;        &#x9;qt5-qmake \&#xA;        &#x9;qtbase5-dev \&#xA;        &#x9;rsync&#xA;&#xA;Build a new kernel&#xA;&#xA;Now download the Linux sources&#xA;&#xA;  Execute as user&#xA;&#xA;git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -b kernelversion&#xA;cd linux&#xA;&#xA;Next is to build a kernel compatible with your vm&#xA;&#xA;make mrproper &amp;&amp; make localmodconfig&#xA;&#xA;Compile it&#xA;&#xA;make -j$(nrpoc)&#xA;&#xA;  Executed as root&#xA;&#xA;make modulesinstall &amp;&amp; make install&#xA;&#xA;Ensure  you have access to sbin to update grub in order to boot onto the new kernel.&#xA;&#xA;echo &#34;export PATH=/usr/sbin:$PATH&#34;     ~/.bashrc&#xA;source ~/.bashrc&#xA;&#xA;  Writing the export in the shell profile allow to not worry about exporting it again later&#xA;&#xA;update-grub or grub-update&#xA;&#xA;Now you’re done, reboot to start with the new kernel !&#xA;&#xA;Compacting the qcow2 image&#xA;&#xA;First off, install zerofree on the host&#xA;&#xA;  On the host&#xA;&#xA;Load nbd kernel module&#xA;sudo modprobe nbd maxpart=8&#xA;&#xA;Connect the QCOW2 image to a /dev/nbd device&#xA;sudo qemu-nbd --connect=/dev/nbd0 working-image.qcow2&#xA;&#xA;Create partition mappings&#xA;sudo kpartx -av /dev/nbd0&#xA;&#xA;Identify partition mappings&#xA;sudo blkid /dev/mapper/nbd0p*&#xA;&#xA;Check and clear partition if needed&#xA;sudo e2fsck -f /dev/mapper/nbd0p1&#xA;&#xA;Ensure the partition isn&#39;t mounted&#xA;mount | grep /dev/mapper/nbd0p1  # should be empty&#xA;&#xA;Apply zerofree&#xA;sudo zerofree /dev/mapper/nbd0p1&#xA;&#xA;Cleanup mounts&#xA;sudo kpartx -dv /dev/nbd0&#xA;sudo qemu-nbd --disconnect /dev/nbd0&#xA;&#xA;Now your image should be as minimal as possible !&#xA;&#xA;Qemu keyboard emulation&#xA;&#xA;To emulate a keyboard with qemu, you can add this flag to the launch command&#xA;&#xA;qemu ... --monitor stdio ...&#xA;&#xA;This will enable the qemu monitor on the current terminal&#xA;&#xA;To trigger a keyboard plugged in &#xA;&#xA;deviceadd usb-kbd,id=keyboard1&#xA;&#xA;To trigger a  keyboard removed&#xA;&#xA;device_del keyboard1&#xA;&#xA;Retrospective&#xA;&#xA;Since then, I have tried many other methods, and even though qemu is practical, I rather used a more commonly use method like a dockerfile ( used in this project ).&#xA;At the time this post was made, I was still studying at a school where there were no best practices and hand-holding.]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="summary">Summary</h2>

<p>This explains my steps into creating a “lightweight” Linux kernel development environment using qemu.</p>

<h2 id="setup-base-system"><strong>Setup base system</strong></h2>

<p>Create the installation image</p>

<pre><code class="language-shell">qemu-img create -f qcow2 &lt;image-name&gt;.qcow2 &lt;size&gt;
</code></pre>

<p>Install an Operating system of choice ( I use debian for this )</p>

<pre><code class="language-bash">qemu-system-x86_64 -cpu host     \
                    -vga virtio  \
                    -enable-kvm  \
                    -usb -device usb-tablet \
                    -hda &lt;qemu image&gt; -boot d \
                    -cdrom &lt;debian iso file&gt; \
                    -serial stdio -m &lt;ram&gt; \
                    -smp &lt;cpu&gt;
</code></pre>

<p>Perform os installation then reboot using this command</p>

<pre><code class="language-bash">qemu-system-x86_64 -nic user,hostfwd=tcp::1234-:22 \
                    -cpu host \
                    -vga virtio \
                    -enable-kvm \
                    -usb -device usb-tablet \
                    -hda &lt;qemu image&gt; -boot d \
                    -serial stdio \
                    -m &lt;ram&gt; -smp &lt;cpu&gt;
</code></pre>

<h3 id="prepare-the-system"><strong>Prepare the system</strong></h3>

<p>On the graphical output do this</p>

<pre><code class="language-bash">su
&lt;input root password&gt;
apt install ssh
</code></pre>

<p>You can now ssh into the vm to setup the required packages</p>

<pre><code class="language-bash">ssh -p 1234 &lt;username&gt;@localhost
apt update
apt install build-essential \
			neovim \
  			libncurses-dev \
    		libssl-dev \
     		bc \
			libelf-dev \
  			git \
    		flex \
     		bison \
      		fakeroot \
       		libperl-dev \
        	qt5-qmake \
        	qtbase5-dev \
        	rsync
</code></pre>

<h2 id="build-a-new-kernel"><strong>Build a new kernel</strong></h2>

<p>Now download the Linux sources</p>

<blockquote><p>Execute as user</p></blockquote>

<pre><code class="language-bash">git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -b &lt;kernel_version&gt;
cd linux
</code></pre>

<p>Next is to build a kernel compatible with your vm</p>

<pre><code class="language-bash">make mrproper &amp;&amp; make localmodconfig
</code></pre>

<p>Compile it</p>

<pre><code class="language-bash">make -j$(nrpoc)
</code></pre>

<blockquote><p>Executed as root</p></blockquote>

<pre><code class="language-bash">make modules_install &amp;&amp; make install
</code></pre>

<p>Ensure  you have access to sbin to update grub in order to boot onto the new kernel.</p>

<pre><code class="language-bash">echo &#34;export PATH=/usr/sbin:$PATH&#34; &gt;&gt; ~/.bashrc
source ~/.bashrc
</code></pre>

<blockquote><p>Writing the export in the shell profile allow to not worry about exporting it again later</p></blockquote>

<pre><code class="language-bash">update-grub or grub-update
</code></pre>

<p>Now you’re done, reboot to start with the new kernel !</p>

<h2 id="compacting-the-qcow2-image"><strong>Compacting the qcow2 image</strong></h2>

<p>First off, install <code>zerofree</code> on the host</p>

<blockquote><p>On the host</p></blockquote>

<pre><code class="language-bash"># Load nbd kernel module
sudo modprobe nbd max_part=8

# Connect the QCOW2 image to a /dev/nbd device
sudo qemu-nbd --connect=/dev/nbd0 working-image.qcow2

# Create partition mappings
sudo kpartx -av /dev/nbd0

# Identify partition mappings
sudo blkid /dev/mapper/nbd0p*

# Check and clear partition if needed
sudo e2fsck -f /dev/mapper/nbd0p1

# Ensure the partition isn&#39;t mounted
mount | grep /dev/mapper/nbd0p1  # should be empty

# Apply zerofree
sudo zerofree /dev/mapper/nbd0p1

# Cleanup mounts
sudo kpartx -dv /dev/nbd0
sudo qemu-nbd --disconnect /dev/nbd0
</code></pre>

<p>Now your image should be as minimal as possible !</p>

<h2 id="qemu-keyboard-emulation"><strong>Qemu keyboard emulation</strong></h2>

<p>To emulate a keyboard with qemu, you can add this flag to the launch command</p>

<pre><code class="language-bash">qemu ... --monitor stdio ...
</code></pre>

<p>This will enable the qemu monitor on the current terminal</p>

<p>To trigger a keyboard plugged in</p>

<pre><code class="language-bash">device_add usb-kbd,id=keyboard1
</code></pre>

<p>To trigger a  keyboard removed</p>

<pre><code class="language-bash">device_del keyboard1
</code></pre>

<h1 id="retrospective">Retrospective</h1>

<p>Since then, I have tried many other methods, and even though qemu is practical, I rather used a more commonly use method like a dockerfile ( used in this <a href="https://git.lejulien.link/lejulien/lfs-2026">project</a> ).
At the time this post was made, I was still studying at a school where there were no best practices and hand-holding.</p>
]]></content:encoded>
      <guid>https://devlog.lejulien.link/kernel-dev-light-setup</guid>
      <pubDate>Mon, 17 Aug 2026 09:38:09 +0000</pubDate>
    </item>
    <item>
      <title>Game of life editor</title>
      <link>https://devlog.lejulien.link/game-of-life-editor</link>
      <description>&lt;![CDATA[Summary&#xA;&#xA;This was a project that I’ve itterated mutiple times without event trying to go further that the first rendering. This is my ways on improving a simple game of life editor but with plenty of editing features.&#xA;&#xA;Core ideas &amp; application:&#xA;&#xA;The first things that I wanned to add on the basic project is a setting and a pause/play option.&#xA;&#xA;In order to do this, I used dearImGUI on top of raylib rendering, the whole project is implemented in C++.&#xA;&#xA;This is what I’ve implemented so far.&#xA;&#xA; &#xA;&#xA;The following steps are what will take me a lot of brain process.&#xA;In order to add more advanced features, I need to optimize this base.&#xA;&#xA;As for now, the grid is stored in a vector of booleans, this causes an issue of memory as we can set the current cells sizes really small.&#xA;The first topic I will bring here for now is the data compression.&#xA;This will allow me to create saves of the current grid in a memory efficient way.&#xA;&#xA;Optimisation &amp; patern reproduction&#xA;&#xA;I wanned to implement a way to start from an initial state and step forward &amp; backward.&#xA;This means storing an history.&#xA;If done like it is implemented right now (as vectors of booleans), this will take too much space in memory.&#xA;Here is my though on the improvments.&#xA;&#xA;Data compression :&#xA;&#xA;Packed data:&#xA;&#xA;The initial state (to reduce load time or file size).&#xA;Undo/redo snapshots (for compact state history) with history buffer of packed data.&#xA;Any export/serialization (like RLE or bitstream).&#xA;&#xA;Unpacked data:&#xA;&#xA;Only once, when loading the initial grid to GPU.&#xA;When restoring an undo/redo state.&#xA;&#xA;RLE(Lossless compression) :&#xA;&#xA;The first type of compression that I&#39;ve implemented was the RLE and it just compacts the data that is represented multiple times into a shorter representation. &#xA;&#xA;As the game of life contains only 2 types, it is easier to implement. &#xA;&#xA;There could be multiple dead or alive cells that are stored into a 1D array. &#xA;&#xA;To achieve my goal, I want to compressed any grid sizes to have a shorter representation. &#xA;&#xA;Here is my first iteration on this. &#xA;&#xA;gridwidth.gridheight.initialstate.nbr.nbr.…&#xA;&#xA;// data is a vector of bool that contains each cell states&#xA;std::string World::getCompressed() {&#xA;  if (!data || data-  empty()) {&#xA;    return {};&#xA;  }&#xA;  bool previousstate = (data)[0];&#xA;  std::vectoruint32t compressedout;&#xA;  compressedout.pushback(width);&#xA;  compressedout.pushback(height);&#xA;  compressedout.pushback((previousstate) ? 1 : 0);&#xA;  unsigned int count = 0;&#xA;  for (auto state : data) {&#xA;    if (previousstate != state) {&#xA;      compressedout.pushback(count++);&#xA;      previousstate = state;&#xA;      count = 1;&#xA;      continue;&#xA;    }&#xA;    count++;&#xA;  }&#xA;  compressedout.pushback(count);&#xA;  return compressedout;&#xA;}&#xA;&#xA;// Ex for a grid of 33 x 18&#xA;// std vectorbool data = {true, true, true, false, false, true, true, false, true, false until the end};&#xA;// the compressed method results in 33.18.1.3.2.2.1.1.585&#xA;&#xA;This seems easy enough, now the decompression algorythm.&#xA;&#xA;void World::loadCompressed(const std::vectoruint32t &amp;compressed) {&#xA;  if (compressed.empty()) {&#xA;    return;&#xA;  }&#xA;  auto it = compressed.begin();&#xA;  int width = it++;&#xA;  int height = it++;&#xA;  bool actualstate = (it++ == 1);&#xA;  auto newdata = new std::vectorbool(width  height, false);&#xA;  while (it != compressed.end()) {&#xA;    unsigned int count = *it++;&#xA;    for (unsigned int i = 0; i &lt; count; ++i) {&#xA;      newdata-  pushback(actualstate);&#xA;    }&#xA;    actualstate = !actualstate;&#xA;  }&#xA;  delete this-  data;&#xA;  this-  data = newdata;&#xA;  this-  width = width;&#xA;  this-  _height = height;&#xA;}&#xA;`]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="summary">Summary</h2>

<p>This was a project that I’ve itterated mutiple times without event trying to go further that the first rendering. This is my ways on improving a simple game of life editor but with plenty of editing features.</p>

<h2 id="core-ideas-application"><strong>Core ideas &amp; application</strong>:</h2>

<p>The first things that I wanned to add on the basic project is a setting and a pause/play option.</p>

<p>In order to do this, I used dearImGUI on top of raylib rendering, the whole project is implemented in C++.</p>

<p>This is what I’ve implemented so far.</p>

<p> <img src="https://outline.lejulien.link/api/files.get?sig=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1cGxvYWRzLzFlN2U5NmY5LTljZTItNDA5OC1iYmQ4LWM2NDIwNjllMDdlOS8xYmQyMTE4YS0zM2U5LTQ3ZWQtYWE5NC1jNWExNjYwOTlkOTUvR2FtZU9mTGlmZUVkaXRvckJhc2UucG5nIiwidHlwZSI6ImF0dGFjaG1lbnQiLCJpYXQiOjE3ODY5NTYyMTYsImV4cCI6MTc4NzU2MTAxNn0.rQ4wh3UlJa9bXZqsfLsh14XCwfSiFBCYIKkzrbPfKSs" alt=""></p>

<p>The following steps are what will take me a lot of brain process.
In order to add more advanced features, I need to optimize this base.</p>

<p>As for now, the grid is stored in a vector of booleans, this causes an issue of memory as we can set the current cells sizes really small.
The first topic I will bring here for now is the data compression.
This will allow me to create saves of the current grid in a memory efficient way.</p>

<h2 id="optimisation-patern-reproduction">Optimisation &amp; patern reproduction</h2>

<p>I wanned to implement a way to start from an initial state and step forward &amp; backward.
This means storing an history.
If done like it is implemented right now (as vectors of booleans), this will take too much space in memory.
Here is my though on the improvments.</p>

<h3 id="data-compression"><strong>Data compression :</strong></h3>

<p><strong>Packed data</strong>:</p>
<ul><li>The initial state (to reduce load time or file size).</li>
<li>Undo/redo snapshots (for compact state history) with history buffer of packed data.</li>
<li>Any export/serialization (like RLE or bitstream).</li></ul>

<p><strong>Unpacked data</strong>:</p>
<ul><li>Only once, when loading the initial grid to GPU.</li>
<li>When restoring an undo/redo state.</li></ul>

<h4 id="rle-lossless-compression"><strong>RLE(Lossless compression)</strong> :</h4>

<p>The first type of compression that I&#39;ve implemented was the RLE and it just compacts the data that is represented multiple times into a shorter representation.</p>

<p>As the game of life contains only 2 types, it is easier to implement.</p>

<p>There could be multiple dead or alive cells that are stored into a 1D array.</p>

<p>To achieve my goal, I want to compressed any grid sizes to have a shorter representation.</p>

<p>Here is my first iteration on this.</p>

<p><code>&lt;grid_width&gt;.&lt;grid_height&gt;.&lt;initial_state&gt;.&lt;nbr&gt;.&lt;nbr&gt;.&lt;…&gt;</code></p>

<pre><code class="language-cpp">// _data is a vector of bool that contains each cell states
std::string World::getCompressed() {
  if (!_data || _data-&gt;empty()) {
    return {};
  }
  bool previous_state = (*_data)[0];
  std::vector&lt;uint32_t&gt; compressed_out;
  compressed_out.push_back(_width);
  compressed_out.push_back(_height);
  compressed_out.push_back((previous_state) ? 1 : 0);
  unsigned int count = 0;
  for (auto state : *_data) {
    if (previous_state != state) {
      compressed_out.push_back(count++);
      previous_state = state;
      count = 1;
      continue;
    }
    count++;
  }
  compressed_out.push_back(count);
  return compressed_out;
}

// Ex for a grid of 33 x 18
// std vector&lt;bool&gt; _data = {true, true, true, false, false, true, true, false, true, &lt;false until the end&gt;};
// the compressed method results in 33.18.1.3.2.2.1.1.585
</code></pre>

<p>This seems easy enough, now the decompression algorythm.</p>

<pre><code class="language-cpp">void World::loadCompressed(const std::vector&lt;uint32_t&gt; &amp;compressed) {
  if (compressed.empty()) {
    return;
  }
  auto it = compressed.begin();
  int width = *it++;
  int height = *it++;
  bool actual_state = (*it++ == 1);
  auto new_data = new std::vector&lt;bool&gt;(width * height, false);
  while (it != compressed.end()) {
    unsigned int count = *it++;
    for (unsigned int i = 0; i &lt; count; ++i) {
      new_data-&gt;push_back(actual_state);
    }
    actual_state = !actual_state;
  }
  delete this-&gt;_data;
  this-&gt;_data = new_data;
  this-&gt;_width = width;
  this-&gt;_height = height;
}
</code></pre>
]]></content:encoded>
      <guid>https://devlog.lejulien.link/game-of-life-editor</guid>
      <pubDate>Mon, 17 Aug 2026 08:44:00 +0000</pubDate>
    </item>
  </channel>
</rss>