<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: w4ffl35</title>
    <description>The latest articles on DEV Community by w4ffl35 (@w4ffl35).</description>
    <link>https://dev.to/w4ffl35</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F130235%2F8f8824a3-f180-428f-87b1-a08b042bf8f2.jpg</url>
      <title>DEV Community: w4ffl35</title>
      <link>https://dev.to/w4ffl35</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/w4ffl35"/>
    <language>en</language>
    <item>
      <title>Clip Studio Paint EX 1.13.2 on Linux with Wine</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Tue, 06 Oct 2026 16:49:07 +0000</pubDate>
      <link>https://dev.to/w4ffl35/clip-studio-paint-ex-1132-on-linux-with-wine-1e76</link>
      <guid>https://dev.to/w4ffl35/clip-studio-paint-ex-1132-on-linux-with-wine-1e76</guid>
      <description>&lt;h1&gt;
  
  
  Clip Studio Paint EX 1.13.2 on Linux with Wine
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt8udko4qs5idbdqnzlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt8udko4qs5idbdqnzlz.png" alt="Clip Studio Paint EX 1.x running on Linux through Wine" width="799" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I bought Clip Studio Paint EX 1.13.2 a few years ago and wanted to keep using it on Linux.&lt;/p&gt;

&lt;p&gt;It opens on my Debian 13 desktop through Wine, and I was able to sign in. I wrote down the setup I used, including the XP-Pen Deco LW (IT1060B) notes, in &lt;a href="https://github.com/w4ffl35/linux-clipstudio-installer" rel="noopener noreferrer"&gt;linux-clipstudio-installer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Wine is unofficial, so I don't know how it will behave on every system. The installer doesn't include Clip Studio Paint or bypass license activation.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>software</category>
      <category>tools</category>
    </item>
    <item>
      <title>What I split into public Capsize packages</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Wed, 30 Sep 2026 15:15:01 +0000</pubDate>
      <link>https://dev.to/w4ffl35/what-i-split-into-public-capsize-packages-3ac2</link>
      <guid>https://dev.to/w4ffl35/what-i-split-into-public-capsize-packages-3ac2</guid>
      <description>&lt;p&gt;I didn't set out to make a pile of tiny repos. I kept finding code that already had one clear job and could be useful outside the app where it started. This week I gave those pieces their own public homes.&lt;/p&gt;

&lt;p&gt;The companion and social pieces are the largest group:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-auth" rel="noopener noreferrer"&gt;capsize-auth&lt;/a&gt; provides password, token and OAuth2 primitives.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-bluesky" rel="noopener noreferrer"&gt;capsize-bluesky&lt;/a&gt; is the AT Protocol client used by the social tools.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-social" rel="noopener noreferrer"&gt;capsize-social&lt;/a&gt; handles Bluesky and Discord account connections.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-voice" rel="noopener noreferrer"&gt;capsize-voice&lt;/a&gt; measures a writing style and uses that profile during generation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-persona" rel="noopener noreferrer"&gt;capsize-persona&lt;/a&gt; combines persona, voice and long-term conversation facts in a reply service.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-memory" rel="noopener noreferrer"&gt;capsize-memory&lt;/a&gt; provides SQLAlchemy models and functions for rooms, participants and conversation turns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was the test: does this piece have one job, and can another app use it on its own? A bot can use the Bluesky client without loading the persona service. A local chat app can keep conversation memory without knowing anything about Discord. An app can also hand &lt;code&gt;capsize-memory&lt;/code&gt; its own database session. The package doesn't need to own the connection.&lt;/p&gt;

&lt;p&gt;The supporting repositories cover a different layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-commons" rel="noopener noreferrer"&gt;capsize-commons&lt;/a&gt; contains selectively installable Python, TypeScript and C++ building blocks.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-ci" rel="noopener noreferrer"&gt;capsize-ci&lt;/a&gt; contains versioned reusable GitHub Actions workflows.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-fastmail" rel="noopener noreferrer"&gt;capsize-fastmail&lt;/a&gt; reads Fastmail through JMAP, including mailbox listing, pagination and delta sync.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Capsize-Games/capsize-github-traffic" rel="noopener noreferrer"&gt;capsize-github-traffic&lt;/a&gt; saves repository traffic history before GitHub's 14-day window drops it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AIRunner had the same problem. I split out &lt;a href="https://github.com/Capsize-Games/airunner-common" rel="noopener noreferrer"&gt;airunner-common&lt;/a&gt;, &lt;a href="https://github.com/Capsize-Games/airunner-eval" rel="noopener noreferrer"&gt;airunner-eval&lt;/a&gt;, &lt;a href="https://github.com/Capsize-Games/airunner-native" rel="noopener noreferrer"&gt;airunner-native&lt;/a&gt; and &lt;a href="https://github.com/Capsize-Games/airunner-tts-vendor" rel="noopener noreferrer"&gt;airunner-tts-vendor&lt;/a&gt;. Shared code, agent tests, the native launcher and the MeloTTS/OpenVoice layer no longer need to move as one block.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical way to use the split
&lt;/h2&gt;

&lt;p&gt;Start small. If an app only needs Bluesky, use &lt;code&gt;capsize-bluesky&lt;/code&gt;. If it needs account storage and posting across services, add &lt;code&gt;capsize-social&lt;/code&gt;. Bring in memory, voice or a persona only when the app needs it.&lt;/p&gt;

&lt;p&gt;The same rule applies to AIRunner. Its launcher shouldn't own the eval harness, and the eval harness shouldn't drag in the desktop app. The split makes that obvious. It also lets each piece ship when it's ready.&lt;/p&gt;

&lt;p&gt;I want these repos to stay small enough to read. If one starts collecting unrelated work, that is a sign that the boundary has gone bad. The point is not the repo count. The point is being able to use one part without hauling the rest of the system behind it.&lt;/p&gt;

&lt;p&gt;The full list, including commit and release counts, is in the &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;four-week Capsize report&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>devtools</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Sharing Django plumbing with capsize-commons</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Tue, 29 Sep 2026 15:15:01 +0000</pubDate>
      <link>https://dev.to/w4ffl35/sharing-django-plumbing-with-capsize-commons-3fnh</link>
      <guid>https://dev.to/w4ffl35/sharing-django-plumbing-with-capsize-commons-3fnh</guid>
      <description>&lt;p&gt;I published &lt;a href="https://github.com/Capsize-Games/capsize-commons" rel="noopener noreferrer"&gt;capsize-commons&lt;/a&gt;, then used it in sites that already existed. A shared package does not help much if every live site keeps its own copy of the same settings and health checks. Shipping it was only the start.&lt;/p&gt;

&lt;p&gt;The Python package now carries shared settings construction, logging, health/readiness routes and small HTTP helpers. The TypeScript side is published as &lt;code&gt;@capsizellc/commons&lt;/code&gt;. The first adopters included Capsize Online, joecurlee.com, the WXRQ admin surface and other Django sites. Each site kept its own application. They stopped maintaining separate versions of the same foundation.&lt;/p&gt;

&lt;p&gt;The stack is deliberately boring: Python packaging, Django, a small TypeScript package, CI and trusted publishing. The technical angle is the adoption seam. A shared helper has to preserve the old site's behavior while making the next site easier to start. That means compatibility checks, a versioned health contract and a migration that can be reviewed one site at a time.&lt;/p&gt;

&lt;p&gt;I can now fix a shared retry or settings bug once, publish a version, and update each site when I am ready.&lt;/p&gt;

&lt;p&gt;The source is &lt;a href="https://github.com/Capsize-Games/capsize-commons" rel="noopener noreferrer"&gt;capsize-commons on GitHub&lt;/a&gt;. The public sites that use the pattern include &lt;a href="https://capsize.online/" rel="noopener noreferrer"&gt;capsize.online&lt;/a&gt; and &lt;a href="https://joecurlee.com/" rel="noopener noreferrer"&gt;joecurlee.com&lt;/a&gt;. The release context is in the &lt;a href="https://capsize.online/" rel="noopener noreferrer"&gt;Capsize four-week overview&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical adoption order
&lt;/h2&gt;

&lt;p&gt;Start with one shared behavior that is easy to observe. Health and readiness routes are a good candidate because a smoke check can compare the old and new responses. Publish a small version. Adopt it in one site. Run the same check. Only then move the next site.&lt;/p&gt;

&lt;p&gt;That sequence keeps a shared library from becoming a second monolith. The library owns the common contract. The application owns the reason it exists.&lt;/p&gt;

&lt;p&gt;The first adopters are deliberately different. A project portal, a personal site and a radio admin do not have the same job, but they do need the same answer for health, settings and a few boring operational details. A shared package earns its place when that common answer gets easier to maintain without flattening the applications around it.&lt;/p&gt;

&lt;p&gt;The package is small on purpose. It should remove repeated setup, not become the place where every application-specific choice goes to hide.&lt;/p&gt;

&lt;p&gt;That restraint is what makes the next adoption reviewable.&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I built Capsize Online as a static Django site</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Mon, 28 Sep 2026 15:15:02 +0000</pubDate>
      <link>https://dev.to/w4ffl35/how-i-built-capsize-online-as-a-static-django-site-5a0g</link>
      <guid>https://dev.to/w4ffl35/how-i-built-capsize-online-as-a-static-django-site-5a0g</guid>
      <description>&lt;p&gt;I built &lt;a href="https://capsize.online/" rel="noopener noreferrer"&gt;Capsize Online&lt;/a&gt; to collect my public software, games and release notes in one place. I wanted Django for editing, but I did not need a live application server for pages that only change when I publish them. The site compiles the Django content into static files for production.&lt;/p&gt;

&lt;p&gt;The site went live during the week with the shared Capsize shader identity and a tag-driven deploy path. The authoring database stays local. The production server receives the compiled output, not a running Django application. That keeps the public surface simple while leaving the content workflow pleasant to edit.&lt;/p&gt;

&lt;p&gt;The output can live on any plain web server. Each tagged build also leaves a clear release and rollback point.&lt;/p&gt;

&lt;p&gt;The site links &lt;a href="https://airunner.art/" rel="noopener noreferrer"&gt;AIRunner&lt;/a&gt;, &lt;a href="https://spikeforge.net/" rel="noopener noreferrer"&gt;SpikeForge&lt;/a&gt;, the &lt;a href="https://av.capsizegames.com/" rel="noopener noreferrer"&gt;Capsize Audio Visualizer&lt;/a&gt;, &lt;a href="https://capsizegames.com/" rel="noopener noreferrer"&gt;Capsize Games&lt;/a&gt;, &lt;a href="https://radio.capsize.online/" rel="noopener noreferrer"&gt;WXRQ&lt;/a&gt; and &lt;a href="https://joecurlee.com/" rel="noopener noreferrer"&gt;my personal site&lt;/a&gt;. Its devlog can connect a project update directly to the repositories and releases behind it.&lt;/p&gt;

&lt;p&gt;The live portal is &lt;a href="https://capsize.online/" rel="noopener noreferrer"&gt;capsize.online&lt;/a&gt;. The four-week release story is in &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;Four weeks of building in public&lt;/a&gt;, with the technical project notes collected on &lt;a href="https://dev.to/w4ffl35"&gt;DEV&lt;/a&gt;. The report links each public repository directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small Django site pattern
&lt;/h2&gt;

&lt;p&gt;Keep the content model small. A title, a slug, a summary, a body, a date and a publication status are enough for a useful devlog. Render the body to a static route during the build. Put the public images in the static tree and let the compiler carry them with the page.&lt;/p&gt;

&lt;p&gt;This pattern works well for a project portal because the authoring experience and the deployment target have different needs. Django is a good editor. Static HTML is a good thing to serve.&lt;/p&gt;

&lt;p&gt;The first version of the site was a list of links. The current version is closer to a small index of finished things: a project has a page, a release has a place to land, and a reader can move from a chart to the thing that produced it.&lt;/p&gt;

&lt;p&gt;That is a modest job for a website, but it is a useful one. The portal does not need to explain every implementation detail. It needs to make the next click obvious and keep the project names, release pages and public work in one place.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Porting Cowboy Casino to VileEngine</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Sun, 27 Sep 2026 15:15:01 +0000</pubDate>
      <link>https://dev.to/w4ffl35/porting-cowboy-casino-to-vileengine-19f</link>
      <guid>https://dev.to/w4ffl35/porting-cowboy-casino-to-vileengine-19f</guid>
      <description>&lt;p&gt;I am moving &lt;a href="https://capsizegames.itch.io/cowboy-casino" rel="noopener noreferrer"&gt;Cowboy Casino&lt;/a&gt; into VileEngine, the C++ engine I use for retro games. Cowboy Casino is a small role-playing game about walking into a wild-west casino, learning the tables and trying to leave with more chips than you brought in.&lt;/p&gt;

&lt;p&gt;The work is bigger than replacing one renderer. The casino is an overworld with rooms, doors, table scenes, dealers, save slots, character movement, dialogue and an ending. The native port now has the campaign map, collision and visibility layers, the table sessions, versioned persistence, converted art and new audio loops for the casino floor and boss table. The release build is the next milestone.&lt;/p&gt;

&lt;p&gt;VileEngine supplies the C++23 runtime, SFML presentation, miniaudio, the CRT treatment and the editor tools around them. Cowboy Casino supplies the content and the rules. Keeping those responsibilities separate makes the port easier to test: the engine can improve its scene and audio work while the game keeps its own campaign state and table logic.&lt;/p&gt;

&lt;p&gt;The original game is available on &lt;a href="https://capsizegames.itch.io/cowboy-casino" rel="noopener noreferrer"&gt;itch.io&lt;/a&gt;, and the public project map is on &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;capsize.online&lt;/a&gt;. I will add the remake download there when the release build is ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a port feel like the same game
&lt;/h2&gt;

&lt;p&gt;The first pass is not the final screen. It is the return path. Walk from the casino to a table, finish a round, return to the same room, save, quit and load it again. If those transitions keep the wallet, position and campaign state intact, the port has a foundation. The visual polish can then move forward without hiding a missing game rule.&lt;/p&gt;

&lt;p&gt;The next public milestone is the remake release. Until then, the itch page remains the right place for the original download and the repository is the right place for the engine work.&lt;/p&gt;

&lt;p&gt;The port also gives VileEngine a real game to push against. A scene stack, an editor, audio and a CRT pass are easy to discuss in isolation. They become useful when a player can walk through a casino, sit down at a table, finish a round and return to the room they left.&lt;/p&gt;

&lt;p&gt;That is the standard for the release candidate. The screen can change later. The game has to remember what the player did and bring them back to a place that still makes sense.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>indiedev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building the Capsize Audio Visualizer with C++ and Qt</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Sat, 26 Sep 2026 15:15:01 +0000</pubDate>
      <link>https://dev.to/w4ffl35/building-the-capsize-audio-visualizer-with-c-and-qt-4lln</link>
      <guid>https://dev.to/w4ffl35/building-the-capsize-audio-visualizer-with-c-and-qt-4lln</guid>
      <description>&lt;p&gt;I keep coming back to the &lt;a href="https://av.capsizegames.com/" rel="noopener noreferrer"&gt;Capsize Audio Visualizer&lt;/a&gt; because it is small enough to finish. It is a C++ and Qt desktop application that turns live audio into shader-driven scenes, with controls for changing how the signal affects the picture.&lt;/p&gt;

&lt;p&gt;This week it picked up CRT presentation work, floating mode, cross-shader audio mappings and three releases. The project is written in C++ and Qt with a native audio path and a collection of shader-driven scenes. The visual identity is not a web-only skin. The same shader language and palette now appear across the desktop app, the public site and the other Capsize properties.&lt;/p&gt;

&lt;p&gt;Floating mode is a small feature with a large effect on how the application is used. The visualizer can sit beside another application instead of taking over the whole screen. Cross-shader mappings make the audio signal feel like one input to a set of related scenes rather than a separate toggle in every effect.&lt;/p&gt;

&lt;p&gt;Try the public build at &lt;a href="https://av.capsizegames.com/" rel="noopener noreferrer"&gt;av.capsizegames.com&lt;/a&gt; or see the desktop edition on &lt;a href="https://capsizegames.itch.io/capsize-audio-visualizer" rel="noopener noreferrer"&gt;itch.io&lt;/a&gt;. The full four-week overview is on &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;capsize.online&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A useful way to extend it
&lt;/h2&gt;

&lt;p&gt;Pick one audio feature and map it to one visual parameter. Keep the mapping visible in the shader or effect configuration. Then add a second effect that responds to the same signal in a different way. The result is easier to tune when the signal path is shared and the visual differences live at the edge.&lt;/p&gt;

&lt;p&gt;That is the balance I want from the project: a small program people can use tonight, with enough structure that the next visual idea has somewhere to go.&lt;/p&gt;

&lt;p&gt;The public build makes the idea easy to test. Start a track, put the window beside another application, change the mapping and watch the same signal move through a different scene. If the effect needs a paragraph before it makes sense, the effect probably needs another pass.&lt;/p&gt;

&lt;p&gt;The release work also keeps the boring edges in view: a local queued build, a repeatable package and a public page that explains what the download is. A visual tool gets better when the distance between changing a shader and trying the result stays short.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>qt</category>
      <category>audio</category>
      <category>shaders</category>
    </item>
    <item>
      <title>WXRQ turned a production kit into a radio station</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:15:02 +0000</pubDate>
      <link>https://dev.to/w4ffl35/wxrq-turned-a-production-kit-into-a-radio-station-a8o</link>
      <guid>https://dev.to/w4ffl35/wxrq-turned-a-production-kit-into-a-radio-station-a8o</guid>
      <description>&lt;p&gt;I started &lt;a href="https://radio.capsize.online/" rel="noopener noreferrer"&gt;WXRQ&lt;/a&gt; as a new repository for an automated radio and television station. Within a few days it had a public player, a schedule and a production path from written script to an HLS stream.&lt;/p&gt;

&lt;p&gt;The production kit writes and checks a script, renders several voice takes, chooses a take for each line, adds a music bed, schedules the result, encodes it and sends it through HLS. The television channel has its own transport. The public site shows the player and schedule. The admin lets the production work be browsed and edited. The lecture pipeline turns CC BY textbooks into narrated courseware, so the station is not limited to one kind of show.&lt;/p&gt;

&lt;p&gt;The stack is a mixture of Python, Django, Chatterbox, LMMS, NVENC and a small web player. Each tool has a job. The script gate catches problems before a voice is rendered. The voice path can compare several takes instead of accepting the first file that came back. HLS gives the public channel a normal streaming surface rather than a private development endpoint.&lt;/p&gt;

&lt;p&gt;The station reached 0.6.13 during the week. You can listen, see what is on air and check the schedule at &lt;a href="https://radio.capsize.online/" rel="noopener noreferrer"&gt;radio.capsize.online&lt;/a&gt;. The wider release story is on &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;capsize.online&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a small show
&lt;/h2&gt;

&lt;p&gt;Start with one short segment. Give it a beginning, a change and an ending. Run the script checks before you touch the voice pipeline. Render more than one take only when the line needs it, then keep the chosen take next to the script and the reason for choosing it. Add a bed that supports the scene instead of competing with it.&lt;/p&gt;

&lt;p&gt;That small loop is enough to learn the system. After that, add the schedule and the public player. A station becomes a product when someone outside the repository can find the show, hear it and know what comes next.&lt;/p&gt;

&lt;p&gt;The station is still small, which is exactly why the pieces are easy to see. A script is an input. A chosen take is an artefact. A schedule is a promise about what a listener will hear. The public player is where all of those decisions meet.&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>audio</category>
      <category>livestreaming</category>
    </item>
    <item>
      <title>AIRunner is becoming a set of tools instead of one giant tree</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Thu, 24 Sep 2026 15:15:01 +0000</pubDate>
      <link>https://dev.to/w4ffl35/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree-3k9b</link>
      <guid>https://dev.to/w4ffl35/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree-3k9b</guid>
      <description>&lt;p&gt;I had let &lt;a href="https://github.com/Capsize-Games/airunner" rel="noopener noreferrer"&gt;AIRunner&lt;/a&gt;, my open-source desktop AI application, do too much in one repository. The split is now visible in four public packages: &lt;a href="https://github.com/Capsize-Games/airunner-eval" rel="noopener noreferrer"&gt;airunner-eval&lt;/a&gt;, &lt;a href="https://github.com/Capsize-Games/airunner-tts-vendor" rel="noopener noreferrer"&gt;airunner-tts-vendor&lt;/a&gt;, &lt;a href="https://github.com/Capsize-Games/airunner-native" rel="noopener noreferrer"&gt;airunner-native&lt;/a&gt; and &lt;a href="https://github.com/Capsize-Games/airunner-common" rel="noopener noreferrer"&gt;airunner-common&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The names describe the boundaries. The evaluation package can process models without dragging the application into the run. The TTS vendor fork can be tested and published without importing the host application's database. Native tools can stay close to their sidecar binaries. Shared request and response payloads can be versioned once and consumed by the desktop and service layers.&lt;/p&gt;

&lt;p&gt;The web engine moved in the same direction. It stopped naming the products it hosts, moved the world and economy layer into &lt;code&gt;uwuchat-worldsystems&lt;/code&gt;, and renamed the service package to &lt;code&gt;airunner_engine&lt;/code&gt;. The remaining boundary is visible in the code instead of being a convention in a README. That matters when a new application is added because the engine has fewer reasons to know it exists.&lt;/p&gt;

&lt;p&gt;The stack is still familiar: Python, PySide6, HTTP and WebSocket services, package publishing and CI checks. The work was less about picking a new framework and more about making the existing contracts explicit. Import boundaries run in CI. The desktop/daemon contract has a version. Shared &lt;code&gt;LLMRequest&lt;/code&gt; and &lt;code&gt;LLMResponse&lt;/code&gt; payloads live in &lt;code&gt;airunner-common&lt;/code&gt; instead of being copied between packages.&lt;/p&gt;

&lt;p&gt;The user-facing site is &lt;a href="https://airunner.art/" rel="noopener noreferrer"&gt;airunner.art&lt;/a&gt;. The &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;four-week release overview&lt;/a&gt; covers the other projects that moved alongside it.&lt;/p&gt;

&lt;p&gt;The payoff is visible when a new change arrives. A model-evaluation change can stay in the evaluator. A native sidecar change can stay with the sidecar. The desktop app can consume a versioned payload instead of reaching into a folder that happened to be next door. Those are small boundaries, but they remove a lot of guesswork from the next release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why extract a package?
&lt;/h2&gt;

&lt;p&gt;Extraction is worth doing when the package has its own reason to change, its own tests and a public consumer that should not install the rest of the application. If those things are not true, a new repository is just another place to forget to update.&lt;/p&gt;

&lt;p&gt;The next AIRunner step is to keep the service boundary just as clear as the first four extractions. The goal is a smaller set of packages that can be installed and released independently while the desktop application still feels like one thing.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>desktop</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build a small event-driven classifier with SpikeForge</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Wed, 23 Sep 2026 15:15:02 +0000</pubDate>
      <link>https://dev.to/w4ffl35/build-a-small-event-driven-classifier-with-spikeforge-5a</link>
      <guid>https://dev.to/w4ffl35/build-a-small-event-driven-classifier-with-spikeforge-5a</guid>
      <description>&lt;p&gt;I like to learn SpikeForge by giving it a small job and keeping the moving pieces visible. This walkthrough uses the public toolkit, a short experiment and the event path that gained a real train/test split in the latest release cycle.&lt;/p&gt;

&lt;p&gt;Start with the &lt;a href="https://github.com/Capsize-Games/spikeforge" rel="noopener noreferrer"&gt;SpikeForge repository&lt;/a&gt; and install the package in a fresh environment. Pick one of the example datasets already supported by the project. Keep the first run short. A small experiment that you can rerun is more useful than a large run that leaves you guessing about which setting changed the result.&lt;/p&gt;

&lt;p&gt;The shape of the experiment is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load the dataset and turn the samples into the event representation.&lt;/li&gt;
&lt;li&gt;Split the samples before training, so the test set stays out of the update loop.&lt;/li&gt;
&lt;li&gt;Choose a compact network and a short number of epochs.&lt;/li&gt;
&lt;li&gt;Save the configuration beside the result.&lt;/li&gt;
&lt;li&gt;Compare the test output with the training output rather than reporting one number alone.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The train/test split is the important detail. It keeps an event-driven experiment honest when the model is changing quickly. The same configuration can then move through a target adapter or into the &lt;a href="https://github.com/Capsize-Games/spikeforge-hub" rel="noopener noreferrer"&gt;SpikeForge model hub&lt;/a&gt; with a name, version and small amount of provenance.&lt;/p&gt;

&lt;p&gt;SpikeForge is built around Python, PyTorch and snnTorch, but the useful interface is the experiment boundary. You can change the model without changing the dataset loader. You can add a target without rewriting the training loop. That is why the project was split into packages rather than kept as a single directory with a longer README.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to record
&lt;/h2&gt;

&lt;p&gt;Record the dataset, event conversion, seed, model name, number of epochs and the exact package versions. Put those beside the output rather than in a notebook cell that will disappear. If you publish the result, include the short configuration and a link to the source. Small habits like this make the next experiment faster because you can see what actually changed.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://spikeforge.net/" rel="noopener noreferrer"&gt;SpikeForge project page&lt;/a&gt; has the current package and dashboard links. I also wrote a &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;four-week Capsize overview&lt;/a&gt; with the release context and the other projects that moved at the same time.&lt;/p&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SpikeForge Dashboard gives the experiment a desktop home</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Tue, 22 Sep 2026 15:15:09 +0000</pubDate>
      <link>https://dev.to/w4ffl35/spikeforge-dashboard-gives-the-experiment-a-desktop-home-amd</link>
      <guid>https://dev.to/w4ffl35/spikeforge-dashboard-gives-the-experiment-a-desktop-home-amd</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/Capsize-Games/spikeforge-dashboard" rel="noopener noreferrer"&gt;SpikeForge Dashboard&lt;/a&gt; is the desktop interface for experiments made with the SpikeForge spiking-neural-network toolkit. Its desktop builds moved through 0.2.5 and 0.2.6 after a run of smaller releases that established the packaging path.&lt;/p&gt;

&lt;p&gt;The dashboard exists for the part of the work that is awkward in a terminal: looking at an experiment, checking what was loaded, and keeping the result close to the configuration that produced it. It is a React and TypeScript dashboard packaged as a desktop application and backed by the SpikeForge packages. The app is not a replacement for Python. It is a visual surface for the same experiment.&lt;/p&gt;

&lt;p&gt;The release work focused on the boundary between source code and the thing a user downloads. The build now has a package path, a desktop bundle, smoke checks and a small release checklist. The source tree can be green while the archive has the wrong files, the wrong path or a missing licence. The packaged archive is part of the test target.&lt;/p&gt;

&lt;p&gt;The source is public in the &lt;a href="https://github.com/Capsize-Games/spikeforge-dashboard" rel="noopener noreferrer"&gt;SpikeForge Dashboard repository&lt;/a&gt;. The project site is &lt;a href="https://spikeforge.net/" rel="noopener noreferrer"&gt;spikeforge.net&lt;/a&gt;, and the desktop build is available through &lt;a href="https://capsizegames.itch.io/spikeforge-desktop" rel="noopener noreferrer"&gt;Capsize Games on itch.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wanted the app to feel like a place for the experiment rather than a launcher with a screenshot attached. That means the current run, the loaded data and the path back to the source should stay near each other. It also means the release archive gets opened and checked as an archive, not only built as a side effect of the CI job.&lt;/p&gt;

&lt;h2&gt;
  
  
  A good first use
&lt;/h2&gt;

&lt;p&gt;Install the desktop build and open one of the small examples from the core toolkit. Keep the experiment short, then compare the training and test views. If the result is worth keeping, move the configuration into the repository or the model hub instead of leaving it inside a screenshot.&lt;/p&gt;

&lt;p&gt;This is the pattern I want from the desktop projects: a finished surface, a public download and a clear route back to the code. The next release can improve the surface without hiding how the experiment works.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;broader four-week release story&lt;/a&gt; covers the other software, games and sites that moved at the same time.&lt;/p&gt;

</description>
      <category>python</category>
      <category>qt</category>
      <category>desktop</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SpikeForge grew into a toolkit, a model hub and a dashboard</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Mon, 21 Sep 2026 21:21:52 +0000</pubDate>
      <link>https://dev.to/w4ffl35/spikeforge-grew-into-a-toolkit-a-model-hub-and-a-dashboard-37k3</link>
      <guid>https://dev.to/w4ffl35/spikeforge-grew-into-a-toolkit-a-model-hub-and-a-dashboard-37k3</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/Capsize-Games/spikeforge" rel="noopener noreferrer"&gt;SpikeForge&lt;/a&gt; is my Python toolkit for building and testing spiking neural networks. It stopped behaving like one big project during this release cycle: the core toolkit, target adapters, model hub and SpikeForge Dashboard all moved forward as separate packages and applications.&lt;/p&gt;

&lt;p&gt;The core project released 0.4.0 and 0.5.0, then kept publishing the smaller package releases that make the ecosystem usable. The event path got a real train/test split. Quantization work moved into the drift checks. Shared logging came from &lt;code&gt;capsize-commons&lt;/code&gt;, and the CI path gained a fast leaf lane for the parts that do not need the whole workspace.&lt;/p&gt;

&lt;p&gt;The package layout is now a practical map of the work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;spikeforge&lt;/code&gt; holds the training and experiment workflow.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spikeforge-targets&lt;/code&gt; holds target-specific conversions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spikeforge-hub&lt;/code&gt; owns the offline-first model catalogue.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spikeforge-dashboard&lt;/code&gt; contains the web dashboard and desktop application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation is useful, not just a tidy repository list. Someone experimenting in Python does not need to install the desktop app. Someone browsing models does not need the server. Each piece can ship when it is ready, with compatibility recorded instead of implied.&lt;/p&gt;

&lt;p&gt;The stack is Python, PyTorch and snnTorch around the core, with a web dashboard and desktop application around it. The model hub is deliberately cache-friendly, so a catalogue can be inspected and used without turning every experiment into a network operation. SpikeForge Dashboard gives the same work a visual entry point and provides a place to inspect the experiment rather than only its final number.&lt;/p&gt;

&lt;p&gt;The project page has the current package links and release notes: &lt;a href="https://spikeforge.net/" rel="noopener noreferrer"&gt;spikeforge.net&lt;/a&gt;. The desktop releases are collected on &lt;a href="https://capsizegames.itch.io/spikeforge-desktop" rel="noopener noreferrer"&gt;itch.io&lt;/a&gt;, and the source is on &lt;a href="https://github.com/Capsize-Games/spikeforge" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small experiment to try
&lt;/h2&gt;

&lt;p&gt;Install the core package, choose one of the examples, and keep the first run small. Start with one dataset and a short training window. Then move the same experiment through the target adapter and save the result in the hub catalogue. The point of the exercise is not a leaderboard number. It is seeing the path from an experiment to a named, repeatable artefact.&lt;/p&gt;

&lt;p&gt;A follow-up article walks through a small event-driven classifier. The &lt;a href="https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/" rel="noopener noreferrer"&gt;four-week overview&lt;/a&gt; covers the rest of the Capsize work from the same period.&lt;/p&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>The Consciousness Gradient: Qualia, Integration, and the Emergence of Intelligence v2.1.0</title>
      <dc:creator>w4ffl35</dc:creator>
      <pubDate>Sun, 06 Sep 2026 19:26:52 +0000</pubDate>
      <link>https://dev.to/w4ffl35/the-consciousness-gradient-qualia-integration-and-the-emergence-of-intelligence-v210-3bgi</link>
      <guid>https://dev.to/w4ffl35/the-consciousness-gradient-qualia-integration-and-the-emergence-of-intelligence-v210-3bgi</guid>
      <description>&lt;p&gt;The Consciousness Gradient: Qualia, Integration, and the Emergence of Intelligence&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://zenodo.org/records/22547704" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzenodo.org%2Fstatic%2Fimages%2Feu.png" height="60" class="m-0" width="88"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://zenodo.org/records/22547704" rel="noopener noreferrer" class="c-link"&gt;
            The Consciousness Gradient: Qualia, Integration, and the Emergence of Intelligence | Zenodo
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            This paper proposes an exploratory framework in which consciousness and qualia are treated as the same phenomenon at different degrees of integration. On this view, minimal qualia are minimal consciousness, while macro-awareness is a more highly integrated and reportable form of the same underlying process. The paper further advances the hypothesis that intelligence, understood as flexible adaptation to structurally novel situations, emerges only once qualitative integration reaches sufficient depth. The framework is developed through a dual-aspect interpretation of physically instantiated processing and introduces the idea of autonomous experiential synthesis: a history-bearing, environmentally coupled process in which past experience shapes present processing in an open-ended way. The paper contrasts this with current AI systems built on fixed architectures and frozen learned parameters, and proposes that such systems may fail at a specific class of structurally out-of-distribution tasks unless they possess genuine experiential autonomy. The paper offers four axioms, five testable predictions, and a benchmark proposal, the Relational Reversal Task, as a way to make the framework vulnerable to empirical failure. It is presented not as established theory, but as a speculative and falsifiable proposal about the relationship among consciousness, qualitative integration, and intelligence. Note: This paper was developed through an iterative process involving the author and AI language models. The foundational thesis, core arguments, axioms, and theoretical commitments originated with the author. AI tools assisted with literature review, drafting, organization, and adversarial critique. The author takes full responsibility for the final claims.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzenodo.org%2Fstatic%2Ffavicon.ico" width="50" height="50"&gt;
          zenodo.org
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;v2.1.0 updated with references to A.N. Whitehead&lt;/p&gt;

&lt;p&gt;This paper proposes an exploratory framework in which consciousness and qualia are treated as the same phenomenon at different degrees of integration. On this view, minimal qualia are minimal consciousness, while macro-awareness is a more highly integrated and reportable form of the same underlying process. The paper further advances the hypothesis that intelligence, understood as flexible adaptation to structurally novel situations, emerges only once qualitative integration reaches sufficient depth.&lt;/p&gt;

&lt;p&gt;The framework is developed through a dual-aspect interpretation of physically instantiated processing and introduces the idea of autonomous experiential synthesis: a history-bearing, environmentally coupled process in which past experience shapes present processing in an open-ended way. The paper contrasts this with current AI systems built on fixed architectures and frozen learned parameters, and proposes that such systems may fail at a specific class of structurally out-of-distribution tasks unless they possess genuine experiential autonomy.&lt;/p&gt;

&lt;p&gt;The paper offers four axioms, five testable predictions, and a benchmark proposal, the Relational Reversal Task, as a way to make the framework vulnerable to empirical failure. It is presented not as established theory, but as a speculative and falsifiable proposal about the relationship among consciousness, qualitative integration, and intelligence.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>consciousness</category>
      <category>science</category>
    </item>
  </channel>
</rss>
