<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://mcclowes.com/blog</id>
    <title>@mcclowes Blog</title>
    <updated>2026-01-06T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://mcclowes.com/blog"/>
    <subtitle>@mcclowes Blog</subtitle>
    <icon>https://mcclowes.com/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Code Frontmatter: An Index for AI?]]></title>
        <id>https://mcclowes.com/blog/2026/01/06/code-frontmatter</id>
        <link href="https://mcclowes.com/blog/2026/01/06/code-frontmatter"/>
        <updated>2026-01-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[When an AI assistant explores your codebase, it reads files. Each file costs tokens. A lot of that reading turns out to be unnecessary—the AI loads a file just to discover it's irrelevant.]]></summary>
        <content type="html"><![CDATA[<p>When an AI assistant explores your codebase, it reads files. Each file costs tokens. A lot of that reading turns out to be unnecessary—the AI loads a file just to discover it's irrelevant.</p>
<p>I've been experimenting with a simple idea: add a YAML frontmatter block to the top of each file.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * purpose: Fetches player data from FPL API</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * related:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./search/route.ts - paginated version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> */</span><br></span></code></pre></div></div>
<p>The theory is that the AI reads just the first 15-20 lines of each file, builds a rough map of the codebase, and only loads full files when needed.</p>
<p>On paper, the numbers look good. A 300-line file's frontmatter might use ~50 tokens versus ~1500 for the full file. But whether that translates to meaningful gains in practice—fewer wasted reads, better file selection—is less clear. It depends on how well the AI actually uses the information, and whether the overhead of maintaining frontmatter is worth it.</p>
<p>There's a secondary benefit: it doubles as documentation. Unlike comments buried in the code, frontmatter sits at the entrance.</p>
<p>I'm not convinced yet. It's extra friction on every file, and the actual efficiency gains are hard to measure. A benchmarking test I conducted seemed to show the context window consumption reduced to 40% of it's previous size, much smaller than the theoretical. But it's an interesting direction—treating code like a searchable index rather than a pile of files to grep through.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="a-fuller-example">A fuller example<a href="https://mcclowes.com/blog/2026/01/06/code-frontmatter#a-fuller-example" class="hash-link" aria-label="Direct link to A fuller example" title="Direct link to A fuller example" translate="no">​</a></h2>
<p>Here's what this might look like across a real project—a serverless data pipeline that mirrors the Fantasy Premier League <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span> into Postgres:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// app/api/cron/route.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token doc-comment comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * purpose: Cron endpoint triggered by GitHub Actions hourly</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * inputs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - Authorization header (cron secret)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * outputs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - Triggers data collection job</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * related:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./lib/collector.ts - actual collection logic</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./lib/db/jobs.ts - job tracking</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> */</span><br></span></code></pre></div></div>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// lib/collector.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token doc-comment comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * purpose: Fetches fresh data from FPL API and writes snapshots</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * inputs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - None (fetches from external API)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * outputs:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - Immutable snapshots in player_snapshots table</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - Updated master tables (players, teams)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * related:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./db/snapshots.ts - snapshot storage</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./db/players.ts - player master table</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> *   - ./fpl-client.ts - API client</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * domain: FPL data is time-sensitive; snapshots preserve history</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> * ---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token doc-comment comment" style="color:rgb(98, 114, 164)"> */</span><br></span></code></pre></div></div>
<p>The pattern particularly starts to pay off when files reference each other. An AI looking for "how team optimization works" can read the headers, see that <code>genetic.ts</code> depends on <code>fitness.ts</code> for scoring, and load only the relevant files. Without frontmatter, it would likely load the entire <code>lib/</code> directory to understand the relationships.</p>
<p>Obviously this requires some maintenance to keep the frontmatter fresh/accurate, but Claude Code helps do that.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="ai" term="ai"/>
        <category label="coding" term="coding"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Vibe]]></title>
        <id>https://mcclowes.com/blog/2025/12/19/vibe</id>
        <link href="https://mcclowes.com/blog/2025/12/19/vibe"/>
        <updated>2025-12-19T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<iframe style="border-radius:12px" src="https://open.spotify.com/embed/track/0IIXsXPq6inf9o62V1iAh0?utm_source=generator" width="100%" height="352" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
<iframe width="560" height="315" src="https://www.youtube.com/embed/6EZVlM_zaBU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" loading="lazy"></iframe>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="music" term="music"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Lea: A programming language that reads like you think]]></title>
        <id>https://mcclowes.com/blog/2025/12/11/lea</id>
        <link href="https://mcclowes.com/blog/2025/12/11/lea"/>
        <updated>2025-12-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I built a programming language. It's called Lea, and it's designed around one core belief: code should flow the way your brain does—left to right, step by step.]]></summary>
        <content type="html"><![CDATA[<p>I built a programming language. It's called <a href="https://github.com/mcclowes/lea" target="_blank" rel="noopener noreferrer" class="">Lea</a>, and it's designed around one core belief: code should flow the way your brain does—left to right, step by step.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="why-another-language">Why another language?<a href="https://mcclowes.com/blog/2025/12/11/lea#why-another-language" class="hash-link" aria-label="Direct link to Why another language?" title="Direct link to Why another language?" translate="no">​</a></h2>
<p>Most programming languages force you to read inside-out. Consider filtering and transforming a list in JavaScript:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token console class-name">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">reduce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">filter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">numbers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token parameter">x</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> x </span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token number">2</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token parameter">x</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> x </span><span class="token operator">*</span><span class="token plain"> x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token parameter"> b</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> a </span><span class="token operator">+</span><span class="token plain"> b</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre></div></div>
<p>Your eyes jump to the innermost function, then work outward. It's backwards from how we naturally describe the process: "take the numbers, filter them, square them, sum them up."</p>
<p>Lea fixes this with pipes:</p>
<div class="language-lea codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-lea codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">let numbers = [1, 2, 3, 4, 5]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">numbers</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  /&gt; filter((x) -&gt; x &gt; 2)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  /&gt; map((x) -&gt; x * x)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  /&gt; reduce(0, (acc, x) -&gt; acc + x)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  /&gt; print  -- 50</span><br></span></code></pre></div></div>
<p>Data flows left-to-right through transformations. You read it exactly as you'd explain it.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="resilience-as-syntax">Resilience as syntax<a href="https://mcclowes.com/blog/2025/12/11/lea#resilience-as-syntax" class="hash-link" aria-label="Direct link to Resilience as syntax" title="Direct link to Resilience as syntax" translate="no">​</a></h2>
<p>The other thing that always frustrated me: handling retries, timeouts, and caching in production code requires so much boilerplate. In Lea, these are first-class language features through decorators:</p>
<div class="language-lea codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-lea codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">let fetchUser = (id) -&gt; http.get("/users/" ++ id)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  #retry(3)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  #timeout(1000)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  #memo</span><br></span></code></pre></div></div>
<p>No wrapper functions. No importing retry libraries. The resilience behaviour is declared right where the function is defined.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-philosophy">The philosophy<a href="https://mcclowes.com/blog/2025/12/11/lea#the-philosophy" class="hash-link" aria-label="Direct link to The philosophy" title="Direct link to The philosophy" translate="no">​</a></h2>
<p>Lea occupies a specific niche: functional scripting with built-in resilience. It's designed for the kind of code that glues systems together—data pipelines, <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span> orchestration, backend automation.</p>
<p>The goal isn't to replace JavaScript or Python everywhere. It's to make certain kinds of code dramatically more readable and robust.</p>
<p>Some design choices:</p>
<ul>
<li class=""><strong>Immutability by default</strong> - <code>let</code> for constants, <code>maybe</code> for the rare mutable variable</li>
<li class=""><strong>Optional typing</strong> - Start dynamic, add types gradually with <code>:: Int</code> annotations</li>
<li class=""><strong>Pipeline-first</strong> - The <code>/&gt;</code> operator isn't an afterthought; it's the primary way to compose operations</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="current-state">Current state<a href="https://mcclowes.com/blog/2025/12/11/lea#current-state" class="hash-link" aria-label="Direct link to Current state" title="Direct link to Current state" translate="no">​</a></h2>
<p>Lea is still experimental. It has a tree-walk interpreter written in TypeScript, a VS Code extension for syntax highlighting, and a REPL for playing around. It's perfect for learning about language design or prototyping data transformation logic.</p>
<p>Is it production-ready? No. But that's not really the point. Sometimes you build things to explore ideas, to see what programming could feel like if we made different choices.</p>
<p>If you're curious, check out the <a href="https://github.com/mcclowes/lea" target="_blank" rel="noopener noreferrer" class="">GitHub repo</a> or use <a href="https://lea.mcclowes.com/" target="_blank" rel="noopener noreferrer" class="">the playground</a>. Run the REPL. Try writing some pipelines. Let me know what you think.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> clone https://github.com/mcclowes/lea.git</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> lea</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">npm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">npm</span><span class="token plain"> run repl</span><br></span></code></pre></div></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="projects" term="projects"/>
        <category label="dev" term="dev"/>
        <category label="programming languages" term="programming languages"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Prefix]]></title>
        <id>https://mcclowes.com/blog/2025/11/18/prefix</id>
        <link href="https://mcclowes.com/blog/2025/11/18/prefix"/>
        <updated>2025-11-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Prefix game screenshot]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Prefix game screenshot" src="https://mcclowes.com/assets/images/prefix-c1367524adc13ffa95dbbfff2fdb8fe3.png" width="2924" height="1766" class="img_ev3q"></p>
<p>I've been working on a new game called Prefix.</p>
<p>You have to guess the word of the day (usually a 5-12 letter word). You start with the first letter revealed. By guessing words that fit given the letters revealed so far, you gradually arrive at the right answer.</p>
<p>You can play it <a href="https://prefix.mcclowes.com/" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/puzzles/prefix-o-1.PNG" alt="Image 1 of 3" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/puzzles/prefix-o-2.PNG" alt="Image 2 of 3" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/puzzles/prefix-o-3.PNG" alt="Image 3 of 3" class="image_i3UB markdown-img"></p></div></div>
<p>It looks a bit like Wordle, but it's actually an attempt to make a 1-player version of the fantastic word game <a href="https://www.ludozofi.com/home/games/contact/" target="_blank" rel="noopener noreferrer" class="">Contact</a>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-play">How to play<a href="https://mcclowes.com/blog/2025/11/18/prefix#how-to-play" class="hash-link" aria-label="Direct link to How to play" title="Direct link to How to play" translate="no">​</a></h3>
<div style="position:relative;padding-bottom:56.25%;height:0"><iframe src="https://www.loom.com/embed/748a8362041e4ba1b8d57315926be0f4" title="Embedded Loom Video" frameborder="0" allowfullscreen="" loading="lazy" style="position:absolute;top:0;left:0;width:100%;height:100%"></iframe></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="game design" term="game design"/>
        <category label="dev" term="dev"/>
        <category label="gaming" term="gaming"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Paintings November 25]]></title>
        <id>https://mcclowes.com/blog/2025/11/12/paintings-november-25</id>
        <link href="https://mcclowes.com/blog/2025/11/12/paintings-november-25"/>
        <updated>2025-11-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<Carousel]]></summary>
        <content type="html"><![CDATA[<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/isa-4.jpeg" alt="Image 1 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/isa-3.jpeg" alt="Image 2 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/isa-2.jpeg" alt="Image 3 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/isa-1.jpeg" alt="Image 4 of 4" class="image_i3UB markdown-img"></p></div></div>
<p>WIP</p>
<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/cat.jpeg" alt="Image 1 of 3" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/flowers.jpeg" alt="Image 2 of 3" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-nov-25/isa-leaves.jpeg" alt="Image 3 of 3" class="image_i3UB markdown-img"></p></div></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="art" term="art"/>
        <category label="painting" term="painting"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[PWAs could still be good]]></title>
        <id>https://mcclowes.com/blog/2025/11/10/pwas-are-almost-good</id>
        <link href="https://mcclowes.com/blog/2025/11/10/pwas-are-almost-good"/>
        <updated>2025-11-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I just upgraded my Fantasy Premier League helper into a Progressive Web App (PWA).]]></summary>
        <content type="html"><![CDATA[<p>I just upgraded my <a href="https://mcclowes.com/blog/2025/11/04/what-the-fpl" target="_blank" rel="noopener noreferrer" class="">Fantasy Premier League helper</a> into a Progressive Web App (<span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span>).</p>
<p>I haven't really touched the tech since 2017, and my main memory of them ws encountering issues with them caching code and breaking sites (which is still a risk but was also probably mainly inexperience). Looking into them 8 years later, I was surprised to see...</p>
<p>###&nbsp;1. It's so fully featured</p>
<p>And the features are pretty easy to set up.</p>
<p>You can see everything a <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span> can do here: <a href="https://whatpwacando.today/" target="_blank" rel="noopener noreferrer" class="">https://whatpwacando.today/</a></p>
<p>I've found implementing notifications the <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span> way pretty nice and the storage features are great. For instance, having offline-access to my full FPL database is great, when the official FPL doesn't work offline.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="2-iphone-supports-so-little-of-it">2. iPhone supports so little of it<a href="https://mcclowes.com/blog/2025/11/10/pwas-are-almost-good#2-iphone-supports-so-little-of-it" class="hash-link" aria-label="Direct link to 2. iPhone supports so little of it" title="Direct link to 2. iPhone supports so little of it" translate="no">​</a></h3>
<p>If you go through each of those features on your mobile device, you'll probably see that most of them, especialy the cool most native feeling things, aren't supported.</p>
<p>Given <a href="https://www.youtube.com/watch?v=oUsXoz-wbs4" target="_blank" rel="noopener noreferrer" class="">Steve Jobs was such a PWA-believer</a>, it's disappointing that Apple is so behind the state-of-the-art in <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span> support (though obviously Apple has plenty of reasons to fear exposing near-native app experiences without the need to go through app certification).</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="3-its-easy-to-set-up-in-your-project">3. It's easy to set up in your project<a href="https://mcclowes.com/blog/2025/11/10/pwas-are-almost-good#3-its-easy-to-set-up-in-your-project" class="hash-link" aria-label="Direct link to 3. It's easy to set up in your project" title="Direct link to 3. It's easy to set up in your project" translate="no">​</a></h3>
<p>If you've already done the hard part of implementing an app, the pretty boilerplated work of retrofitting your web app into a <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span> is trivial for Claude/Cursor.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="but-no-one-knows-how-to-install-them">...but no one knows (how) to install them<a href="https://mcclowes.com/blog/2025/11/10/pwas-are-almost-good#but-no-one-knows-how-to-install-them" class="hash-link" aria-label="Direct link to ...but no one knows (how) to install them" title="Direct link to ...but no one knows (how) to install them" translate="no">​</a></h3>
<p>Ultimately though, very few people ever 'Add to home screen' on iPhone (or know it's an option), and even less see the 'Install app' icon in the Chrome URL bar. It's so hidden away in these UIs.</p>
<p>It was a nice reminder to me to see what apps I use regularly already have <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#pwa" class="glossaryTerm_WE8X" aria-describedby="tooltip-pwa">PWA</a><span id="tooltip-pwa" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>PWA</strong> <!-- -->A Progressive Web App (PWA) is a type of web application that is built with progressive enhancement, rather than traditional web development techniques. PWAs are designed to be fast, reliable, and installable on a user's device.</span></span> functionality - <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#vercel" class="glossaryTerm_WE8X" aria-describedby="tooltip-vercel">Vercel</a><span id="tooltip-vercel" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>vercel</strong> <!-- -->Vercel is a cloud platform for frontend developers. It is used to deploy and host websites and web applications.</span></span>, youTube, and more. It can be really nice to have a dedicated window, dock presence, etc. for your go-to web sites, and remove the clutter of the browser.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="dev" term="dev"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[What the FPL!?]]></title>
        <id>https://mcclowes.com/blog/2025/11/04/what-the-fpl</id>
        <link href="https://mcclowes.com/blog/2025/11/04/what-the-fpl"/>
        <updated>2025-11-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I've been working on a revamped version of my Fantasy Premier League helper tool, What the FPL!? I initially built the first version back in 2019, and this version is a complete rebuild with a much more solid technical foundation. The original version used a simpler predicted points algorithm, but this rebuild takes a more sophisticated approach.]]></summary>
        <content type="html"><![CDATA[<p>I've been working on a revamped version of my <a href="https://fantasy.premierleague.com/" target="_blank" rel="noopener noreferrer" class="">Fantasy Premier League</a> helper tool, <strong>What the FPL!?</strong> I initially built the <a class="" href="https://mcclowes.com/blog/2019/01/15/what-the-fpl">first version back in 2019</a>, and this version is a complete rebuild with a much more solid technical foundation. The original version used a simpler predicted points algorithm, but this rebuild takes a more sophisticated approach.</p>
<p>The project is a serverless data pipeline that mirrors the Fantasy Premier League public <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span> into a Supabase Postgres database. It's built with Next.js App Router and runs on <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#vercel" class="glossaryTerm_WE8X" aria-describedby="tooltip-vercel">Vercel</a><span id="tooltip-vercel" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>vercel</strong> <!-- -->Vercel is a cloud platform for frontend developers. It is used to deploy and host websites and web applications.</span></span>, where scheduled GitHub Actions workflows invoke the collection routines through <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span> routes. The collected data is stored as immutable snapshots, so I can analyze historical trends and make better decisions about my team.</p>
<p><img decoding="async" loading="lazy" alt="What the FPL!? dashboard showing player data" src="https://mcclowes.com/assets/images/wtf1-a9a31639142f41cbc49487bf544f6c15.png" width="3326" height="1892" class="img_ev3q"></p>
<p>The architecture is straightforward: GitHub Actions hits a cron endpoint every hour, which triggers the data collector. The collector fetches fresh data from the FPL <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span>, writes snapshots, and updates master tables. Everything is tracked in Supabase with job history, so I can see what's happening and when.</p>
<p><img decoding="async" loading="lazy" alt="Player statistics and gameweek information" src="https://mcclowes.com/assets/images/wtf2-7f48001af6f70c88e63a216292c9ee9d.png" width="2060" height="1744" class="img_ev3q"></p>
<p>The dashboard gives me a clean view of players, teams, and gameweek data. I can filter by position, team, status, and see historical trends through the snapshot system. But the real power of the tool comes from its team optimization features.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="team-optimization-with-custom-metrics">Team optimization with custom metrics<a href="https://mcclowes.com/blog/2025/11/04/what-the-fpl#team-optimization-with-custom-metrics" class="hash-link" aria-label="Direct link to Team optimization with custom metrics" title="Direct link to Team optimization with custom metrics" translate="no">​</a></h2>
<p>What the FPL!? helps you optimize your team using my own custom metrics, including <strong>expectation-weighted fitness</strong>. This metric goes beyond simple point totals by weighting player performance against their expected output based on their position and upcoming fixture difficulty. It gives you a clearer picture of which players are truly outperforming their cost and situation.</p>
<p>The optimization engine uses a genetic algorithm to find a (probably) optimal team composition within your budget constraints. It starts with a population of random team configurations, then evolves them over multiple generations by:</p>
<ol>
<li class=""><strong>Evaluating fitness</strong>: Each team is scored using the custom metrics, including expectation-weighted fitness</li>
<li class=""><strong>Selecting parents</strong>: The best-performing teams are selected to breed the next generation</li>
<li class=""><strong>Crossover</strong>: Combining successful team configurations to create new combinations</li>
<li class=""><strong>Mutation</strong>: Introducing random changes to explore new possibilities</li>
<li class=""><strong>Iteration</strong>: Repeating this process until the algorithm converges on optimal solutions</li>
</ol>
<p>This approach lets you explore thousands of team combinations automatically, finding lineups you might never have considered manually. You can specify constraints like budget, required players, and formation preferences, and the algorithm will find the best team that meets those requirements.</p>
<p><img decoding="async" loading="lazy" alt="Historical data and player snapshots" src="https://mcclowes.com/assets/images/wtf3-716e5cac0ac34d267fe6a5c45d978eda.png" width="2030" height="1892" class="img_ev3q"></p>
<p>The whole thing is open source and available on GitHub, with a full <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#rest" class="glossaryTerm_WE8X" aria-describedby="tooltip-rest">REST</a><span id="tooltip-rest" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>REST</strong> <!-- -->An architectural style for designing networked applications. REST uses HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources identified by URLs.</span></span> <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span> for querying current and historical data. It's been a fun project to rebuild with modern tooling, and it's already helping me make better picks this season.</p>
<p>If you're curious about the original 2019 version, you can read about it <a class="" href="https://mcclowes.com/blog/2019/01/15/what-the-fpl">here</a>.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="dev" term="dev"/>
        <category label="fantasy football" term="fantasy football"/>
        <category label="fpl" term="fpl"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A glossary plugin for Docusaurus]]></title>
        <id>https://mcclowes.com/blog/2025/10/03/docusaurus-plugin-glossary</id>
        <link href="https://mcclowes.com/blog/2025/10/03/docusaurus-plugin-glossary"/>
        <updated>2025-10-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I've always been frustrated by how technical documentation often assumes readers know all the jargon. Whenever I build a site with Docusaurus, I wanted a way to automatically link and explain key terms, so readers can hover to see definitions without breaking their flow.]]></summary>
        <content type="html"><![CDATA[<a class="card_IGiA" href="https://github.com/mcclowes/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer"><div class="header_c7pi"><div class="repoName_SPia"><span class="githubIcon_jJyO" aria-hidden="true"></span>mcclowes/docusaurus-plugin-glossary</div><span class="badge_pz_n">Loading…</span></div><p class="description_WGYz">Fetching repository details…</p><div class="metaRow_dMDu"><span class="metaItem_kXQw" title="Stars">⭐ <!-- -->0</span><span class="metaItem_kXQw" title="Forks">🍴 <!-- -->0</span></div><svg class="githubLogo_duNS" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.603-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0112 6.836c.85.004 1.705.114 2.504.336 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z" fill="currentColor"></path></svg></a>
<p>I've always been frustrated by how technical documentation often assumes readers know all the <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#jargon" class="glossaryTerm_WE8X" aria-describedby="tooltip-jargon">jargon</a><span id="tooltip-jargon" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>jargon</strong> <!-- -->Technical jargon is a type of language that is used to describe technical concepts in a precise and concise manner. It is often used in scientific, engineering, and technical fields.</span></span>. Whenever I build a site with <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#docusaurus" class="glossaryTerm_WE8X" aria-describedby="tooltip-docusaurus">Docusaurus</a><span id="tooltip-docusaurus" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>Docusaurus</strong> <!-- -->A static site generator for React-based websites. Docusaurus is used to build this website.</span></span>, I wanted a way to automatically link and explain key terms, so readers can hover to see definitions without breaking their flow.</p>
<p>There used to be <a href="https://github.com/grnet/docusaurus-terminology" target="_blank" rel="noopener noreferrer" class="">plugins for this</a>, but these open source projects all went stale.</p>
<p>That's why I built <a href="https://github.com/mcclowes/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer" class="">docusaurus-plugin-glossary</a> - a plugin that automatically detects glossary terms in your markdown content and turns them into interactive tooltips.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-solution">The solution<a href="https://mcclowes.com/blog/2025/10/03/docusaurus-plugin-glossary#the-solution" class="hash-link" aria-label="Direct link to The solution" title="Direct link to The solution" translate="no">​</a></h2>
<p>The plugin does two things well:</p>
<ol>
<li class="">
<p><strong>Interactive tooltips</strong>: Hover over any linked term (like this - <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#docusaurus" class="glossaryTerm_WE8X" aria-describedby="tooltip-docusaurus">Docusaurus</a><span id="tooltip-docusaurus" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>Docusaurus</strong> <!-- -->A static site generator for React-based websites. Docusaurus is used to build this website.</span></span>) and see its definition instantly. Click to navigate to the full glossary page for related terms.</p>
</li>
<li class="">
<p><strong>Automatic term detection</strong>: It scans your markdown files and automatically links glossary terms with a subtle dotted underline. No manual markup required.</p>
</li>
</ol>
<p>The magic happens through a remark plugin that processes your markdown before it hits the browser. It respects word boundaries (so "<span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#api" class="glossaryTerm_WE8X" aria-describedby="tooltip-api">API</a><span id="tooltip-api" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>API</strong> <!-- -->A set of rules and protocols that allows different software applications to communicate with each other. APIs define the methods and data formats that applications can use to request and exchange information.</span></span>" doesn't match "application"), and it smartly skips terms inside code blocks, links, or existing components.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="technical-highlights">Technical highlights<a href="https://mcclowes.com/blog/2025/10/03/docusaurus-plugin-glossary#technical-highlights" class="hash-link" aria-label="Direct link to Technical highlights" title="Direct link to Technical highlights" translate="no">​</a></h2>
<ul>
<li class="">Built as a proper <span class="glossaryTermWrapper_tlxd"><a href="https://mcclowes.com/glossary#docusaurus" class="glossaryTerm_WE8X" aria-describedby="tooltip-docusaurus">Docusaurus</a><span id="tooltip-docusaurus" class="tooltip_MOZH tooltipTop_HWYP tooltipFloating_XSLb" role="tooltip"><strong>Docusaurus</strong> <!-- -->A static site generator for React-based websites. Docusaurus is used to build this website.</span></span> plugin following their plugin architecture</li>
<li class="">Uses remark to process markdown at build time</li>
<li class="">React components for the tooltip UI and glossary page</li>
<li class="">Full TypeScript support</li>
<li class="">Configurable term detection with sensible defaults</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="try-it-out">Try it out<a href="https://mcclowes.com/blog/2025/10/03/docusaurus-plugin-glossary#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<p>You can install it from npm:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">npm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> docusaurus-plugin-glossary</span><br></span></code></pre></div></div>
<a class="card_qYam" href="https://www.npmjs.com/package/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer"><div class="header_DOP2"><div class="packageName_Eatc"><span class="npmIcon_pFcu" aria-hidden="true">📦</span>docusaurus-plugin-glossary</div><span class="badge_FpIn">Loading…</span></div><p class="description_Xxle">Fetching package details…</p><div class="metaRow_C9rb"></div><svg class="npmLogo_xLEc" viewBox="0 0 27.23 27.23" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><rect width="27.23" height="27.23" rx="2" fill="#CB3837"></rect><polygon fill="#fff" points="5.8 21.75 13.66 21.75 13.67 9.98 17.59 9.98 17.58 21.76 21.51 21.76 21.52 6.06 5.82 6.04 5.8 21.75"></polygon></svg></a>
<p>Or check out the <a href="https://github.com/mcclowes/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer" class="">GitHub repository</a> for documentation, examples, and source code.</p>
<hr>
<p><strong>Links:</strong></p>
<ul>
<li class=""><a href="https://github.com/mcclowes/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer" class="">GitHub Repository</a></li>
<li class=""><a href="https://www.npmjs.com/package/docusaurus-plugin-glossary" target="_blank" rel="noopener noreferrer" class="">npm Package</a></li>
<li class=""><a href="https://github.com/mcclowes/docusaurus-plugin-glossary#readme" target="_blank" rel="noopener noreferrer" class="">Documentation</a></li>
<li class=""><a href="https://github.com/mcclowes/claude-docusaurus-skills" target="_blank" rel="noopener noreferrer" class="">Claude Docusaurus Skills</a></li>
</ul>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="dev" term="dev"/>
        <category label="open source" term="open source"/>
        <category label="documentation" term="documentation"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Augury]]></title>
        <id>https://mcclowes.com/blog/2025/09/12/augury</id>
        <link href="https://mcclowes.com/blog/2025/09/12/augury"/>
        <updated>2025-09-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A poem]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="A poem" src="https://mcclowes.com/assets/images/augury-53d00ca0988c2f220480a01ce2b1fa2d.jpeg" width="4284" height="3039" class="img_ev3q"></p>
<p>How cool is <a href="https://goodpress.co.uk/pages/the-paper" target="_blank" rel="noopener noreferrer" class="">Good Press</a>?!</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="writing" term="writing"/>
        <category label="poetry" term="poetry"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Election prediction and poll aggregation]]></title>
        <id>https://mcclowes.com/blog/2025/09/12/elections</id>
        <link href="https://mcclowes.com/blog/2025/09/12/elections"/>
        <updated>2025-09-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I've been working on an MRP-based election modal and poll aggregation web app.]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" src="https://mcclowes.com/assets/images/bo3-f3764262662efbe58a2fc3c69afc808c.png" width="3098" height="1442" class="img_ev3q"></p>
<p>I've been working on an MRP-based election modal and poll aggregation web app.</p>
<p><img decoding="async" loading="lazy" src="https://mcclowes.com/assets/images/bo1-2ea6f7695d01c7a3ad16b0db16fa8d8c.png" width="3140" height="1888" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://mcclowes.com/assets/images/bo2-8728cdcbfcbbda7fe765b8befc62d778.png" width="3028" height="1886" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://mcclowes.com/assets/images/bo4-1057e9e0c61ad8a24a57b29d9ac9eaf3.png" width="2964" height="1370" class="img_ev3q"></p>
<p>Let me know if you want access!</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="dev" term="dev"/>
        <category label="politics" term="politics"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Ode to Heather Christle]]></title>
        <id>https://mcclowes.com/blog/2025/09/01/heather-christle</id>
        <link href="https://mcclowes.com/blog/2025/09/01/heather-christle"/>
        <updated>2025-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I own like six nail clippers]]></summary>
        <content type="html"><![CDATA[<p>I own like six nail clippers<br>
<!-- -->and I honestly can’t<br>
<!-- -->find<br>
<!-- -->even one</p>
<p>Loved <a href="https://www.littlebrown.co.uk/titles/heather-christle/paper-crown/9781472158673/" target="_blank" rel="noopener noreferrer" class="">Paper Crown</a>. Great, fun, relatable poetry.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="writing" term="writing"/>
        <category label="poetry" term="poetry"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Perfect knowledge ruins fun and creativity]]></title>
        <id>https://mcclowes.com/blog/2025/08/13/perfect-knowledge-ruins-fun</id>
        <link href="https://mcclowes.com/blog/2025/08/13/perfect-knowledge-ruins-fun"/>
        <updated>2025-08-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In my earlier post, Shakespeare and Dataism, I argued that incomplete information creates drama, surprise, and joy. Perfect information flattens experience.]]></summary>
        <content type="html"><![CDATA[<p>In my earlier post, <a class="" href="https://mcclowes.com/blog/2025/06/23/shakespeare-and-dataism">Shakespeare and Dataism</a>, I argued that incomplete information creates drama, surprise, and joy. Perfect information flattens experience.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="card-games-solved-metas">Card games: solved metas<a href="https://mcclowes.com/blog/2025/08/13/perfect-knowledge-ruins-fun#card-games-solved-metas" class="hash-link" aria-label="Direct link to Card games: solved metas" title="Direct link to Card games: solved metas" translate="no">​</a></h3>
<p>With ubiquitous deck trackers and shared analytics, card game communities quickly converge on optimal lists and lines. Like an optimisation problem, the search space collapses to a few dominant solutions. Experimentation becomes a tax: novelty is punished because you already know it underperforms. You can hear streamers say they “can’t do anything fun” without tanking their win rate, even when entertainment is the goal.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="music-datadriven-sameness">Music: data‑driven sameness<a href="https://mcclowes.com/blog/2025/08/13/perfect-knowledge-ruins-fun#music-datadriven-sameness" class="hash-link" aria-label="Direct link to Music: data‑driven sameness" title="Direct link to Music: data‑driven sameness" translate="no">​</a></h3>
<p>Streaming dashboards reveal what “works,” and modern tools make it trivial to replicate those sounds. Intros get shorter, hooks arrive earlier, and timbres cluster around proven palettes. When everyone optimises for the same metrics, we rush toward homogeneity.</p>
<p>If ignorance is the fuel of play, then a little fog of war is a design feature, not a bug. Keep some hidden information, time‑delayed feedback, or friction in the loop, and the space for creativity reopens.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="thinking" term="thinking"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Holographic cards]]></title>
        <id>https://mcclowes.com/blog/2025/08/10/holocards</id>
        <link href="https://mcclowes.com/blog/2025/08/10/holocards"/>
        <updated>2025-08-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I wanted to recreate the feel of holographic trading cards on the web, using CSS masks, blend modes, and a bit of perspective.]]></summary>
        <content type="html"><![CDATA[<p>I wanted to recreate the feel of holographic trading cards on the web, using CSS masks, blend modes, and a bit of perspective.</p>
<p>Below is a small grid of cards using images I generated with ChatGPT. Move your mouse (or touch) to tilt and reveal the foil. Use the toggle to switch between different mask modes. For each, I've created an non-holo overlay manually, making some elements sit apart from the holographic card elements.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="menagerie">Menagerie<a href="https://mcclowes.com/blog/2025/08/10/holocards#menagerie" class="hash-link" aria-label="Direct link to Menagerie" title="Direct link to Menagerie" translate="no">​</a></h3>
<div class="wrapper_Hulh"><div class="grid_gmKE"><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Caoman"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo1.png" alt="Caoman"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo1.png);mask-image:url(/img/posts/holocards/holo1.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo1-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Caoman</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Frostpup"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo7.png" alt="Frostpup"></div><div class="foil_M1uQ paletteCool_wNia alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo7.png);mask-image:url(/img/posts/holocards/holo7.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo7-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Frostpup</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Lantowl"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo2.png" alt="Lantowl"></div><div class="foil_M1uQ paletteElectric_eVR1 refinedAlpha_VK7a" style="-webkit-mask-image:url(/img/posts/holocards/holo2.png);mask-image:url(/img/posts/holocards/holo2.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo2-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Lantowl</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Spineedle"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo3.png" alt="Spineedle"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo3.png);mask-image:url(/img/posts/holocards/holo3.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo3-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Spineedle</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Armola"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/armola.png" alt="Armola"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/armola.png);mask-image:url(/img/posts/holocards/armola.png)" aria-hidden="true"></div><div class="shine_jkdX shineLinear_TL80" aria-hidden="true"></div></div><div class="caption_MjQ1">Armola</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Ghoulweed"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/ghoulweed.png" alt="Ghoulweed"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/ghoulweed.png);mask-image:url(/img/posts/holocards/ghoulweed.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div></div><div class="caption_MjQ1">Ghoulweed</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Kelpless"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/kelpless.png" alt="Kelpless"></div><div class="foil_M1uQ paletteClassic_CQLM refinedAlpha_VK7a" style="-webkit-mask-image:url(/img/posts/holocards/kelpless.png);mask-image:url(/img/posts/holocards/kelpless.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div></div><div class="caption_MjQ1">Kelpless</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Wombatik"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo6.png" alt="Wombatik"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo6.png);mask-image:url(/img/posts/holocards/holo6.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo6-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Wombatik</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Kitlune"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo5.png" alt="Kitlune"></div><div class="foil_M1uQ paletteCool_wNia refinedAlpha_VK7a" style="-webkit-mask-image:url(/img/posts/holocards/holo5.png);mask-image:url(/img/posts/holocards/holo5.png)" aria-hidden="true"></div><div class="shine_jkdX shineLinear_TL80" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo5-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Kitlune</div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="scrapyard">Scrapyard<a href="https://mcclowes.com/blog/2025/08/10/holocards#scrapyard" class="hash-link" aria-label="Direct link to Scrapyard" title="Direct link to Scrapyard" translate="no">​</a></h3>
<div class="wrapper_Hulh"><div class="grid_gmKE"><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 1"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-1.png" alt="Holo scrap 1"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-1.png);mask-image:url(/img/posts/holocards/holo-scrap-1.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-1-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 1</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 2"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-2.png" alt="Holo scrap 2"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-2.png);mask-image:url(/img/posts/holocards/holo-scrap-2.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-2-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 2</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 3"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-3.png" alt="Holo scrap 3"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-3.png);mask-image:url(/img/posts/holocards/holo-scrap-3.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-3-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 3</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 4"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-4.png" alt="Holo scrap 4"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-4.png);mask-image:url(/img/posts/holocards/holo-scrap-4.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-4-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 4</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 5"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-5.png" alt="Holo scrap 5"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-5.png);mask-image:url(/img/posts/holocards/holo-scrap-5.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-5-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 5</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 6"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-6.png" alt="Holo scrap 6"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-6.png);mask-image:url(/img/posts/holocards/holo-scrap-6.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-6-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 6</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 7"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-7.png" alt="Holo scrap 7"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-7.png);mask-image:url(/img/posts/holocards/holo-scrap-7.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-7-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 7</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo scrap 8"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-scrap-8.png" alt="Holo scrap 8"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-scrap-8.png);mask-image:url(/img/posts/holocards/holo-scrap-8.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-scrap-8-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo scrap 8</div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="wraestlung">Wraestlung<a href="https://mcclowes.com/blog/2025/08/10/holocards#wraestlung" class="hash-link" aria-label="Direct link to Wraestlung" title="Direct link to Wraestlung" translate="no">​</a></h3>
<div class="wrapper_Hulh"><div class="grid_gmKE"><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo punch 1"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-punch-1.png" alt="Holo punch 1"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-punch-1.png);mask-image:url(/img/posts/holocards/holo-punch-1.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-punch-1-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo punch 1</div></div><div class="item_cMRl"><div class="card_ZB_v" role="img" aria-label="Holo punch 2"><div class="art_hv5Q"><img src="https://mcclowes.com/img/posts/holocards/holo-punch-2.png" alt="Holo punch 2"></div><div class="foil_M1uQ paletteClassic_CQLM alphaMode_ZyJR" style="-webkit-mask-image:url(/img/posts/holocards/holo-punch-2.png);mask-image:url(/img/posts/holocards/holo-punch-2.png)" aria-hidden="true"></div><div class="shine_jkdX shineRadial_L_0o" aria-hidden="true"></div><img class="overlay_bYA3" src="https://mcclowes.com/img/posts/holocards/holo-punch-2-overlay.png" alt="" aria-hidden="true" draggable="false"></div><div class="caption_MjQ1">Holo punch 2</div></div></div></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="game design" term="game design"/>
        <category label="tcg" term="tcg"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Poetry competition runner up]]></title>
        <id>https://mcclowes.com/blog/2025/08/02/poetry-competition-runner-up</id>
        <link href="https://mcclowes.com/blog/2025/08/02/poetry-competition-runner-up"/>
        <updated>2025-08-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The Laughter Lines poetry competition was run by Penstricken, a literary magazine. My poem "Sunset" was one of the top three runners up.]]></summary>
        <content type="html"><![CDATA[<p>The <a href="https://penstricken.com/2025/08/02/winner-of-laughter-lines-poetry-competition-announced/" target="_blank" rel="noopener noreferrer" class="">Laughter Lines poetry competition</a> was run by <a href="https://penstricken.com/" target="_blank" rel="noopener noreferrer" class="">Penstricken</a>, a literary magazine. My poem "Sunset" was one of the top three runners up.</p>
<p><img decoding="async" loading="lazy" alt="Sunset poem" src="https://mcclowes.com/assets/images/sunset-f6bc06c6cc727e3218e10461f2d0328a.png" width="2152" height="1492" class="img_ev3q"></p>
<p>The winner was Ana Reisens with her poem "The Translated Instruction Manual for Loving", which used funny excerpts from badly translated instruction manuals to create a poetic guide for love. The other runners up were Larry Needham with "Marriage Bed of the Roses" and Jim Burns with "Tourist Trap".</p>
<p>All four poems will appear in their upcoming Autumn issue, <em>Machinery.</em></p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="poetry" term="poetry"/>
        <category label="writing" term="writing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Evolving AI art]]></title>
        <id>https://mcclowes.com/blog/2025/08/01/evolving-ai-art</id>
        <link href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art"/>
        <updated>2025-08-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This post is AI generated]]></summary>
        <content type="html"><![CDATA[<p><em>This post is AI generated</em></p>
<p>I've been working on an interesting project that combines AI, automation, and generative art. It's called <a href="https://github.com/mcclowes/ai-art" target="_blank" rel="noopener noreferrer" class="">ai-art</a>, and it's a self-evolving digital canvas that improves itself over time.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-it-does">What it does<a href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art#what-it-does" class="hash-link" aria-label="Direct link to What it does" title="Direct link to What it does" translate="no">​</a></h2>
<p>The project creates a digital artwork that evolves automatically through several mechanisms:</p>
<ol>
<li class=""><strong>Hourly random improvements</strong> - The artwork gets small changes every hour, like new shapes, color adjustments, and repositioned elements</li>
<li class=""><strong>AI-guided enhancements</strong> - When you create GitHub issues and assign them to the Copilot agent, it analyzes the current artwork and applies intelligent improvements based on the issue description</li>
<li class=""><strong>Weekly cycles</strong> - After a week, the current artwork gets archived and a new cycle begins</li>
</ol>
<p>The artwork state is stored as structured data in <code>src/artwork-state.ts</code>, and a React Canvas component renders it. The improvement scripts analyze the current state for visual balance, color harmony, and element distribution before making changes.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-automation-system">The automation system<a href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art#the-automation-system" class="hash-link" aria-label="Direct link to The automation system" title="Direct link to The automation system" translate="no">​</a></h2>
<p>The project uses GitHub Actions to run three different improvement systems in parallel:</p>
<ul>
<li class=""><strong>Artwork Evolution</strong> (every hour) - Applies random improvements using <code>improve-artwork.js</code></li>
<li class=""><strong>Codebase Evolution</strong> (every 6 hours) - Improves code quality, performance, and features using <code>improve-codebase.js</code></li>
<li class=""><strong>Copilot AI Improvements</strong> (issue-triggered) - When issues are assigned to the GitHub Copilot agent, it applies intelligent improvements based on the issue context</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="intelligent-improvements">Intelligent improvements<a href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art#intelligent-improvements" class="hash-link" aria-label="Direct link to Intelligent improvements" title="Direct link to Intelligent improvements" translate="no">​</a></h2>
<p>The system doesn't just make random changes. It applies intelligent heuristics:</p>
<ul>
<li class=""><strong>Composition principles</strong> - Uses rule of thirds and golden ratio for better visual arrangement</li>
<li class=""><strong>Color theory</strong> - Selects harmonious colors from curated palettes (warm, cool, earth, pastel, vibrant)</li>
<li class=""><strong>Visual analysis</strong> - Evaluates density, color diversity, and composition before improvements</li>
<li class=""><strong>Contextual text</strong> - Generates meaningful text based on issue titles and descriptions</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-evolving-artwork">The evolving artwork<a href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art#the-evolving-artwork" class="hash-link" aria-label="Direct link to The evolving artwork" title="Direct link to The evolving artwork" translate="no">​</a></h2>
<p>Here's a carousel showing how the artwork has evolved over time:</p>
<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-2.png" alt="Image 1 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-5.png" alt="Image 2 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-7.png" alt="Image 3 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-26.png" alt="Image 4 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-58.png" alt="Image 5 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-62.png" alt="Image 6 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-87.png" alt="Image 7 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-109.png" alt="Image 8 of 9" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/ai-art/ai-art-generation-176.png" alt="Image 9 of 9" class="image_i3UB markdown-img"></p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="why-this-matters">Why this matters<a href="https://mcclowes.com/blog/2025/08/01/evolving-ai-art#why-this-matters" class="hash-link" aria-label="Direct link to Why this matters" title="Direct link to Why this matters" translate="no">​</a></h2>
<p>This project explores several interesting concepts:</p>
<ul>
<li class=""><strong>Continuous evolution</strong> - How systems can improve themselves over time without human intervention</li>
<li class=""><strong>AI collaboration</strong> - Using GitHub Copilot not just for code, but for creative decisions</li>
<li class=""><strong>Automation boundaries</strong> - Finding the right balance between automated and manual contributions</li>
<li class=""><strong>Generative art</strong> - Creating art that evolves through both random and intelligent processes</li>
</ul>
<p>The artwork is currently at generation 176 and continues to evolve. You can see the live version at <a href="https://ai-art-sigma.vercel.app/" target="_blank" rel="noopener noreferrer" class="">ai-art-sigma.vercel.app</a>, and the full source code is available on <a href="https://github.com/mcclowes/ai-art" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>
<p>What's fascinating is watching how the combination of random mutations and intelligent improvements creates something that feels both organic and purposeful. The AI doesn't just make random changes - it analyzes the current state and applies principles of good design, color theory, and composition.</p>
<p>It's a reminder that automation doesn't have to be mindless. With the right constraints and intelligence, automated systems can create genuinely interesting and evolving work.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="ai" term="ai"/>
        <category label="art" term="art"/>
        <category label="automation" term="automation"/>
        <category label="github" term="github"/>
        <category label="projects" term="projects"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Paintings June 25]]></title>
        <id>https://mcclowes.com/blog/2025/06/27/paintings-june-25</id>
        <link href="https://mcclowes.com/blog/2025/06/27/paintings-june-25"/>
        <updated>2025-06-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<Carousel]]></summary>
        <content type="html"><![CDATA[<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-june-25/watercolor-1.jpeg" alt="Image 1 of 5" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-june-25/watercolor-2.jpeg" alt="Image 2 of 5" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-june-25/watercolor-3.jpeg" alt="Image 3 of 5" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-june-25/watercolor-4.jpeg" alt="Image 4 of 5" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-june-25/watercolor-5.jpeg" alt="Image 5 of 5" class="image_i3UB markdown-img"></p></div></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="art" term="art"/>
        <category label="painting" term="painting"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Shakespeare and Dataism]]></title>
        <id>https://mcclowes.com/blog/2025/06/23/shakespeare-and-dataism</id>
        <link href="https://mcclowes.com/blog/2025/06/23/shakespeare-and-dataism"/>
        <updated>2025-06-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[If perfect knowledge is the theoretical endpoint of human understanding—an omniscient, frictionless clarity—then perhaps its inverse, incomplete information, is the essential condition of drama, comedy, and life itself.]]></summary>
        <content type="html"><![CDATA[<p>If perfect knowledge is the theoretical endpoint of human understanding—an omniscient, frictionless clarity—then perhaps its inverse, incomplete information, is the essential condition of drama, comedy, and life itself.</p>
<p>Consider Shakespeare. Nearly every one of his plots hinges on someone not knowing something: Viola disguising herself as a man, Iago's manipulation of Othello through misperception, letters lost or forged, twins mistaken for each other. The comedy and tragedy alike arise from gaps—of knowledge, of identity, of intention. To a God-like observer, nothing surprising happens in Twelfth Night. But to its players, the unknown is everything.</p>
<p>This tension between what is known and what cannot be known isn't just theatrical, it's fun! In Sam Sorensen's game <a href="https://samsorensen.blot.im/cataphracts-design-diary-1" target="_blank" rel="noopener noreferrer" class="">Cataphracts</a>, a wargame simulating Byzantine campaigns, you can see how the real drama lies not in combat mechanics but in the fog of war—supply chains faltering, orders misunderstood, messengers ambushed. The challenge isn't what to do, but whether your intention will survive the distance between thought and action.</p>
<p><a href="https://en.wikipedia.org/wiki/Dataism" target="_blank" rel="noopener noreferrer" class="">Dataism</a> tends to frame complete information as some oerfect state, and income knowledge as a bug to be fixed. But these examples indicate it might be a little dull knowing everything.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="tech" term="tech"/>
        <category label="thinking" term="thinking"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The Bar for AI Keeps Shifting]]></title>
        <id>https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai</id>
        <link href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai"/>
        <updated>2025-05-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[During my computer science studies, our introduction to artificial intelligence didn’t begin with neural networks or robotics, but with a parade of definitions:]]></summary>
        <content type="html"><![CDATA[<p>During my computer science studies, our introduction to artificial intelligence didn’t begin with neural networks or robotics, but with a parade of definitions:</p>
<ul>
<li class=""><strong>“We call programs intelligent if they exhibit behaviors that would be regarded intelligent if they were exhibited by human beings.”</strong> — Herbert Simon</li>
</ul>
<ul>
<li class=""><strong>“AI is the study of how to make computers do things at which, at the moment, people are better.”</strong> — Elaine Rich and Kevin Knight</li>
<li class=""><strong>“AI is the science of common sense.”</strong> — Claudson Bornstein</li>
<li class=""><strong>“AI is the attempt to make computers do what people think computers cannot do.”</strong> — Douglas Baker</li>
<li class=""><strong>“The study of methods by which a computer can simulate aspects of human intelligence.”</strong> — Computers and IT, 2003</li>
<li class=""><strong>“Research scientists in AI try to get machines to exhibit behavior that we call intelligent when we observe it in human beings.”</strong> — James Slagle</li>
<li class=""><strong>“AI is a collective name for problems which we do not yet know how to solve properly by computer.”</strong> — Bertram Raphael</li>
</ul>
<p>In hindsight, these definitions reveal a persistent tension: is intelligence located in the mechanism itself, or in the results it produces? Should we evaluate a system by its inner workings, or by how it makes us feel?</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-simple-engine-behind-the-curtain">The simple engine behind the curtain<a href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai#the-simple-engine-behind-the-curtain" class="hash-link" aria-label="Direct link to The simple engine behind the curtain" title="Direct link to The simple engine behind the curtain" translate="no">​</a></h2>
<p>At their core, large language models like GPT are conceptually straightforward: they predict the next token in a sequence, guided by statistical patterns. If you trace a response step by step, you won’t find “thought” as we experience it, and certainly not self-awareness.</p>
<p>Critics seize on this mechanistic truth to dismiss these systems as mere <a href="https://en.wikipedia.org/wiki/Stochastic_parrot" target="_blank" rel="noopener noreferrer" class="">stochastic parrots</a> — mathematical engines that remix human-authored text without genuine understanding. This is true.</p>
<p>Yet these same models write working code, pass professional exams, offer effective therapy, plan complex trips, interpret poetry, draft legislation, and even play chess tutor or romantic confidant. People build relationships with these LLMs that, to them, are very real.</p>
<p>They are reshaping law, journalism, design, education, and medicine—often in profound ways. The mechanisms may be simple, but their outputs can surprise, unsettle, amuse, and even move us. For most users, intelligence isn’t a property hidden under the hood—it’s an experience at the interface.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="black-boxes-everywhere">Black boxes everywhere<a href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai#black-boxes-everywhere" class="hash-link" aria-label="Direct link to Black boxes everywhere" title="Direct link to Black boxes everywhere" translate="no">​</a></h2>
<p>We’re surrounded by systems we only half understand. You can’t describe exactly how your pancreas regulates insulin, how your car’s fuel injection works, or how a judge arrives at sentencing. You model what you don’t see—simulating beliefs, desires, and likely actions in people, institutions, and now, machines.</p>
<p>The <a href="https://en.wikipedia.org/wiki/Turing_test" target="_blank" rel="noopener noreferrer" class="">Turing Test</a> wasn’t about proving consciousness; it was about demonstrating competence. Its power lies in shifting the question of intelligence away from internal processes and toward external behavior. By that measure—intelligence as perceived—modern language models already qualify.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-danger-of-moving-the-goalposts">The danger of moving the goalposts<a href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai#the-danger-of-moving-the-goalposts" class="hash-link" aria-label="Direct link to The danger of moving the goalposts" title="Direct link to The danger of moving the goalposts" translate="no">​</a></h2>
<p>Every time AI masters a new benchmark, we redefine “intelligence” to exclude it:</p>
<ul>
<li class="">Chess was a hallmark of human ingenuity—until Deep Blue defeated Kasparov.</li>
<li class="">Language was uniquely human—until LLMs composed essays, poems, and jokes.</li>
<li class="">Creativity was safe—until AI-generated art won competitions and went viral.</li>
<li class="">Today, we concede mimicry but deny “true” understanding.</li>
<li class="">Tomorrow, we may demand self-awareness as the final frontier.</li>
</ul>
<p>This intellectual retreat obscures what is already happening and lulls us into complacency. If we keep shifting the bar, we risk ignoring systems capable of influence, persuasion, or even manipulation—simply because they don’t think “our” way.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-intelligence-feels-like">What intelligence feels like<a href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai#what-intelligence-feels-like" class="hash-link" aria-label="Direct link to What intelligence feels like" title="Direct link to What intelligence feels like" translate="no">​</a></h2>
<p>In everyday life, we judge people by their words and deeds, not by their brain chemistry. We call someone intelligent if they communicate clearly, solve problems deftly, or adapt to new challenges—without demanding a tour of their neural pathways. We infer intelligence from interaction and outcome.</p>
<p>The same standard applies to machines. When an LLM untangles a confusing question, tutors a student, or composes a lullaby, it feels intelligent. Focusing solely on “predictive text” is like calling a violin “just vibrating strings” or a novel “just ink on paper.” Mechanism matters—but meaning emerges in context.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="seeing-clearly-responding-wisely">Seeing clearly, responding wisely<a href="https://mcclowes.com/blog/2025/05/28/shapeshifting-definitions-of-ai#seeing-clearly-responding-wisely" class="hash-link" aria-label="Direct link to Seeing clearly, responding wisely" title="Direct link to Seeing clearly, responding wisely" translate="no">​</a></h2>
<p>Navigating this AI era, you must hold two truths simultaneously:</p>
<ol>
<li class=""><strong>Engineered artifacts:</strong> These systems are built, with no intrinsic understanding or self-awareness.</li>
<li class=""><strong>Competent actors:</strong> In interaction, they often behave indistinguishably from intelligent beings.</li>
</ol>
<p>Ignoring either leads to mistakes: techno-mysticism on one side (<a href="https://academic.oup.com/schizophreniabulletin/article/49/6/1418/7251361" target="_blank" rel="noopener noreferrer" class="">or worse</a>), dismissive complacency on the other. Instead, we need a Turing-style perspective that recognises intelligence as a property that emerges in the space between system and user.</p>
<p>That doesn’t mean abandoning rigor or skepticism. It means focusing on outcomes as well as architecture, and acknowledging what’s already changing—even if we don’t yet fully grasp how.</p>
<p>Because intelligence—like meaning, trust, or beauty—isn’t hidden in the mechanism. It lives in the moments when something surprises us, helps us, or moves us. And those moments are already here.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="tech" term="tech"/>
        <category label="ai" term="ai"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Paintings May 25]]></title>
        <id>https://mcclowes.com/blog/2025/05/27/paintings-may-25</id>
        <link href="https://mcclowes.com/blog/2025/05/27/paintings-may-25"/>
        <updated>2025-05-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<Carousel]]></summary>
        <content type="html"><![CDATA[<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-may-25/family-1.jpeg" alt="Image 1 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-may-25/flower-1.jpeg" alt="Image 2 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-may-25/flower-2.jpeg" alt="Image 3 of 4" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/paintings-may-25/greenhouse-1.jpeg" alt="Image 4 of 4" class="image_i3UB markdown-img"></p></div></div>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="art" term="art"/>
        <category label="painting" term="painting"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Fakemon process with AI]]></title>
        <id>https://mcclowes.com/blog/2025/05/12/pokemon-process</id>
        <link href="https://mcclowes.com/blog/2025/05/12/pokemon-process"/>
        <updated>2025-05-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I've been making Fakemon (fake pokemon) using a combination of traditional sketching and modern AI tools. The journey takes us from initial concept sketches through ChatGPT refinement, and finally to Sora for animation.]]></summary>
        <content type="html"><![CDATA[<p>I've been making Fakemon (fake pokemon) using a combination of traditional sketching and modern AI tools. The journey takes us from initial concept sketches through ChatGPT refinement, and finally to Sora for animation.</p>
<p>In this post, I'll walk you through my process of creating Fakemon (fan-made Pokémon) using a combination of traditional sketching and modern AI tools. The journey takes us from initial concept sketches through ChatGPT refinement, and finally to Sora for animation.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="initial-sketching-phase">Initial Sketching Phase<a href="https://mcclowes.com/blog/2025/05/12/pokemon-process#initial-sketching-phase" class="hash-link" aria-label="Direct link to Initial Sketching Phase" title="Direct link to Initial Sketching Phase" translate="no">​</a></h2>
<p>The process began with traditional pencil and paper sketches. This phase is crucial for getting the basic concept down and exploring different design possibilities. I usually start with a type combo, and try and come up with I focused on creating unique and interesting silhouettes while maintaining the distinctive Pokémon style. After the initial rough sketch, I refined the design with more detailed linework.</p>
<div class="wrapper_pkwN fadeRight_Lfa0" role="region" aria-label="Image carousel" aria-roledescription="carousel" tabindex="0"><div class="carouselTrack_mGOp" role="group" aria-label="Carousel images"><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/pokemon-process/1-ghowlish-really-rough.jpeg" alt="Image 1 of 2" class="image_i3UB markdown-img"></p><p class="imageContainer_Slcn markdown"><img src="https://mcclowes.com/img/posts/pokemon-process/2-ghowlish-sketch.jpeg" alt="Image 2 of 2" class="image_i3UB markdown-img"></p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bringing-it-to-life">Bringing it to Life<a href="https://mcclowes.com/blog/2025/05/12/pokemon-process#bringing-it-to-life" class="hash-link" aria-label="Direct link to Bringing it to Life" title="Direct link to Bringing it to Life" translate="no">​</a></h2>
<p>With ChatGPT's new o3 model &amp; image generation, and some specific prompts I've crafted, I've found I can get pretty great fake Pokemon designs. I just upload a photograph of the above in the prompt, and ask for a more refined version of the design, with specific reference to the creatures type, colours, etc.</p>
<p><img decoding="async" loading="lazy" alt="Final Ghowlish design" src="https://mcclowes.com/assets/images/3-ghowlish-fbd321582b74f184873805690006ddf2.png" width="1024" height="1024" class="img_ev3q"></p>
<p>Then I creatged an image for card art, in this case a holographic design variant:</p>
<p><img decoding="async" loading="lazy" alt="Shiny Ghowlish" src="https://mcclowes.com/assets/images/4-ghowlish-shiny-127d8b8ae5f7a671f12784574d55fa04.png" width="1536" height="1024" class="img_ev3q"></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="animation-with-sora">Animation with Sora<a href="https://mcclowes.com/blog/2025/05/12/pokemon-process#animation-with-sora" class="hash-link" aria-label="Direct link to Animation with Sora" title="Direct link to Animation with Sora" translate="no">​</a></h2>
<p>The final step was using Sora to generate an animated version of Ghowlish. This brought the creature to life, allowing us to see its movements and expressions in action:</p>
<p><img decoding="async" loading="lazy" alt="Animated Ghowlish" src="https://mcclowes.com/assets/images/5-ghowlish-animation-447b684573376ed4307ffe023350741a.gif" width="320" height="180" class="img_ev3q"></p>
<p>I find this incredibly hit and miss, and it's still absolutely awful most of the time, but in this case I actually got a good result.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="fleshing-out-the-character">Fleshing out the character<a href="https://mcclowes.com/blog/2025/05/12/pokemon-process#fleshing-out-the-character" class="hash-link" aria-label="Direct link to Fleshing out the character" title="Direct link to Fleshing out the character" translate="no">​</a></h2>
<p>You can also turn to ChatGPT to help refine the design and develop the Pokémon's characteristics. I've used prompts to design its abilities and moves, and more.</p>]]></content>
        <author>
            <name>Max Clayton Clowes</name>
            <uri>https://github.com/mcclowes</uri>
        </author>
        <category label="game design" term="game design"/>
        <category label="tcg" term="tcg"/>
    </entry>
</feed>