<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://romain.codes/feed.xml" rel="self" type="application/atom+xml" /><link href="https://romain.codes/" rel="alternate" type="text/html" /><updated>2026-01-27T14:15:42+00:00</updated><id>https://romain.codes/feed.xml</id><title type="html">Romain Pouclet</title><subtitle>Swit, Xcode, and Continuous Integration.</subtitle><entry><title type="html">199 dogs and counting</title><link href="https://romain.codes/2026/01/27/199-dogs-and-counting/" rel="alternate" type="text/html" title="199 dogs and counting" /><published>2026-01-27T05:33:00+00:00</published><updated>2026-01-27T05:33:00+00:00</updated><id>https://romain.codes/2026/01/27/199-dogs-and-counting</id><content type="html" xml:base="https://romain.codes/2026/01/27/199-dogs-and-counting/"><![CDATA[<p>Introduction my new pet project: a page where I show where I’ve run but most importantly, how many dogs I’ve seen.</p>

<p>TL;DR: you can check how many dogs I’ve seen during my runs <a href="https://dogs.romain.codes/">here</a>.</p>

<p>I mentioned in a <a href="/2026/01/12/2026-week-02/">week update</a> that I started counting the dogs I see during my runs. I realized that it was a good way to keep my mind just busy enough to enjoy the run without overthinking everything I have going on in my life right now, the news and so on. At first, I put those numbers in an Obsidian note, but then I realized it would be fun to make a tiny website for it.</p>

<p><img src="/assets/2026/counting-dogs-page.png" alt="A screenshot of the website showing that the total is 189 dogs and listing the first 2 runs" /></p>

<p>The website uses <a href="https://www.11ty.dev/">11ty</a>. I used it to create the website for <a href="https://sound.games/">Sound Games</a> and I really like it, even if the documentation feels a little “draw the rest of the owl”-y at times.</p>

<p>I’m storing the data in a basic JSON file:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="s2">"31/12/2025"</span><span class="p">,</span><span class="w">

        </span><span class="nl">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"New Westminster"</span><span class="p">,</span><span class="w">

        </span><span class="nl">"distance_in_km"</span><span class="p">:</span><span class="w"> </span><span class="mf">9.47</span><span class="p">,</span><span class="w">

        </span><span class="nl">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">72</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>Additionally, I’m using a data file named <code class="language-plaintext highlighter-rouge">eleventyComputed.js</code> that the engine will load if it exists, which allows you to transform existing data. In my case, I’m using it to compute the total number of dogs and store it into a variable named <code class="language-plaintext highlighter-rouge">total</code> that’s available in my layout:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">total</span><span class="p">:</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">data</span><span class="p">.</span><span class="nx">stats</span><span class="p">.</span><span class="nf">reduce</span><span class="p">((</span><span class="nx">acc</span><span class="p">,</span> <span class="nx">stat</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">acc</span> <span class="o">+</span> <span class="nx">stat</span><span class="p">.</span><span class="nx">count</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Finally, since it’s a very simple website to host, I decided to experiment a little. I followed <a href="https://european-alternatives.eu/blog/how-to-host-a-static-site-on-bunny-net-cdn-with-automatic-deployment">this article</a> and decided to put it on <a href="https://bunny.net">Bunny.net</a> (shameless <a href="https://bunny.net?ref=h67awnoh0d">referral link</a>), in the hope of moving this website out of Netlify. It didn’t take me long, I just had to create a storage zone, create a pull zone, configure the DNS and upload my generated website. I didn’t do the continuous deployment dance yet, because even I knows that would be overkill at this stage.</p>

<p>It was a really fun project to kickstart after spinning it in my head for a couple of days. I have a bunch of ideas that I want to implement because it’s a little boring-looking right now and it’s really hard to ignore that I lazily used <a href="https://getbootstrap.com/">Bootstrap</a>. A project like this needs to be <strong>at least</strong> 46% more whimsical. In the meantime, you can check how many dogs I’ve seen during my runs <a href="https://dogs.romain.codes/">here</a> or check out <a href="https://codeberg.org/palleas/dog-counts">the source code here</a>.</p>]]></content><author><name></name></author><category term="random" /><summary type="html"><![CDATA[Introduction my new pet project: a page where I show where I’ve run but most importantly, how many dogs I’ve seen.]]></summary></entry><entry><title type="html">2026 - Week 02</title><link href="https://romain.codes/2026/01/12/2026-week-02/" rel="alternate" type="text/html" title="2026 - Week 02" /><published>2026-01-12T06:57:00+00:00</published><updated>2026-01-12T06:57:00+00:00</updated><id>https://romain.codes/2026/01/12/2026-week-02</id><content type="html" xml:base="https://romain.codes/2026/01/12/2026-week-02/"><![CDATA[<p>This 2nd week of the year as been mostly catching up on stuff after coming back from a few days of vacations, while trying to stay motivated to go running when it’s been raining pretty much non stop.</p>

<p>I paused my lessons with the new trainer I’d found for running, because after taking a step back and thinking about it, I realized it wasn’t the right approach for me. Where I should have felt empowered and motivated, I realized I felt like shit when I wasn’t able to run one day because of… well, life. Instead I switched back to my original plan, which is meeting regularly with a physio I like who happens to specialize in running. We’re going to plan for some strength training on top of my homework runs to stay injury-free until the big day. I’ve also aquired a static bike for cheap on Facebook Marketplace, just because. As a result, my socials’ feed are now full of ads for a 2000$ peloton bike.</p>

<p>Speaking of homework runs, <a href="https://www.fitfirst.ca/">the shop</a> that organizes the running club I’ve been a part of for a couple of years now, has opened a new location. The original shop is in Burnaby, the new one is in Kitsilano. To celebrate the event, they organized a 19km run between the two locations. I struggled a lot on the second half, because of poor fuel and water planning on my part, but I’m glad I did it. I’m even more glad they’d hired a bus to take us back after. I only counted 48 dogs though, which is a little disappointing for a 2hours run.</p>

<p>Finally, I’ve spent a few hours printing a tool to re-spool some filament. It was probably my fault, but a reusable spool of filament sprung open during a print, causing the filament to run amok when I wanted to unload it. As a result, I needed to find a way to re-spool the filament, which meant printing a device dedicated to this. There is a running joke in the 3D printing community that once you get a printer, you mostly end up printing stuff for the printer itself… I guess it’s true in this situation. I haven’t attempted to respool yet, but I’m sure it will be a fun update next week.</p>

<h2 id="links-from-my-queue">Links from my queue</h2>

<ul>
  <li>Starting with a weird one, did you know that <a href="https://www.science.org/content/article/how-do-wombats-poop-cubes-scientists-get-bottom-mystery">wombats poop cubes</a>? I fell into a rabbit hole after <a href="https://toot.boston/@swachter/115837523881037721">someone pitched a game</a> called “shitting bricks”. Oh, they also <a href="https://www.popsci.com/environment/wombat-butts-kill/">fight using their ass</a>.</li>
  <li>Those two posts about macOS Tahoe’s <a href="https://tonsky.me/blog/tahoe-icons/">choice of icons</a> and the <a href="https://noheger.at/blog/2026/01/11/the-struggle-of-resizing-windows-on-macos-tahoe/">struggles with resizing</a> have been really painful to read. I think I’ll be sticking with Sequoia for a little while.</li>
  <li>I found <a href="https://sylvia.buzz/why-ive-ditched-my-notetaking-app">this article about ditching Bear</a> quite interesting, at a time where I’ve found myself taking way more notes than before. It’s spread across my physical notebook, my <a href="https://deskboardbuddy.com/">deskbuddy</a> and of course <a href="https://obsidian.md/">Obsidian</a>. It did cause me to do my regular tidying of notes a little earlier than usual, though.</li>
</ul>

<p>I’ll end things with a shameless plug for work-related stuff, but if you’re into chaotic (yet fun) games that you can play with friends, please add <a href="https://store.steampowered.com/app/4037180/Go_Ape_Ship/">Go, Ape Ship!</a> to your wishlist. If you’re curious about what we’ve been doing at <a href="https://sound.games/">Sound Games</a>, follow us <a href="https://mastodon.social/@soundgames">on Mastodon here</a>.</p>]]></content><author><name></name></author><category term="notes" /><summary type="html"><![CDATA[This 2nd week of the year as been mostly catching up on stuff after coming back from a few days of vacations, while trying to stay motivated to go running when it’s been raining pretty much non stop.]]></summary></entry><entry><title type="html">2026 - Week 01</title><link href="https://romain.codes/2026/01/05/2026-week-01/" rel="alternate" type="text/html" title="2026 - Week 01" /><published>2026-01-05T02:09:00+00:00</published><updated>2026-01-05T02:09:00+00:00</updated><id>https://romain.codes/2026/01/05/2026-week-01</id><content type="html" xml:base="https://romain.codes/2026/01/05/2026-week-01/"><![CDATA[<p>Last year I wrote 12 notes posts, which is better than the 2 posts I wrote in 2023 when I tried this trend. I’m hoping to do better this year, but we’ll see how it goes.</p>

<p>This past week as been composed of resting and chilling with my partner. We started an overdue rewatch of <a href="https://www.imdb.com/title/tt3526078/">Schitt’s Creek</a>, finally watched the first episode of <a href="https://www.imdb.com/title/tt22202452/">Pluribus</a> and cooked a lot of good food. The past few years have not ended well for us. It became almost a sad tradition to have to travel back to France at the last minute because of a family emergency of some kind. This year was quiet which we really appreciated.</p>

<p><img src="/assets/2026/weeknotes-2026-1-run-dogs.png" alt="A screenshot of a run on Garmin Connect, the full path is hidden. On top of it is a counter with the number 72" /></p>

<p>This year I’ve signed up to run the <a href="https://bmovanmarathon.ca/">BMO marathon in Vancouver</a>. A friend planted the seed in my head last year and I toyed with the idea for a few months before finally signing up. I’ve been running for long enough that I know I can run a decent half-marathon without training too extensively, so I wanted to challenge myself and see if I could commit to a more demanding schedule. I didn’t set any goals besides training properly and hopefully finishing the race. During the past couple of weeks, I’ve been slowly ramping up, running longer distances and counting the dogs I see. I’m supposed to run 19km on Saturday, so that should be interesting. I’m excited to meet weekly with my running buddies every Saturday morning for the next 5 months.</p>

<p><img src="/assets/2026/weeknotes-2026-1-lithophane.jpeg" alt="A rectangular box with a printed image that says even when you are feeling sad, there will always be people in the world" /></p>

<p>I finally took the time to look <a href="/2026/01/04/you-can-t-update-your-3d-printer-s-firmware-in-lan-only-mode/">into the issue</a> preventing me from using Bambu Studio 2 and I’ve been printing a lot of different objects, from stackable boxes to sort LEGO or puzzle pieces, to a lithophane made for a friend. I took a fun quote from their child and made it into a tiny box that lights up, which was pretty fun.</p>

<p>I was fairly excited to go back to work today. We’ve released Spilled! and announced Go Ape Ship! last year (<a href="https://sound.games/games.html">as you can see here</a>), so things have been moving fast.</p>

<p>I’m planning on sharing links of stuff I’ve enjoyed in the past week but I didn’t prepare them ahead of time and it’s already Monday. For this week, I just want to give a shoutout to <a href="https://www.azabani.com/2025/12/18/shoestring-web-engine-ci.html">this transcript of a talk</a> about the CI infrastructure for <a href="https://servo.org/">Servo</a>. I was a little thrown off by the format at first but I quickly got into it and couldn’t put it down. Truly fascinating stuff.</p>]]></content><author><name></name></author><category term="notes" /><summary type="html"><![CDATA[Last year I wrote 12 notes posts, which is better than the 2 posts I wrote in 2023 when I tried this trend. I’m hoping to do better this year, but we’ll see how it goes.]]></summary></entry><entry><title type="html">You can’t update your 3D printer’s firmware in LAN-only mode</title><link href="https://romain.codes/2026/01/04/you-can-t-update-your-3d-printer-s-firmware-in-lan-only-mode/" rel="alternate" type="text/html" title="You can’t update your 3D printer’s firmware in LAN-only mode" /><published>2026-01-04T01:23:00+00:00</published><updated>2026-01-04T01:23:00+00:00</updated><id>https://romain.codes/2026/01/04/you-can-t-update-your-3d-printer-s-firmware-in-lan-only-mode</id><content type="html" xml:base="https://romain.codes/2026/01/04/you-can-t-update-your-3d-printer-s-firmware-in-lan-only-mode/"><![CDATA[<p>I bought a 3D printer 3 years ago and it looks like its firmware has been out of date for almost as long now.</p>

<p>My printer is a <a href="https://ca.store.bambulab.com/products/p1s">Bambulab P1S</a> that I really like. As my friend <a href="/2024/01/14/2023-in-review/">told me before buying</a>, it’s pretty much like if Apple had made a 3D printer. I don’t know how much this statement holds true these days, considering the drop in software quality, but I must admit that I’ve had very little trouble with my printer ever since I plugged it in.</p>

<p>I don’t remember when I tried to update <a href="https://bambulab.com/en/download/studio">Bambu Studio</a> (the app you use to talk to the printer) to version 2.x but I remember running into an issue when I tried to start a print, something about a nozzle issue. I didn’t really want to look into the issue immediately, so I’d just reverted back to the latest 1.x version and moved on with my life. Based on the release notes, I suspect that was around February 2025. Since then, I’ve kept printing with version 1 of the software, ignoring the occasional warning telling me that the 3D model I’d downloaded would work better with the latest version of the Bambu Studio app.</p>

<p><img src="/assets/2026/3dprinting-firmware-update-octoclips.jpeg" alt="Tiny clips of various colours shaped like octopi used to seal bags of food" /></p>

<p>Today, as my lovely partner asked me to print some cute <a href="https://makerworld.com/en/models/35697-the-original-octopus-chip-clip?from=search#profileId-33386">Octopus Chip Clips</a>, I decided to download the latest version of Bambu Studio again. As expected, I ran into an issue about a nozzle.</p>

<blockquote>
  <p>🚨 Invalid nozzle information, please refresh or manually set nozzle information</p>
</blockquote>

<p>I felt many emotions at once: <strong>confusion</strong> (What do you mean the information about the nozzle is invalid?), <strong>resentment</strong> (It’s not my fault! I haven’t changed anything!), and finally <strong>anger</strong> (it’s your hardware! I thought you were the Apple of 3D printers?!). Once I’d stopped crying and screaming under the rain (of which we’re currently getting plenty #vancouver), I decided to start looking around for solutions.</p>

<p>After a little while, I decided to make sure that the printer was running the latest version of the firmware. It would be a little emnbarassing for me to be running outdated somewhere, as someone who keeps writing <a href="/2025/10/12/updating-dependencies-in-a-gradle-project/">unoriginal</a> <a href="/2022/04/28/keeping-my-dependencies-up-to-date/">blogposts</a> about <a href="/2024/02/19/keeping-on-keeping-my-dependencies-up-to-date/">keeping your dependencies up to date</a>. I selected the “Device” section of Bambu Studio, clicked on “Update” to see that my printer was running the latest version of the firmware, <code class="language-plaintext highlighter-rouge">1.04.something</code>. Cool.</p>

<p>Still somewhat unsatisfied by this answer, I went looking for a list of the firmware’s versions to double check where it said the latest version was <code class="language-plaintext highlighter-rouge">01.09.00.00</code> and that version <code class="language-plaintext highlighter-rouge">01.04.02.00</code> was released… in October 2023. My printer has been running a version of the firmware released 2 years ago. Embarassing. Fortunately, I took a quick peek at the release notes and didn’t see any release made to prevent the printer from catching on fire.</p>

<p>The question is, why did Bambu Studio think the printer was running the latest version of the firmware if it wasn’t? The answer is pretty frustating. You see, there are two ways you can run your printer. You can either connect to Bambu Labs’ cloud services or you can run your printer in LAN only mode. While I wasn’t super worried about seeing my printer going rogue after some kind of targeted attack against Bambulabs’ cloud services, I didn’t see the value of connecting to their cloud services either.</p>

<p>Bambu Studio is open source, so it was easy to locate this <a href="https://github.com/bambulab/BambuStudio/issues/4530">open issue</a>. The short version is that if you’re running in LAN only mode, Bambu Studio will always think you’re running the latest version of the firmware. At least, that was the case until September 2025 but to be able to get local only updates, it looks like you need to connect your printer to the cloud at least once.</p>

<p><img src="/assets/2026/3dprinting-firmware-update-chips.jpg" alt="Two bags of chips sealed close with small yellow octopus-shaped chips" /></p>

<p>I did that and the printer immediately asked me if I wanted to update to the latest version of the firmware. I did the update, the nozzle issue went away like magic and I was able to print some very cute chip clips.</p>]]></content><author><name></name></author><category term="craft" /><summary type="html"><![CDATA[I bought a 3D printer 3 years ago and it looks like its firmware has been out of date for almost as long now.]]></summary></entry><entry><title type="html">Ain’t Nobody Got kotlin.time for That</title><link href="https://romain.codes/2025/12/10/ain-t-nobody-got-kotlin-time-for-that/" rel="alternate" type="text/html" title="Ain’t Nobody Got kotlin.time for That" /><published>2025-12-10T05:40:00+00:00</published><updated>2025-12-10T05:40:00+00:00</updated><id>https://romain.codes/2025/12/10/ain-t-nobody-got-kotlin-time-for-that</id><content type="html" xml:base="https://romain.codes/2025/12/10/ain-t-nobody-got-kotlin-time-for-that/"><![CDATA[<p>I remember this famous scene in the TV show <a href="https://en.wikipedia.org/wiki/Malcolm_in_the_Middle">Malcolm in the middle</a> where the father realizes that a lightbulb died and decides to change it, this is pretty much what happened to me as I decided to update some of our dependencies.</p>

<p>These days, I use Kotlin for server side development. I already covered <a href="/2024/08/24/using-kotlin-to-build-comics-outmash/">here</a> why I like it and not much has changed since. To go a little deeper into our technology stack, we use <a href="https://www.postgresql.org/">Postgresql</a> (with the <a href="https://www.jetbrains.com/exposed/">exposed</a> framework) and describe API specifications with OpenAPI (using <a href="https://github.com/fabrikt-io/fabrikt">Fabrikt</a> for code generation). I’m mentioning those because I had to update them all at once in a massive pull-request impacting around 150 files.</p>

<p>Earlier this week, I ran <a href="/2025/10/13/updating-dependencies-in-a-gradle-project/">my script</a> that checks for outdated dependencies in a gradle project and realized there was a bunch of libraries I wanted to update, including the kotlin plugin itself, <a href="https://github.com/Kotlin/kotlinx-datetime">kotlinx-datetime</a> and exposed.</p>

<p>Updating the version of kotlinx-datetime introduced deprecation warnings: there is no longer need for their Instant and Clock types, since those are now available in Kotlin’s standard library (since version 2.1). Turns out, representing time is a common need, so it made sense to move it there. Unfortunately, updating kotlinx-datetime broke Exposed’s date and time types.</p>

<p>As a result, I switched to a different branch and updated Exposed to <code class="language-plaintext highlighter-rouge">1.0.0-RC-4</code>, which was… a lot of work, but pretty straightforward package changes (<code class="language-plaintext highlighter-rouge">org.jetbrains.exposed.sql.Table</code> is now <code class="language-plaintext highlighter-rouge">org.jetbrains.exposed.v1.core.Table</code>, etc). It worked until I realized that Exposed depends on… a more recent version of kotlinx-datetime.</p>

<p>After a quick search it looked like I could have used a compatibility version of datetime, but it seemed easier to go for it, merge both branches together and address the errors that popped up.</p>

<p>Lastly, the last task was to upgrade Fabrikt, because the generated code expected to use <code class="language-plaintext highlighter-rouge">kotlinx.datetime.Instant</code> and not the never <code class="language-plaintext highlighter-rouge">kotlin.time.Instant</code>. After bumping to the latest version and tweaking the code generation command to set the <code class="language-plaintext highlighter-rouge">--instant-library</code> option to <code class="language-plaintext highlighter-rouge">KOTLIN_TIME_INSTANT</code>, we were back in business.</p>

<p>A pull request that touches around 150 files is way about my comfort threshold, but an extensive suite of tests that covers all the sensitives parts made it a lot more tolerable.</p>]]></content><author><name></name></author><category term="programming" /><summary type="html"><![CDATA[I remember this famous scene in the TV show Malcolm in the middle where the father realizes that a lightbulb died and decides to change it, this is pretty much what happened to me as I decided to update some of our dependencies.]]></summary></entry><entry><title type="html">Unity games’ player preferences on macOS</title><link href="https://romain.codes/2025/12/06/unity-playerprefs-macos/" rel="alternate" type="text/html" title="Unity games’ player preferences on macOS" /><published>2025-12-06T06:16:00+00:00</published><updated>2025-12-06T06:16:00+00:00</updated><id>https://romain.codes/2025/12/06/unity-playerprefs-macos</id><content type="html" xml:base="https://romain.codes/2025/12/06/unity-playerprefs-macos/"><![CDATA[<p>I’m not a game developer, but after more than a year doing shenanigans at <a href="https://sound.games/">Sound Games</a>, some of my colleagues’ knowledge has somehow transcended the limits of the physical world and travelled toward my office in Vancouver, where I’m now brave enough to spend more time in the Unity editor. I’ve had to learn how to reset the state of a game without making changes to said game and it took me way too long to remember how some of this works from my days building iOS or macOS apps.</p>

<p>TL;DR: Even if <a href="https://docs.unity3d.com/ScriptReference/PlayerPrefs.html">the documentation</a> states that PlayerPrefs stores player preferences in a plist file on macOS, this is partially true since it uses the defaults system. If you’re trying to make changes to the state of your game, use <code class="language-plaintext highlighter-rouge">defaults write com.company.game key value</code> from your terminal.</p>

<p>For context, we’re working on a game where we store state (last time you did a specific action, the preferred volume for the music, inverting the Y axis on your gamepad like some kind of monster…). Right now we don’t have a “reset to defaults” button which means I couldn’t re-test actions that happen the first time you launch the game, for example. It’s in the work, but apparently even in the world of video games people try to assign priorities to different tasks and prefer working on the more pressing ones first. Weird.</p>

<p>As a result, I started peeking into the source code of the game, harassed my colleagues on the other side of the Atlantic to figure out what we were using and learned about <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> which, as the name suggests, stores player’s preferences. Further, as the documentation says, the actual preferences live in a flat file in <code class="language-plaintext highlighter-rouge">~/Library/Preferences/ExampleBundleIdentifier.plist</code> where <code class="language-plaintext highlighter-rouge">ExampleBundleIdentifier</code> is your bundle identifier (duh) such as <code class="language-plaintext highlighter-rouge">com.mycompany.mysupergame</code>. This was enough to get me going. I grabbed my old and weird friend <a href="https://en.wikipedia.org/wiki/Property_list#Tooling">PlistBuddy</a> that allows you to decode and execute command against a property list file: print content, edit a key, delete it… I should probably have moved to the more modern version, <code class="language-plaintext highlighter-rouge">plutil</code>, but that is not here nor there. Also, I forgot it existed until I read the wikipedia page linked earlier.</p>

<p>I ran some <code class="language-plaintext highlighter-rouge">PlistBuddy -c "Delete :my-state-key" codes.romain.whatever.plist</code> commands, relaunched the game and… nothing changed. Even worse, the changes I’d made to the file had somehow never happened. After some more digging, asking around and trying to search online for an answer, I brought up the issue with my colleagues and someone mentioned iCloud potentially being the culprit. That’s when it clicked, like a movie where the hero (in this case, me) has a flashback and remembers something from their childhood (in this case, the last time I worked on a macOS app) that will save the day: user defaults.</p>

<p>If you’re not familiar, when making apps for the Apple platforms, there is this <a href="https://developer.apple.com/documentation/foundation/userdefaults">simple key value database</a> you can use to store informations within your app. I won’t go into details, but you can access this database on macOS using the <code class="language-plaintext highlighter-rouge">defaults</code> command line tool. On a hunch, I typed <code class="language-plaintext highlighter-rouge">defaults read com.mycompany.mysupergame</code> and saw the informations I was expecting to tweak, and more. I tried to update some value using <code class="language-plaintext highlighter-rouge">defaults write ...</code>, relaunched my game and like a Christmas miracle, the changes were showing up in the game.</p>

<p>What’s the moral of the story? I can think of a couple. First, if you have to use <code class="language-plaintext highlighter-rouge">fs_events</code> to watch the changes happening to a file because you’re convinced that a goblin living somewhere in the operating system is modifying that file in secret, you probably need to take a break because you’ve gone too deep. Second, always remember to ask your colleagues, because someone will suggest something that will put you on the right tracks. Lastly, because you’ve only been through the first part of a <a href="https://gamedev.tv/courses/unity6-complete-3d">27 hours long unity tutorial</a> doesn’t mean you can’t make meaningful contributions to the world of video games. Believe in your dreams.</p>]]></content><author><name></name></author><category term="programming" /><summary type="html"><![CDATA[I’m not a game developer, but after more than a year doing shenanigans at Sound Games, some of my colleagues’ knowledge has somehow transcended the limits of the physical world and travelled toward my office in Vancouver, where I’m now brave enough to spend more time in the Unity editor. I’ve had to learn how to reset the state of a game without making changes to said game and it took me way too long to remember how some of this works from my days building iOS or macOS apps.]]></summary></entry><entry><title type="html">Updating dependencies in a gradle project</title><link href="https://romain.codes/2025/10/13/updating-dependencies-in-a-gradle-project/" rel="alternate" type="text/html" title="Updating dependencies in a gradle project" /><published>2025-10-13T05:05:00+00:00</published><updated>2025-10-13T05:05:00+00:00</updated><id>https://romain.codes/2025/10/13/updating-dependencies-in-a-gradle-project</id><content type="html" xml:base="https://romain.codes/2025/10/13/updating-dependencies-in-a-gradle-project/"><![CDATA[<p>If there is one hill I’m willing to get mildly injured on, it’s that you should keep your dependencies up to date.</p>

<p>Keeping my dependencies up to date is something I <a href="https://romain.codes/2022/04/28/keeping-my-dependencies-up-to-date/">keep</a> on writing <a href="https://romain.codes/2024/02/20/keeping-on-keeping-my-dependencies-up-to-date/">about</a>, most recently to introduce a <a href="https://romain.codes/2024/07/13/agamotto-is-available-on-github/">command line tool</a> I wrote to list out of date dependencies in Swift projects. Kotlin has replaced Swift for me these days, but the problem remained, especially as we’re building cool stuff at <a href="https://sound.games/">Sound Games</a> and I get to make the servers go brrrrr<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>.</p>

<p>Dependabot is one of the most popular ways to keep your dependencies up to date. It started as a standalone product and is <a href="https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide">now part of GitHub’s offering</a>. As you may know, I’ve decided to <a href="https://romain.codes/2025/09/09/moving-away-from-github/">stop using GitHub</a>, but that’s not (only) why I’m not using Dependabot on other projects. I think that updating dependencies should be a conscious decision. Just because you get a pull-request created automatically where all your tests are passing does not mean that the update is safe. It’s actually pretty easy to bite yourself in the butt by merging a green PR, going to bed and waking up to angry message from the 12 daily users of your side project about comic books<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>.</p>

<p>Now for the perfect solution: I don’t really have one. Recently at work, I created a super quick and dirty script that retrieves all the top-level dependencies we use in the project, retrieve the most recent versions available on the maven central repository and print a sorted list to compare both. I figured I would write about this.</p>

<h2 id="listing-dependencies">Listing dependencies</h2>

<p>You can list your dependencies in a Gradle project using the <code class="language-plaintext highlighter-rouge">gradle</code> command line tool to run the <code class="language-plaintext highlighter-rouge">:dependencies</code> subtask. It will print a tree with all the dependencies used for a specific configuration. Something that roughly looks like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>|    +--- io.ktor:ktor-utils-jvm:3.2.3 (c)
|    +--- io.ktor:ktor-serialization-kotlinx-jvm:3.2.3 (c)
|    +--- io.ktor:ktor-call-id-jvm:3.2.3 (c)
|    +--- io.ktor:ktor-network-jvm:3.2.3 (c)
|    \--- io.ktor:ktor-io-jvm:3.2.3 (c)
+--- io.ktor:ktor-client-core:3.2.3
|    \--- io.ktor:ktor-client-core-jvm:3.2.3
|         +--- org.slf4j:slf4j-api:2.0.17
|         +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
|         |    \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
|         |         +--- org.jetbrains:annotations:23.0.0
|         |         +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
|         |         |    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2 (c)
|         |         |    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (c)
|         |         |    \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.2 (c)
|         |         \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -&gt; 2.1.21 (*)
</code></pre></div></div>

<p>My original approach was to run this command and parse its output to retrieve our dependencies, but I didn’t like it. No real reasons to justify this except that it didn’t feel right. I then quickly realized that all the dependencies are in a <a href="https://docs.gradle.org/current/userguide/version_catalogs.html">version catalog</a>. If you’re not familiar, the version catalog is a file in the TOML format that looks like this:</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[</span><span class="n">versions</span><span class="k">]</span>
<span class="n">ktor-version</span> <span class="o">=</span><span class="w"> </span><span class="s">"3.3.0"</span>

<span class="k">[</span><span class="n">libraries</span><span class="k">]</span>
<span class="n">ktor-server-core</span> <span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">module</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"io.ktor:ktor-server-core-jvm"</span><span class="p">,</span><span class="w"> </span><span class="n">version</span><span class="p">.</span><span class="n">ref</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"ktor-version"</span><span class="w"> </span><span class="p">}</span>  
<span class="n">ktor-server-core-html-builder</span> <span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">module</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"io.ktor:ktor-server-html-builder"</span><span class="p">,</span><span class="w"> </span><span class="n">version</span><span class="p">.</span><span class="n">ref</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"ktor-version"</span><span class="w"> </span><span class="p">}</span>
</code></pre></div></div>

<p>I don’t have anything that can parse TOML<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> so instead I went for a naive approach where I read the file line by line, remove the comments and use a regular expression to retrieve which module we’re using and at which version. How confident am I in this approach? A solid 2 out of 10: what is easy to break is probably just as easy to fix, so that’s good enough right now.</p>

<h2 id="getting-all-the-versions-available-for-a-module">Getting all the versions available for a module</h2>

<p>The next step was to retrieve each modules’ available versions so we can compare with the version we’re using. After a quick search, I found out that there is <a href="https://central.sonatype.org/search/rest-api-guide/">a search API</a> available for the maven central repository, so I started with that.</p>

<figure><img src="/assets/2025/dependencies-rapidapi.png" alt="Sending a request to the API using the RapidAPI app " /><figcaption>Sending a request to the API using the RapidAPI app </figcaption></figure>

<p>As the screenshot above shows using RapidAPI<sup id="fnref:4"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup>, the API accepts a query (see 1) with a group (<code class="language-plaintext highlighter-rouge">g</code>), and an artifact name (<code class="language-plaintext highlighter-rouge">a</code>). Please don’t ask me what the <code class="language-plaintext highlighter-rouge">core</code> argument means, for I don’t remember. Using the filter’s feature (2) that accepts <a href="/2024/01/30/my-command-line-toolbet/#jq">a jq syntax</a>, you can see what we retrieve a list of versions (3). Good enough!</p>

<p>Unfortunately, I’ve found this API to be slow and unreliable, as most of my requests failed with timeouts. At this point it’s not clear to me if this search API is still actively maintained or not. I’ll try to find out because my alternative solution was a little, well, alternative.</p>

<figure><img src="/assets/2025/dependencies-browser-listing.png" alt="All the versions available for a specific library " /><figcaption>All the versions available for a specific library </figcaption></figure>

<p>Instead of using the search API, I’m grabbing the content of the page that lists all the versions available on a repo<sup id="fnref:6"><a href="#fn:6" class="footnote" rel="footnote" role="doc-noteref">5</a></sup> (in the screenshot above, those are the versions for the <code class="language-plaintext highlighter-rouge">sql-gauss-db</code> artifact in the <code class="language-plaintext highlighter-rouge">com.easy-query</code> group) and parse the HTML. That’s a little fragile, but it does the job for now. Plus, the chances that the format of the URLs on that page change in the foreseeable future are pretty low<sup id="fnref:5"><a href="#fn:5" class="footnote" rel="footnote" role="doc-noteref">6</a></sup>.</p>

<h2 id="comparing-versions">Comparing versions</h2>

<p>Finally, I have the versions we use and the versions that exist, so I originally started by sorting the list alphabetically and grabbed the top version as the latest. I knew this was a bad idea that I would have to fix eventually, but I didn’t expect I would have to address it immediately when my script suggested I upgrade a library from <code class="language-plaintext highlighter-rouge">1.12.x</code> to <code class="language-plaintext highlighter-rouge">1.2.x.</code>. As a result, I resigned into writing a proper semver parser (that doesn’t account for pre-releases versions yet) and addressed that issue.</p>

<p>The result is a simple script that shows the version used by a library and the latest version available upstream, in this simple format.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>com.cjbooms:fabrikt                                : 24.0.0 -&gt; 24.1.3
org.jetbrains.kotlinx:kotlinx-serialization-json   : 1.8.0 -&gt; 1.9.0
org.jetbrains.kotlinx:kotlinx-datetime             : 0.6.1 -&gt; 0.7.1
org.testcontainers:testcontainers                  : 1.19.8 -&gt; 1.21.3
org.testcontainers:postgresql                      : 1.19.8 -&gt; 1.21.3
...
</code></pre></div></div>

<p>Of course, there is already a bunch of things I want to improve, but this feels like a straight path toward re-implementing a bad version of dependabot, so I just merged my pull-request, selected a few dependencies to update first and moved on with my day, giving time for those improvement ideas to settle. I guess I’ll get back to it when all my dependencies are up to date?</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>That’s my official job description, if you were wondering. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>This is of course a <a href="https://romain.codes/2025/03/29/screw-it-i-m-writing-a-web-testing-framework/">random example</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>I also think that the irony of adding a new dependency solely to retrieve the dependencies I use would have been too much to bear <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:4">
      <p>RIP Paw, which was a much better/cuter name, don’t @ me on this. <a href="#fnref:4" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:6">
      <p>After checking their <a href="https://repo1.maven.org/robots.txt">robots.txt</a>, which explicitly disallows uses of their data for training of AI models, but allows it for searching purposes. <a href="#fnref:6" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:5">
      <p>Famous last words. <a href="#fnref:5" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="programming" /><summary type="html"><![CDATA[If there is one hill I’m willing to get mildly injured on, it’s that you should keep your dependencies up to date.]]></summary></entry><entry><title type="html">2025 - Week 38: this website runs on my Oura ring</title><link href="https://romain.codes/2025/09/21/2025-week-38/" rel="alternate" type="text/html" title="2025 - Week 38: this website runs on my Oura ring" /><published>2025-09-21T22:00:00+00:00</published><updated>2025-09-21T22:00:00+00:00</updated><id>https://romain.codes/2025/09/21/2025-week-38</id><content type="html" xml:base="https://romain.codes/2025/09/21/2025-week-38/"><![CDATA[<p>Yesterday I ran into this news about a hacker who reused a <a href="https://bogdanthegeek.github.io/blog/projects/vapeserver/">disposable vape to host a website</a>, pretty impressive stuff. I ordered an Oura ring 18 months ago, but haven’t really used it (or charged it, for what it’s worth) in months now. It made me think… could I build and host this website on my Oura ring as well? Probably not. Also, this isn’t even what this post is about. Kind of embarrassing for you if you believed that.</p>

<p>We have family visiting, so we decided to rent a place on the <a href="https://www.sunshinecoastcanada.com/">Sunshine Coast</a>. I have made myself a nice spot to work from and I’ve been taking the occasional break swimming, kayaking or standup paddleboarding<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>, adjusting my time to enjoy the weather while getting things done. I also stopped by the local public library while the rest of the family is wandering around and it’s always a good experience. Once again, we really need to protect public libraries at all cost.</p>

<figure><img src="/assets/2025/weeknotes-2025-38-library.jpeg" alt="The entrance of the public library, in Sechelt " /><figcaption>The entrance of the public library, in Sechelt </figcaption></figure>

<p>Since <a href="https://podcasts.apple.com/us/podcast/floodcast/id1019768302">my favourite podcast</a> has ended, I started listening to the first episodes again, like a ghost stuck in a loop unable to move on… until I discovered the <a href="https://www.bufferingcast.com/">Buffering the Vampire Slayer podcast</a>. Despite everything <a href="https://en.wikipedia.org/wiki/Joss_Whedon#Accusations_of_workplace_harassment">we now know about Joss Whedon</a>, the Buffy TV show was a huge part of me growing up. I watched it religiously when it was aired in France<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>, then on repeat when we got the DVD Box Set. This podcast really hits the nostalgia part of my brain, the hosts are funny… I highly recommend it. I’ve also started to re-watch all the episodes, because why not.</p>

<p>I finally started reading <a href="https://thecon.ai/">The AI Con</a> by Emily M. Bender and Alex Hanna and it’s a very good read so far. I’m also reading <a href="https://en.wikipedia.org/wiki/Legends_%26_Lattes">Legends and Latte</a>, which is a lot lighter so overall it’s a healthy balance. Everything is terrible but we’ll always have giants orcs and coffee shops.</p>

<p>Finally, I put a fresh coat of paint on my blog. When I was trying to make some changes to include a link to my <a href="/now">/now</a> page, I realized that the stylesheet that came with the theme I setup a few years ago and tweaked over the years was out of control. So I did what everybody with a few hours to kill would do, I removed it altogether and re-did the integration myself. It’s not perfect, I still have some minor fixes to do here and there, but I’m glad I was able to do it. I’ll probably write a dedicated blog post about it soon<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup>.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Although a case could be made that not a lot of standing is being done. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>Often in random orders, which drove me nuts. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>Famous last words. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="notes" /><summary type="html"><![CDATA[Yesterday I ran into this news about a hacker who reused a disposable vape to host a website, pretty impressive stuff. I ordered an Oura ring 18 months ago, but haven’t really used it (or charged it, for what it’s worth) in months now. It made me think… could I build and host this website on my Oura ring as well? Probably not. Also, this isn’t even what this post is about. Kind of embarrassing for you if you believed that.]]></summary></entry><entry><title type="html">I’m moving away from GitHub</title><link href="https://romain.codes/2025/09/09/moving-away-from-github/" rel="alternate" type="text/html" title="I’m moving away from GitHub" /><published>2025-09-09T03:32:00+00:00</published><updated>2025-09-09T03:32:00+00:00</updated><id>https://romain.codes/2025/09/09/moving-away-from-github</id><content type="html" xml:base="https://romain.codes/2025/09/09/moving-away-from-github/"><![CDATA[<p>Well, kind of. I guess I’m leaving GitHub like I left Facebook: I don’t plan on using it anymore, but since that’s where the people of our residence tell us about their kids’ lemonade stands, I’m keeping my account to interact with the outside world when needed.</p>

<p>GitHub will always have a special place in my heart, it hurts to do the maths but I think I started using it in… 2008? I’ve been using (and supporting!) them ever since: I used the <a href="https://github.blog/changelog/2021-04-19-deprecation-notice-github-jobs-site/">now defunct Job API</a> as an example in <a href="https://romain.codes/2014/11/07/i-wrote-a-book/">my book</a>, I contributed to libraries using their API, beta tested products like the iOS app or GitHub Actions, and I even tried to <a href="https://romain.codes/2024/11/19/meeting-with-github/">provide helpful feedback on Copilot</a>, despite the fact that… well, you know.</p>

<p>That being said, this has been a long time coming for various reason, but these days it feels like your ethics is the only thing you can control, so I’m chosing to follow mine and leave. Last week, with the TV in the background, I gradually started removing stuff from there and it wasn’t as painful or annoying as I thought it would be.</p>

<p>First, I used <code class="language-plaintext highlighter-rouge">gh</code> (<a href="https://romain.codes/2024/01/30/my-command-line-toolbet/#gh">a tool I really like</a>) to list all the forks I owned. The first half were a bunch libraries from my buddybuild days that I used to fork and try to onboard, while the other half were mostly Apple repositories that I forked once I was (finally!) allowed to do some open-source work. There was nothing really interesting nor surprising, but I’m pretty sure I’d done a pass on recent forks already.</p>

<p>The next thing I did was just going through all the repos I created. I went through a lot of various emotions: confusion for the empty repositories with a cryptic codename I could no longer explain, frustration for private side projects I worked on but couldn’t publicly release because of Apple’s open-source policy, and nostalgia for projects I’d simply abandoned. From there, I made decisions:</p>
<ul>
  <li>the stuff I cared about but that provided little value, I simply downloaded an archive, deleted the repository, and added to my will<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></li>
  <li>the aforementioned stuff with cryptic names and often very little code, I simply removed</li>
  <li>the rest I pushed to <a href="https://codeberg.org/palleas">my fresh Codeberg</a> account, marked as archived on Codeberg and deleted on GitHub. It’s usually stuff that I mentioned in blog posts or side project I’m actually working on.</li>
</ul>

<p>Codeberg has been fun to use so far, it feels like GitHub in the early days with a snappy UI and no constant mentions of an AI offering I simply don’t care about. I like the fact that it’s backed by a non profit based in Europe<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> and that it’s based on an open-source tool, <a href="https://forgejo.org/">Forgejo</a>. I briefly considered self hosting my own instance for fun, but I know it would only be fun for a short while. I reserve the right to reconsider after I’m done packing food rations and building my nuclear bunker. In the meantime, I put my money where my mouth is: I downgraded my GitHub account (that I was paying for extra CI minutes) to free and gave that money <a href="https://donate.codeberg.org/">to Codeberg</a>.</p>

<p>I still have a few private projects to migrate, such as <a href="https://romain.codes/categories/#category-comics-outmash">Comics Outmash</a> and this blog (which uses <a href="https://romain.codes/2022/04/18/on-migrating-my-blog-to-gatsby/">Netlify</a>). It’s only been delayed because I still need to figure out the CI situation. This is the kind of stuff I might consider self-hosting because access to <a href="https://docs.codeberg.org/ci/#using-codeberg's-instance-of-woodpecker-ci">Codeberg’s CI instance</a> needs to be reviewed first, which I totally understand.</p>

<p>I don’t expect my decision to impact GitHub, but at this point it feels worse to put my ethics aside and embrace the <a href="https://en.wikipedia.org/wiki/Enshittification">enshittification</a>, so I’m taking the leap. I guess we’ll see in 6 months if and how my life was transformed by this change?</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>not really. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>a.k.a. the technical backwater that makes that guy from that website all angry <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="random" /><summary type="html"><![CDATA[Well, kind of. I guess I’m leaving GitHub like I left Facebook: I don’t plan on using it anymore, but since that’s where the people of our residence tell us about their kids’ lemonade stands, I’m keeping my account to interact with the outside world when needed.]]></summary></entry><entry><title type="html">Now (September 2025)</title><link href="https://romain.codes/2025/09/09/now/" rel="alternate" type="text/html" title="Now (September 2025)" /><published>2025-09-09T03:32:00+00:00</published><updated>2025-09-09T03:32:00+00:00</updated><id>https://romain.codes/2025/09/09/now</id><content type="html" xml:base="https://romain.codes/2025/09/09/now/"><![CDATA[<p>This is my first attempt at a <a href="https://slashpages.net/#now">/now</a> page, so I will keep it short and promise to do better next time.</p>

<p>I’m currently working (and have been for the past year or so) at <a href="https://sound.games/">Sound Games</a> where we do… game stuff. I can’t really share much at this point, except that I’m in charge of making the backend go brrr. I never really saw myself joining a video games startup but after 7 years at Apple, I needed something different. I have already learned a lot of new stuff and the people are awesome.</p>

<p>Still recovering from a pretty shitty summer, but it’s hard to truly focus on that with family visiting. I’m expecting a lot of running in the upcoming weeks because I truly miss it and it’s been hard to commit to it when you’re trying to entertain, work and the weather is super hot. I do miss the people from my running club too, which is surprising since it involves waking up at 6:30 every Saturdays. We’re currently staying at a friend’s cottage on the coast, so at least I’m able to swim (albeit briefly because it’s f- cold) and go on short kayak trips.</p>

<p>I think this will be a good place to add what I’m playing, listening, watching and so on.</p>]]></content><author><name></name></author><category term="now" /><summary type="html"><![CDATA[This is my first attempt at a /now page, so I will keep it short and promise to do better next time.]]></summary></entry></feed>