<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Die Dubiose Dev</title>
    <subtitle>Random thoughts, projects, mini projects, and ideas.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://dubiose.dev/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://dubiose.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-03T00:00:00+00:00</updated>
    <id>https://dubiose.dev/atom.xml</id>
    <entry xml:lang="en">
        <title>Tent Pole Bungee End Caps</title>
        <published>2026-09-03T00:00:00+00:00</published>
        <updated>2026-09-03T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/tent-pole-bungee-cap/"/>
        <id>https://dubiose.dev/mini-projects/tent-pole-bungee-cap/</id>
        
        <summary type="html">&lt;p&gt;These replacement end caps were designed to fit common carbon-fiber and fiberglass tent poles. They allow the internal bungee cord to be reattached after replacing a damaged pole segment. The cord passes through the opening in the cap and is secured at the end of the final pole section.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Easy &amp; Delicious Camping Breakfast Burritos for the Lazy-ish</title>
        <published>2026-08-14T00:00:00+00:00</published>
        <updated>2026-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitlin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/blog/easy-camp-cooking/"/>
        <id>https://dubiose.dev/blog/easy-camp-cooking/</id>
        
        <content type="html" xml:base="https://dubiose.dev/blog/easy-camp-cooking/">&lt;figure&gt;
  &lt;img src=&quot;/img/blog/easy_camp_cooking/holding_burrito.avif&quot; alt=&quot;A thin breakfast burrito is held in front of a clean pan. Behind is a foil wrapped burrito.&quot;&gt;
  &lt;figcaption&gt;
    Two burritos photographed by &lt;a href=&quot;https://dubiose.dev/&quot;&gt;Caitlin Sar Campbell&lt;/a&gt; and licensed under &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/4.0/&quot;&gt;CC BY-SA 4.0&lt;/a&gt;. All photos in this specific blog post are licensed under &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/4.0/&quot;&gt;CC BY-SA 4.0&lt;/a&gt;
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I was recently made aware that I had been using some mildly novel camping cooking techniques. Due to the strength of the reactions to said mildly novel cooking technique, I felt obligated to document and share my approach. Thus this blog post.&lt;/p&gt;
&lt;h1 id=&quot;the-technique&quot;&gt;The Technique&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/easy_camp_cooking/sealed_up.avif&quot; alt=&quot;Sealed up Burritos&quot; /&gt;
The idea is that before you go camping you make your burritos, wrap them in aluminum foil, then vacuum pack them.&lt;/p&gt;
&lt;p&gt;Because they are vacuum packed they take a bit less space, but more importantly they can be hygienically and conveniently placed in a cooler full of ice without any other special precautions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/easy_camp_cooking/3_in_a_pan.avif&quot; alt=&quot;3 Burritos Warming up in a Pan&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Because they are wrapped in aluminum foil they can be warmed up in a pan without making the pan dirty at all. When you are done cooking and the pan is cooled, the pan can be stored away in a bag, completely clean and labor free.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/easy_camp_cooking/char.avif&quot; alt=&quot;A burrito with a dark char on its tortilla&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can even get a nice char if the burritos are relatively flat. In the above case I let it go too long.&lt;/p&gt;
&lt;p&gt;The whole technique produces really filling, satisfying, and pleasant breakfasts with an absolute minimal effort. A total win for the music festival goer, or the hacker at the next hacker camp grounds.&lt;/p&gt;
&lt;h1 id=&quot;sample-recipe-to-use&quot;&gt;Sample Recipe to Use&lt;/h1&gt;
&lt;p&gt;While the technique can be used with any sort of aluminum-wrappable food in theory I do think egg and cheese breakfast burritos really shine here. This is my favorite recipe that makes 8 burritos which in my experience hold for 5 days in an ice filled cooler.&lt;/p&gt;
&lt;h2 id=&quot;ingredients&quot;&gt;Ingredients&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;8 flour tortillas&lt;/li&gt;
&lt;li&gt;18 eggs&lt;/li&gt;
&lt;li&gt;2 red bell peppers&lt;/li&gt;
&lt;li&gt;1 large onion&lt;/li&gt;
&lt;li&gt;gouda cheese to taste (for me ~200g)&lt;/li&gt;
&lt;li&gt;salt and pepper&lt;/li&gt;
&lt;li&gt;Monosodium glutamate (MSG)&lt;/li&gt;
&lt;li&gt;Butter&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cooking-steps&quot;&gt;Cooking Steps&lt;/h2&gt;
&lt;h3 id=&quot;the-filling&quot;&gt;The Filling&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Mince the bell peppers and onion into fine pieces. Finer is better here.&lt;/li&gt;
&lt;li&gt;Heavily butter a pan and sauté the onions and bell peppers till semi translucent and soft to the bite.&lt;/li&gt;
&lt;li&gt;While the onions and bellpeppers cook, crack and scramble all 18 eggs, mix in some salt, pepper, and MSG till the mix is slightly too salty.&lt;/li&gt;
&lt;li&gt;Add salt, pepper, and MSG to the onion / pepper mix till the mix is slightly too salty.&lt;/li&gt;
&lt;li&gt;Turn the heat down and add more butter to the onion / pepper mix if the pan is dry or pieces are sticking to the bottom of the pan.&lt;/li&gt;
&lt;li&gt;Quickly mix in the eggs while stirring continuously.&lt;/li&gt;
&lt;li&gt;As you mix the eggs should start to firm up. The goal is to not build up any burnt brown eggs and keeping everything mixed and moving evenly.&lt;/li&gt;
&lt;li&gt;As the eggs start to firm up, now is the time to add in the gouda cheese. Continue to stir continuously.&lt;/li&gt;
&lt;li&gt;As the eggs continue to firm, remove the pan from the heat while continuing to stir. Stir until you are confident no burnt brown egg crust will form.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;making-the-burritos&quot;&gt;Making the Burritos&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Use a spatula to divide the eggs into 4 even quadrants. Split each quadrant in half again such that you have 8 even sections of filling.&lt;/li&gt;
&lt;li&gt;Place a 1/8 section of filling into a burrito and tightly wrap it being sure to fold in both ends.&lt;/li&gt;
&lt;li&gt;Wrap the burrito in aluminum foil being sure to fold in both ends.&lt;/li&gt;
&lt;li&gt;Repeat for all 7 remaining burritos.&lt;/li&gt;
&lt;li&gt;Place all the wrapped burritos in the fridge to cool down. When cool proceed.&lt;/li&gt;
&lt;li&gt;Vacuum seal the burritos. I normally recommend 2 per person for breakfast so I like to do 2 burritos / vacuum bag.&lt;/li&gt;
&lt;li&gt;Toss them in the ice cooler or keep them in the fridge till you are ready to cook them.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;warming-the-burritos-up&quot;&gt;Warming the Burritos Up&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;In a clean dry stainless steel (or any type of) pan place as many burritos as will fit across the flat bottom of the pan.&lt;/li&gt;
&lt;li&gt;Place the pan on a burner and warm up the burritos.*&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Cook time can vary dramatically depending on the equipment and environment, but in my experience 2-5min per side depending on preference and the like should work. Once you flip the burrito the top side should remain hot to the touch even a minute later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&#39;s it. Super simple and easy if you put in the prep work.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Travel Protector for the Arctic Summair Plus</title>
        <published>2026-08-12T00:00:00+00:00</published>
        <updated>2026-08-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/arctic-summair-plus-protector/"/>
        <id>https://dubiose.dev/mini-projects/arctic-summair-plus-protector/</id>
        
        <summary type="html">&lt;p&gt;This simple protector addresses a small issue I have experienced while traveling with the &lt;a rel=&quot;external&quot; href=&quot;https://www.arctic.de/en/Summair-Plus/AEBRZ00024A&quot;&gt;Arctic Summair Plus Fan&lt;/a&gt;. The front &quot;grill&quot; can be pressed into the blades themselves causing interference. Undoing this requires effort and a sharp object to pop the &quot;grill&quot; back over the tabs. This simple protector stops this problem from happening.Designed in OpenSCAD.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Reflections on Running Bevy Workshops After GPN</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitlin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/blog/bevy-workshop-reflections/"/>
        <id>https://dubiose.dev/blog/bevy-workshop-reflections/</id>
        
        <content type="html" xml:base="https://dubiose.dev/blog/bevy-workshop-reflections/">&lt;figure&gt;
  &lt;img src=&quot;/img/blog/bevy_workshop_reflections/gpn24.avif&quot; alt=&quot;Photo of GPN24 attendees gathered in a large hall&quot;&gt;
  &lt;figcaption&gt;
    &lt;a href=&quot;https://entropia.de/GPN24&quot;&gt;GPN24&lt;/a&gt;, photographed by &lt;a href=&quot;https://dubiose.dev/&quot;&gt;Caitlin Sar Campbell&lt;/a&gt; and licensed under &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/4.0/&quot;&gt;CC BY-SA 4.0&lt;/a&gt;.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h1 id=&quot;setup&quot;&gt;Setup&lt;/h1&gt;
&lt;p&gt;Some time ago, I signed up to run a workshop at GPN24 in 2026.&lt;/p&gt;
&lt;p&gt;Before doing so, I had the opportunity to volunteer at the &lt;a rel=&quot;external&quot; href=&quot;https://bevy.org/&quot;&gt;Bevy&lt;/a&gt; workshop at &lt;a rel=&quot;external&quot; href=&quot;https://2025.rustweek.org/&quot;&gt;RustWeek 2025&lt;/a&gt;, run by Bevy co-maintainer &lt;a rel=&quot;external&quot; href=&quot;https://shaping.systems&quot;&gt;Alice I. Cecile&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Long story short, I very much liked the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/alice-i-cecile/bevy-match-3&quot;&gt;&lt;em&gt;&quot;here is a working game; improve it as much as your Rust and Bevy know-how allows&quot;&lt;/em&gt;&lt;/a&gt; approach the RustWeek workshop took, and &lt;a rel=&quot;external&quot; href=&quot;https://codeberg.org/mholiv/gpn-survivors&quot;&gt;created a workshop modeled on the same approach.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While the workshop eventually went swimmingly, thanks to &lt;a rel=&quot;external&quot; href=&quot;https://social.treehouse.systems/@schrottkatze&quot;&gt;Jade&lt;/a&gt;, who volunteered to help as we were randomly talking, there were some differences at GPN that I would take into consideration. These differences aren&#39;t necessarily GPN-specific as much as they are specific to non-industry-centric, hacker/maker-centric events.&lt;/p&gt;
&lt;p&gt;I wanted to document these here such that future Bevy workshop runners might be able to consider these points in advance.&lt;/p&gt;
&lt;h1 id=&quot;hardware-considerations&quot;&gt;Hardware Considerations&lt;/h1&gt;
&lt;h2 id=&quot;situation&quot;&gt;Situation&lt;/h2&gt;
&lt;p&gt;I think a major factor to consider when running Bevy workshops at GPN is that there is a lot more diversity in hardware compared to more industry-centric conferences.&lt;/p&gt;
&lt;p&gt;While at RustWeek, the majority of the hardware consisted of M3/M4 Macs, several of the latest &lt;a rel=&quot;external&quot; href=&quot;https://frame.work/&quot;&gt;Framework laptops&lt;/a&gt; featuring dedicated GPUs, or other quite powerful modern hardware.&lt;/p&gt;
&lt;p&gt;The story was very different at GPN. Here I saw people working on &lt;a rel=&quot;external&quot; href=&quot;https://store.steampowered.com/steamdeck&quot;&gt;Steam Decks&lt;/a&gt;, self-built &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Cyberdeck&quot;&gt;Cyberdecks&lt;/a&gt;, many older laptops, and a few newer machines. Notably, though not strictly related, there wasn&#39;t a single MacBook to be seen.&lt;/p&gt;
&lt;p&gt;Part of this might be a result of relative socioeconomic diversity at GPN compared to RustWeek, for sure, but a large part of this comes from hacker conference culture in general. Better to have self-expressive, open-source, self-made hardware than not.&lt;/p&gt;
&lt;p&gt;As a result, the initial compile times were horrendous, shining a worse light on Rust and Bevy than I would have liked. They ranged from 10 minutes to 40 minutes, depending on the machine, with an average around 20 minutes.&lt;/p&gt;
&lt;p&gt;People were literally SSH-ing into remote machines to compile it there, only to find that the debug builds were too big to scp back in a reasonable time.&lt;/p&gt;
&lt;p&gt;In the end, though, everyone did get the code running after the initial compile, including one participant who did the initial 40-minute compile twice after reading online that &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/cargo/commands/cargo-clean.html&quot;&gt;&lt;code&gt;cargo clean&lt;/code&gt;&lt;/a&gt; could address compile bugs.&lt;/p&gt;
&lt;p&gt;This being said, I think we can do better.&lt;/p&gt;
&lt;h2 id=&quot;possible-improvements&quot;&gt;Possible Improvements&lt;/h2&gt;
&lt;p&gt;I have two possible improvements that could help, one of which is uniquely enabled by hacker-centric events.&lt;/p&gt;
&lt;h3 id=&quot;1-bevy-feature-optimization&quot;&gt;1 - Bevy Feature Optimization&lt;/h3&gt;
&lt;p&gt;The workshop I ran just used the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/crate/bevy/latest/features&quot;&gt;default Bevy features&lt;/a&gt; without any manual selection at all. I had considered trimming it down, but opted against it because I didn&#39;t want users to be confused if they added Bevy ecosystem crates that suddenly didn&#39;t work due to said missing features.&lt;/p&gt;
&lt;p&gt;Looking back, I should have done this. I could have eliminated many of the image formats, audio formats, system-specific features like Android, custom cursor, zstd, and many more.&lt;/p&gt;
&lt;p&gt;Having a slimmed-down build, I suspect, would have made many people happier with the workshop. While this isn&#39;t technically an accessibility issue in the strictest sense, it feels that way when you see people not able to work because of older hardware while others get a 10-30 minute &quot;head start&quot;.&lt;/p&gt;
&lt;p&gt;At the very least, it feels privileged not to try to make things better. Something I can improve on.&lt;/p&gt;
&lt;h3 id=&quot;2-shared-compile-caches&quot;&gt;2 - Shared Compile Caches&lt;/h3&gt;
&lt;p&gt;This one is more unique. Hacker-centric conferences, in my experience at least in Europe, allow people to host and run servers on the conference network.&lt;/p&gt;
&lt;p&gt;This enables the potential for a locally hosted shared compile cache.&lt;/p&gt;
&lt;p&gt;Personally, I use &lt;a rel=&quot;external&quot; href=&quot;https://github.com/mozilla/sccache&quot;&gt;sccache&lt;/a&gt; in my own CI/CD pipeline and in my &lt;a rel=&quot;external&quot; href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; build environment for Steam targets with a locally hosted &lt;a rel=&quot;external&quot; href=&quot;https://docs.rustfs.com/features/s3-compatibility/&quot;&gt;S3-compatible endpoint&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think this could be used to speed up the workshop at conferences that allow for local hosting.&lt;/p&gt;
&lt;p&gt;The workshop participant could run this single command and start compiling right away, transferring binaries to their machine and bootstrapping themselves past the pain point.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AWS_ACCESS_KEY_ID=&amp;quot;ReadOnlyId&amp;quot; \
AWS_SECRET_ACCESS_KEY=&amp;quot;ReadOnlyKey&amp;quot; \
SCCACHE_BUCKET=&amp;quot;workshop&amp;quot; \
SCCACHE_ENDPOINT=&amp;quot;OnLanIpOrDns&amp;quot; \
RUSTC_WRAPPER=sccache \
cargo build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One could pre-populate it with &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/X86-64&quot;&gt;x86_64&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/AArch64&quot;&gt;aarch64&lt;/a&gt; artifacts, and people would be on their way MUCH faster.&lt;/p&gt;
&lt;h1 id=&quot;software-considerations&quot;&gt;Software Considerations&lt;/h1&gt;
&lt;h2 id=&quot;situation-1&quot;&gt;Situation&lt;/h2&gt;
&lt;p&gt;Like with hardware, GPN-like conferences provide a very unique and diverse software environment. No macOS, no Windows, but a ton of Linux. Not just your &lt;a rel=&quot;external&quot; href=&quot;https://ubuntu.com/&quot;&gt;Ubuntu&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://www.debian.org/&quot;&gt;Debian&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://fedoraproject.org/&quot;&gt;Fedora&lt;/a&gt; either. The workshop featured many &lt;a rel=&quot;external&quot; href=&quot;https://archlinux.org/&quot;&gt;Arch&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt; machines, several Fedora and Debian machines, a &lt;a rel=&quot;external&quot; href=&quot;https://voidlinux.org/&quot;&gt;Void Linux&lt;/a&gt; machine, and a &lt;a rel=&quot;external&quot; href=&quot;https://store.steampowered.com/steamos&quot;&gt;SteamOS&lt;/a&gt; machine.&lt;/p&gt;
&lt;p&gt;While it was really cool to see Bevy running on such a diverse series of ecosystems, this led to several issues with setting things up to compile properly.&lt;/p&gt;
&lt;p&gt;Particularly with NixOS and SteamOS.&lt;/p&gt;
&lt;h2 id=&quot;possible-improvements-1&quot;&gt;Possible Improvements&lt;/h2&gt;
&lt;p&gt;While this is a hard one to address outside of the existing &lt;a rel=&quot;external&quot; href=&quot;https://bevy.org/learn/quick-start/getting-started/setup/#installing-os-dependencies&quot;&gt;Bevy Linux-specific guides&lt;/a&gt;, I do think there is more to be done.&lt;/p&gt;
&lt;p&gt;At the very least, workshops should aim to provide a &lt;a rel=&quot;external&quot; href=&quot;https://nixos.wiki/wiki/Flakes&quot;&gt;NixOS flake&lt;/a&gt;. It was pretty simple, and Jade ended up distributing it to the NixOS participants.&lt;/p&gt;
&lt;p&gt;I do think there is a better general solution though that should at least be considered, this being &lt;a rel=&quot;external&quot; href=&quot;https://distrobox.it&quot;&gt;distrobox&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Distrobox is, in essence, scaffolding around &lt;a rel=&quot;external&quot; href=&quot;https://specs.opencontainers.org/image-spec/&quot;&gt;OCI images&lt;/a&gt; (think Docker or &lt;a rel=&quot;external&quot; href=&quot;https://podman.io/&quot;&gt;Podman&lt;/a&gt; images) that lets users do things inside of those OCI images. You could distribute the workshop as a small (6 to 60 MB) image hosted on &lt;a rel=&quot;external&quot; href=&quot;https://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry&quot;&gt;GHCR&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The workshop participant could get Bevy running in a pre-set-up environment with literally two commands.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;distrobox enter --name mybox --image ghcr.io/orgLocation/workshop:eventTag
cargo run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Distrobox &lt;a rel=&quot;external&quot; href=&quot;https://distrobox.it/compatibility/#host-distros&quot;&gt;works virtually anywhere, including VERY out-there environments like SteamOS or Void Linux&lt;/a&gt; &lt;a rel=&quot;external&quot; href=&quot;https://distrobox.it/#installation&quot;&gt;and is trivial to install.&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;location-considerations&quot;&gt;Location Considerations&lt;/h1&gt;
&lt;p&gt;This one was simpler but is still worth considering. If you are organizing a workshop, make sure there are plenty of power outlets. Compiling Rust is a battery killer, and participants can focus more on creativity if they don&#39;t have to worry about their 2023 laptop battery dying mid-recompile.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I hope future workshop runners can learn from my thoughts and experiences here. I know I will be changing things quite a bit to make things as nice as I can going forward.&lt;/p&gt;
&lt;p&gt;This all being said, no one is entitled to more free labor than a volunteer workshop runner is willing to give. No judgment should be made if people go a different route.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bevy glTF Considerations</title>
        <published>2026-03-07T00:00:00+00:00</published>
        <updated>2026-03-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitlin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/misc/bevy-gltf-considerations/"/>
        <id>https://dubiose.dev/misc/bevy-gltf-considerations/</id>
        
        <content type="html" xml:base="https://dubiose.dev/misc/bevy-gltf-considerations/">&lt;h1 id=&quot;the-situation-at-hand&quot;&gt;The situation at hand.&lt;/h1&gt;
&lt;p&gt;The amount of work that has been put into the Bevy glTF system is clear and evident. There is a ton of functionality that works really well and helps the engine shine.&lt;/p&gt;
&lt;p&gt;In working on my game and continuing to learn the Bevy codebase, there is an issue that I think, while not threatening now, will only continue to grow into a larger and larger problem as time goes on.&lt;/p&gt;
&lt;p&gt;This is the state of the &lt;code&gt;gltf-rs&lt;/code&gt; dependency that Bevy uses in the &lt;code&gt;bevy-gltf&lt;/code&gt; crate.&lt;/p&gt;
&lt;p&gt;This crate is not well maintained, to the point where the same issue has been submitted multiple times over the years.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2023 - https://github.com/gltf-rs/gltf/pull/392&lt;/li&gt;
&lt;li&gt;2025 - https://github.com/gltf-rs/gltf/pull/456&lt;/li&gt;
&lt;li&gt;2026 - https://github.com/gltf-rs/gltf/pull/467&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All three of these are for the same issue, adding &lt;code&gt;KHR_texture_basisu&lt;/code&gt; support, and in my opinion all three were/are clean implementations against the existing &lt;code&gt;gltf&lt;/code&gt; codebase.&lt;/p&gt;
&lt;p&gt;If you look at the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/gltf-rs/gltf/pulls&quot;&gt;outstanding PRs&lt;/a&gt;, most of them are for adding one or another of the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/KhronosGroup/glTF/tree/main/extensions&quot;&gt;Ratified Khronos Extensions
&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is where the fundamental issue arises. While these extensions are not part of the core glTF 2.0 specification, they are de facto needed in order to use glTF as a modern 3D asset standard, particularly where glTF/GLB is the primary and preferred asset format.&lt;/p&gt;
&lt;p&gt;As Bevy becomes more and more widely recognized as a game engine, it will become stranger and stranger that the only real options for textures are JPEG and PNG, both with their own issues and non-native GPU deficiencies.&lt;/p&gt;
&lt;p&gt;Even worse, in my book, is telling current and future Bevy developers that &quot;Bevy sort of hacks in KTX2 texture support in glTF files, but you need to use a special tool that turns your compliant glTF file into a non-compliant one BUT IT WORKS IN BEVY!&quot;&lt;/p&gt;
&lt;h1 id=&quot;what-should-we-aim-for&quot;&gt;What should we aim for?&lt;/h1&gt;
&lt;p&gt;Before continuing to consider resolutions, I think considering what would be desirable is worth doing.&lt;/p&gt;
&lt;h2 id=&quot;long-term&quot;&gt;Long Term&lt;/h2&gt;
&lt;p&gt;From a developer perspective, the ideal goal would be to make the glTF/GLB experience a first-class one.&lt;/p&gt;
&lt;p&gt;The developer should be able to use glTF/GLB files without fear, without worrying about compatibility or the need to hack things in, in the same way that a Unity developer imports &lt;code&gt;.unity&lt;/code&gt; assets knowing things will go smoothly.&lt;/p&gt;
&lt;p&gt;Technologically speaking, I think this means we aim for FULL compatibility with all &lt;a rel=&quot;external&quot; href=&quot;https://github.com/KhronosGroup/glTF/tree/main/extensions&quot;&gt;ratified Khronos extensions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is less daunting than it may seem. We already handle a good amount of these, and just need to parse the glTF JSON to hand it off to the relevant existing Bevy code.&lt;/p&gt;
&lt;p&gt;Others are already in progress.&lt;/p&gt;
&lt;p&gt;Others will need new code in Bevy or elsewhere.&lt;/p&gt;
&lt;p&gt;In addition, I would propose that we consider adding selected vendor extensions including &lt;code&gt;EXT_texture_webp&lt;/code&gt; and &lt;code&gt;EXT_texture_avif&lt;/code&gt; (if we have AVIF support in the engine already). These are less important, but would lean into the first-class developer experience.&lt;/p&gt;
&lt;h2 id=&quot;short-term&quot;&gt;Short Term&lt;/h2&gt;
&lt;p&gt;In looking at what level of expanded glTF support we see in other game engines, we see this:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Extension&lt;/th&gt;&lt;th&gt;Godot&lt;/th&gt;&lt;th&gt;Unity&lt;/th&gt;&lt;th&gt;Bevy&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_animation_pointer&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_draco_mesh_compression&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_lights_punctual&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_anisotropy&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_clearcoat&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_diffuse_transmission&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_dispersion&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_emissive_strength&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_ior&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues?q=is%3Aissue+is%3Aopen+KHR_materials_ior&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_iridescence&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_sheen&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues?q=is%3Aissue+is%3Aopen+KHR_materials_sheen&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_specular&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues?q=is%3Aissue+is%3Aopen+KHR_materials_specular&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_transmission&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues/111&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_unlit&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_variants&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_volume&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues/209&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_mesh_quantization&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_texture_basisu&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_texture_transform&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_xmp_json_ld&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_lights_image_based&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/issues/108&quot;&gt;in progress&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_mesh_gpu_instancing&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_meshopt_compression&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_texture_webp&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_pbrSpecularGlossiness&lt;/code&gt;&lt;/td&gt;&lt;td&gt;X*&lt;/td&gt;&lt;td&gt;partial&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;*&lt;a rel=&quot;external&quot; href=&quot;https://github.com/search?q=repo%3Agodotengine%2Fgodot%20KHR_&amp;amp;type=code&quot;&gt;Godot docs don&#39;t list supported and unsupported extensions, but looking through the source I found nothing missing.&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/atteneder/glTFast/blob/openupm/Documentation~/features.md&quot;&gt;Unity imports via glTFast&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;I propose that, short term, we aim to be a superset of Unity, focusing on supporting the extensions they have that we don&#39;t.&lt;/p&gt;
&lt;p&gt;Short term, we may consider adding &lt;code&gt;EXT_texture_webp&lt;/code&gt; as well, since this would be trivial once we decide on an approach.&lt;/p&gt;
&lt;h1 id=&quot;potential-resolutions&quot;&gt;Potential Resolutions&lt;/h1&gt;
&lt;p&gt;There are several resolutions I could foresee. BUT the only resolution that I think would be actively harmful would be to continue to base &lt;code&gt;bevy_gltf&lt;/code&gt; on &lt;code&gt;gltf-rs&lt;/code&gt; without a long-term plan.&lt;/p&gt;
&lt;p&gt;We should not pull a Warhammer 40k and build an empire around a slowly rotting corpse of a project. Not without a plan to lean less on the corpse at least.&lt;/p&gt;
&lt;h2 id=&quot;best-case-gltf-rs-revival&quot;&gt;Best Case - gltf-rs revival&lt;/h2&gt;
&lt;p&gt;If we can revive the project, either through a maintainer of &lt;code&gt;gltf-rs&lt;/code&gt; becoming active or through the project adding a Bevy-vouched-for approver, this would be the best case.&lt;/p&gt;
&lt;p&gt;With an understanding that the &lt;code&gt;gltf-rs&lt;/code&gt; project owners may have certain requirements, we could agree to only make changes that do not interfere with those requirements.&lt;/p&gt;
&lt;p&gt;This requires some buy-in from the &lt;code&gt;gltf-rs&lt;/code&gt; owners, which may be impossible.&lt;/p&gt;
&lt;p&gt;This would allow us to make these changes to benefit Bevy and the community as a whole.&lt;/p&gt;
&lt;h2 id=&quot;case-2-gltf-rs-fork&quot;&gt;Case 2 - gltf-rs fork&lt;/h2&gt;
&lt;p&gt;Another option is for a group of people to maintain a fork of the existing project. It will be more work, but the crate is well documented and has a test suite that could be expanded to reduce future labor.&lt;/p&gt;
&lt;p&gt;Here we could start by cherry-picking the relevant existing PRs, and we would be halfway done with our long-term goals.&lt;/p&gt;
&lt;p&gt;The advantage here is that we could use upstream labor in our efforts to maintain the crate. The whole wider community benefits.&lt;/p&gt;
&lt;h2 id=&quot;case-3-do-raw-gltf-i-o-in-house-as-part-of-bevy-gltf&quot;&gt;Case 3 - do raw glTF I/O in-house as part of bevy-gltf&lt;/h2&gt;
&lt;p&gt;This is less bad than one might think. Right now we use &lt;code&gt;gltf-rs&lt;/code&gt; and wrap our &quot;user space&quot; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/bevyengine/bevy/blob/162a7080911dc8b782475553fef8888c8d103655/crates/bevy_gltf/src/loader/extensions/mod.rs#L62&quot;&gt;GltfExtensionHandler trait&lt;/a&gt; around it.&lt;/p&gt;
&lt;p&gt;There are some existing extensions that are implemented in-house, namely &lt;code&gt;khr_materials_anisotropy&lt;/code&gt;, &lt;code&gt;khr_materials_clearcoat&lt;/code&gt;, and &lt;code&gt;khr_materials_specular&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I think this approach is valid. My primary concern here is that we are still wrapping the code around a slowly rotting corpse. My secondary concern is that we lose out on upstream efforts.&lt;/p&gt;
&lt;p&gt;I think there is a path forward if we take this approach.&lt;/p&gt;
&lt;p&gt;In addition to adding all the extensions that make for a predictable first-class glTF experience, we slowly handle the core glTF features as well using the same code paths.&lt;/p&gt;
&lt;p&gt;We have the &lt;code&gt;khr_materials_anisotropy&lt;/code&gt; extension, but we could then add &lt;code&gt;core_node_hierarchy&lt;/code&gt; that would handle a core glTF 2.0 feature.&lt;/p&gt;
&lt;p&gt;We could do this slowly over time, one piece at a time, replacing one core feature at a time until we have &lt;code&gt;core_*&lt;/code&gt;, where all glTF 2.0 core functionality is handled and wrapped around nothing.&lt;/p&gt;
&lt;p&gt;This would let us slowly migrate away without replacing the world.&lt;/p&gt;
&lt;h1 id=&quot;conclusion-key-points&quot;&gt;Conclusion / Key Points&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;If glTF is our preferred asset format, we should make using it a first-class experience.&lt;/li&gt;
&lt;li&gt;The root cause of the existing glTF problems is &lt;code&gt;gltf-rs&lt;/code&gt; not being well maintained.&lt;/li&gt;
&lt;li&gt;We can fix this root cause by reviving the core project, forking it, or bringing it in-house.&lt;/li&gt;
&lt;li&gt;No matter which way we go, we SHOULD &amp;amp; MUST not build an empire on a rotting corpse.&lt;/li&gt;
&lt;/ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Kungsfors Protector Sleeve</title>
        <published>2026-02-19T00:00:00+00:00</published>
        <updated>2026-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/kungsfors-protector-sleeve/"/>
        <id>https://dubiose.dev/mini-projects/kungsfors-protector-sleeve/</id>
        
        <summary type="html">&lt;p&gt;This protective sleeve was designed to fit over the IKEA Kungsfors magnetic knife holder. The sleeve prevents knife edges from making direct contact with the metal surface, reducing the risk of chipping when placing or removing knives. The design slides over the holder and stays in place during normal use.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Learning Engrammer</title>
        <published>2025-05-05T00:00:00+00:00</published>
        <updated>2025-05-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitlin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/blog/new-keyboard-new-layout/"/>
        <id>https://dubiose.dev/blog/new-keyboard-new-layout/</id>
        
        <content type="html" xml:base="https://dubiose.dev/blog/new-keyboard-new-layout/">&lt;h1 id=&quot;new-keyboard-new-layout&quot;&gt;New Keyboard New Layout&lt;/h1&gt;
&lt;p&gt;I recently decided to buy a new keyboard after my the pleather shedding issue with trusty Microsoft ergonomic keyboard became too severe to ignore. As well as that keyboard has served me, when it started polluting my home something needed to be done.&lt;/p&gt;
&lt;p&gt;After some research I landed on Keycron’s Q10 Max. The build quality is excellent, and the Alice style layout lets me stay in an ergonomic, but not too radical (i.e. split) form factor.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/new_keyboard_new_layout/desktop.avif&quot; alt=&quot;Picture of the author&amp;#39;s desk.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The Q10 Max being wireless let me continue on my path towards a clean, clutter free, and wire free desktop.&lt;/p&gt;
&lt;p&gt;I decided that, while I was at it I should consider alternative keyboard layouts. After all a new keyboard requires relearning muscle memory, why not double down?&lt;/p&gt;
&lt;p&gt;I considered a few layouts, namely &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rdavison/graphite-layout&quot;&gt;Graphite&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://engram.dev&quot;&gt;Engram&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/GalileoBlues/Gallium&quot;&gt;Gallium&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://sites.google.com/alanreiser.com/handsdown&quot;&gt;Hands Down&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An important thing I learned in my research is that there seems to be a definitive break between post and pre covid layouts, with post covid layouts being substantially more well designed.&lt;/p&gt;
&lt;p&gt;I ended up going with Engram variant because I liked the emphasis on roll-ins, and the inner column punctuation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/new_keyboard_new_layout/engrammer.webp&quot; alt=&quot;Engrammer Layout Digram&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I went with the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/sunaku/engrammer&quot;&gt;Engrammer&lt;/a&gt; because the brace and bracket locations in Engram where not great for software development.  Engrammer has the same letter layout as engram, except with a more programmer centric symbol layout.&lt;/p&gt;
&lt;h1 id=&quot;what-i-did-and-how-i-learned&quot;&gt;What I Did And How I Learned&lt;/h1&gt;
&lt;p&gt;Learning Engram was extremely painful. I committed to a cold turkey approach and switched both my laptop and desktop layout to use Engrammer on day one.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/new_keyboard_new_layout/keybr_cal.avif&quot; alt=&quot;Keybr.com Calendar showing one month of work.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I also did 30 minutes of daily keyboarding practice on &lt;a rel=&quot;external&quot; href=&quot;https://www.keybr.com&quot;&gt;keybr.com&lt;/a&gt; (which has many alternative layouts build in, including engram build in) daily for one month.&lt;/p&gt;
&lt;p&gt;The learing process went something like this:&lt;/p&gt;
&lt;h2 id=&quot;week-1&quot;&gt;Week 1&lt;/h2&gt;
&lt;p&gt;Pure Agony. If I worked a traditional job I surely would have been fired. My productivity dropped to like 5% on normal.&lt;/p&gt;
&lt;p&gt;I couldn’t even play video games normally. I had to remap every game I played to use the new layout. (I know I could have switched back for games, but I wanted to commit 100%.)&lt;/p&gt;
&lt;h2 id=&quot;week-2&quot;&gt;Week 2&lt;/h2&gt;
&lt;p&gt;Very painful. Posable to code but barely.&lt;/p&gt;
&lt;p&gt;Wondered why I decided to do such a dumb thing.&lt;/p&gt;
&lt;h2 id=&quot;week-3&quot;&gt;Week 3&lt;/h2&gt;
&lt;p&gt;Slow, but I can work.&lt;/p&gt;
&lt;p&gt;At this point it felt like things where starting to come together.&lt;/p&gt;
&lt;h2 id=&quot;week-4&quot;&gt;Week 4&lt;/h2&gt;
&lt;p&gt;Feeling slow but better.&lt;/p&gt;
&lt;p&gt;Over the hump for sure.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/blog/new_keyboard_new_layout/speed_chart.avif&quot; alt=&quot;Keybr.com Speed Progress Chart. Shows slow progress&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The main thing that helped was consistency. I practiced every day even if it was the only thing I did that day. My life basically revolves around typing in one form or another so even on bad days I had some motivation.&lt;/p&gt;
&lt;p&gt;If I had one tip for people who want to learn a new key layout it would be to practice every day.&lt;/p&gt;
&lt;h1 id=&quot;impact&quot;&gt;Impact&lt;/h1&gt;
&lt;p&gt;It&#39;s been just over a month and I continue to practice daily. Thing get better daily. This blog post probably only took 20% longer to type than it would have if I used QWERTY/Z.&lt;/p&gt;
&lt;p&gt;Funny thing is that I now struggle with QWERTY/Z.&lt;/p&gt;
&lt;p&gt;Overall typing feels better now and I am happy.&lt;/p&gt;
&lt;p&gt;Would I recommend learning a new layout? Yes, but only if you can commit hard. Otherwise the productivity drop would be too drastic for too long.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Box Fan Privacy Screen</title>
        <published>2025-04-05T00:00:00+00:00</published>
        <updated>2025-04-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/box-fan-privacy-screen/"/>
        <id>https://dubiose.dev/mini-projects/box-fan-privacy-screen/</id>
        
        <summary type="html">&lt;p&gt;This privacy screen was designed to provide privacy by replacing the front grate of a box fan. It allows air to flow threw without allowing look in. Perfect if you want cool air and privacy! The grate was designed for a Lasko box fan but should work with other box fans.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>280mm x 150mm Crate</title>
        <published>2025-04-04T00:00:00+00:00</published>
        <updated>2025-04-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/crate/"/>
        <id>https://dubiose.dev/mini-projects/crate/</id>
        
        <summary type="html">&lt;p&gt;This 280mm x 150mm robust crate was designed to hold root vegetables, but could be used for any heavy goods. This is being released as one of many simpler designs I made over the years.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Nasal Strip Holder</title>
        <published>2025-04-03T00:00:00+00:00</published>
        <updated>2025-04-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/nasal-strip-holder/"/>
        <id>https://dubiose.dev/mini-projects/nasal-strip-holder/</id>
        
        <summary type="html">&lt;p&gt;This simple nasal strip holder was designed to be placed on a nightstand and keep things organized. The design is simple and trivial to change. This is being released as one of many simpler designs I made over the years.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Roller Blind Window Clip</title>
        <published>2022-05-28T00:00:00+00:00</published>
        <updated>2022-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/roller-blind-window-clip/"/>
        <id>https://dubiose.dev/mini-projects/roller-blind-window-clip/</id>
        
        <summary type="html">&lt;p&gt;This roller blind window clip was designed to be compatible with Gardinia. This clip was designed after the original one was broken and a replacement was needed. This design is definitively stronger than the original design.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>PanelDue 7i Case for the Railcore II </title>
        <published>2020-03-24T00:00:00+00:00</published>
        <updated>2020-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/paneldue-7i-case-railcore/"/>
        <id>https://dubiose.dev/mini-projects/paneldue-7i-case-railcore/</id>
        
        <summary type="html">&lt;p&gt;This is my simple PanelDue 7i case for the Railcore II.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Secret Hitler Name Plaques</title>
        <published>2019-11-17T00:00:00+00:00</published>
        <updated>2019-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/secret-hitler-name-plaques/"/>
        <id>https://dubiose.dev/mini-projects/secret-hitler-name-plaques/</id>
        
        <summary type="html">&lt;p&gt;A quick multi material 3d print project I put together for a friend. These are used in the VERY fun (and freely available) &lt;a rel=&quot;external&quot; href=&quot;https://www.secrethitler.com/&quot;&gt;Secret Hitler&lt;/a&gt; Game. If you like the game I would encourage you to support the creators by purchasing a pre printed card set from them.&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Tall Laptop Stand</title>
        <published>2019-09-06T00:00:00+00:00</published>
        <updated>2019-09-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            Caitlin Sar Campbell
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dubiose.dev/mini-projects/tall-laptop-stand/"/>
        <id>https://dubiose.dev/mini-projects/tall-laptop-stand/</id>
        
        <summary type="html">&lt;p&gt;This project was my first ever venture into 3D design. I had just acquired a 3D printer and wanted to print something out for myself. This was created in &quot;Parts&quot; mode in FreeCAD. In the end the design worked out well and I used it for many years.&lt;/p&gt;</summary>
        
    </entry>
</feed>
