RSS/Atom Feed Analyzer
Analysis of https://simonwillison.net/atom/everything/
Feed fetched in 37 ms.
Content type is application/xml; charset=utf-8.
Feed is 123,886 characters long.
Warning Feed is missing an ETag.
Feed has a last modified date of Mon, 26 Oct 2026 23:53:07 GMT.
Feed is well-formed XML.
Warning Feed has no styling.
This is an Atom feed.
Feed title: Simon Willison's Weblog
Error Feed self link: http://simonwillison.net/atom/everything/ does not match feed URL: https://simonwillison.net/atom/everything/.
Warning Feed is missing an image.
Feed has 30 items.
First item published on 2026-10-26T23:53:07.000Z
Last item published on 2026-10-13T01:40:05.000Z
All items have published dates.
Newest item was published on 2026-10-26T23:53:07.000Z.
Home page URL: http://simonwillison.net/
Error Home page URL is on a different protocol: http:.
Warning Home page URL redirected to https://simonwillison.net/.
Home page has feed discovery link in <head>.
Home page has a link to the feed in the <body>
Formatted XML
<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
<title>Simon Willison's Weblog</title>
<link href="http://simonwillison.net/" rel="alternate"/>
<link href="http://simonwillison.net/atom/everything/" rel="self"/>
<id>http://simonwillison.net/</id>
<updated>2026-10-26T23:53:07+00:00</updated>
<author>
<name>Simon Willison</name>
</author>
<entry>
<title>GPT-6.1 Terra</title>
<link href="https://simonwillison.net/2026/Oct/26/gpt-61-terra/" rel="alternate"/>
<published>2026-10-26T23:53:07+00:00</published>
<updated>2026-10-26T23:53:07+00:00</updated>
<id>https://simonwillison.net/2026/Oct/26/gpt-61-terra/</id>
<summary type="html"><p><strong><a href="https://openai.com/index/introducing-gpt-6-1-terra/">GPT-6.1 Terra</a></strong></p>
It's always interesting to note which aspects of a new model are emphasized in the release announcement.</p>
<p>In the case of GPT-6.1 Terra, OpenAI went with visual reasoning and computer use:</p>
<blockquote>
<p>We’re introducing <strong>GPT-6.1 Terra</strong>, a fast, efficient model that combines detailed visual reasoning and precise computer use alongside clearer, more natural writing. A significant step up from GPT‑5.6 Terra, it excels at the communication and computer-based tasks that fill the workday, from drafting proposals and interpreting technical drawings to filling out forms and editing videos.</p>
</blockquote>
<p>Terra sits in the same position as Sonnet in the Anthropic model collection - not the cheapest or the most expensive, making it harder to decide when to use it.</p>
<p>Computer use is a good example of a task that benefits from a less expensive model, since you might put it to work on automated, repetitive tasks.</p>
<p>OpenAI's Ted Sanders provided some useful advice in <a href="https://news.ycombinator.com/item?id=50248124#50249160">a comment</a> on Hacker News:</p>
<blockquote>
<p>In the case of GPT-6.1 Terra, I'd say Terra is probably better than Astra and Sol at technical communication, similar on vision and computer use (but much faster!), and a bit worse on most other things. For API developers, it's a nice midrange option if you want something cheaper than Sol but a lot smarter than Luna (especially for vision / computer use / communication). For subscribers, it's not a bombshell release - if you're hitting usage limits, maybe it helps you go a bit further, and if you want clearer communication or faster computer use, it can be a nice option to select.</p>
</blockquote>
<p>Here are <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e">the pelicans</a> for the different reasoning levels. This pelican <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e#reasoning-2">for "max"</a> cost <a href="https://www.llm-prices.com/#it=16&amp;ot=22629&amp;sel=gpt-6.1-terra">11.3161 cents</a> and took 4 minutes and 11 seconds:</p>
<p><img alt="It's a good pelican and a good bicycle - correctly shaped frame, feet n pedals either side of the frame, has the same color scheme as the others in the GPT-6 and GPT-6.1 families." src="https://static.simonwillison.net/static/2026-10-26/terra-max.webp" /></p>
<p>Here's <a href="https://static.simonwillison.net/static/2026/openai-pelicans-october-2026.html">a new comparison grid</a> showing pelicans for every reasoning level of OpenAI's current frontier lineup: GPT-6 Astra, GPT-6.1 Sol, GPT-6.1 Terra, and GPT-6 Luna.</p>
<p>GPT-6.1 Terra is priced at $1/million input tokens and $5/million output - almost half the price of GPT-5.6 Terra and GPT-6.1 Sol, and around 10x the price of GPT-6 Luna.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50248124">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/openai">openai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a>, <a href="https://simonwillison.net/tags/gpt">gpt</a></p></summary>
<category term="ai"/>
<category term="openai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="llm-pricing"/>
<category term="pelican-riding-a-bicycle"/>
<category term="llm-release"/>
<category term="gpt"/>
</entry>
<entry>
<title>Quoting Jason Koebler</title>
<link href="https://simonwillison.net/2026/Oct/26/jason-koebler/" rel="alternate"/>
<published>2026-10-26T19:00:25+00:00</published>
<updated>2026-10-26T19:00:25+00:00</updated>
<id>https://simonwillison.net/2026/Oct/26/jason-koebler/</id>
<summary type="html"><blockquote cite="https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/"><p>Because big tech platforms essentially do not have customer support and make it impossible for their users to contact a human, many people experiencing run-of-the-mill tech problems have turned to ChatGPT. And, increasingly, ChatGPT is telling people that have normal tech support problems that they have discovered something journalistically notable and that 404 Media, specifically, can help them.</p></blockquote>
<p class="cite">&mdash; <a href="https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/">Jason Koebler</a>, ChatGPT Keeps Telling People 404 Media Can Solve Their Tech Support Problems</p>
<p>Tags: <a href="https://simonwillison.net/tags/jason-koebler">jason-koebler</a>, <a href="https://simonwillison.net/tags/openai">openai</a>, <a href="https://simonwillison.net/tags/journalism">journalism</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/ai-ethics">ai-ethics</a>, <a href="https://simonwillison.net/tags/ai-misuse">ai-misuse</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/chatgpt">chatgpt</a>, <a href="https://simonwillison.net/tags/404-media">404-media</a></p></summary>
<category term="jason-koebler"/>
<category term="openai"/>
<category term="journalism"/>
<category term="ai"/>
<category term="llms"/>
<category term="ai-ethics"/>
<category term="ai-misuse"/>
<category term="generative-ai"/>
<category term="chatgpt"/>
<category term="404-media"/>
</entry>
<entry>
<title>webframe: evaluated as a scraper and a sandbox</title>
<link href="https://simonwillison.net/2026/Oct/26/webframe-evaluation/" rel="alternate"/>
<published>2026-10-26T16:15:00+00:00</published>
<updated>2026-10-26T16:15:00+00:00</updated>
<id>https://simonwillison.net/2026/Oct/26/webframe-evaluation/</id>
<summary type="html"><p><strong>Research:</strong> <a href="https://github.com/simonw/research/tree/main/webframe-evaluation#readme">webframe: evaluated as a scraper and a sandbox</a></p>
<p><a href="https://github.com/tractordev/webframe">webframe</a> is a neat little project from Jeff Lindsay which lets you "run a web page like a program" - you point it at a URL or file and it executes it in a hidden headless web view and outputs <code>console.log()</code> to standard output and any exceptions to standard error.</p>
<p>It's written in Go on top of the <a href="https://github.com/crgimenes/glaze">glaze</a> library, which provides access to a system browser ("WKWebView on macOS, WebKitGTK on Linux, WebView2 on Windows") so it doesn't need to bundle its own browser engine.</p>
<p>It reminds me of my own <a href="https://shot-scraper.datasette.io/en/stable/javascript.html">shot-scraper javascript</a> tool, albeit in a much smaller package that doesn't depend on Playwright.</p>
<p>I had Claude Opus 5.5 <a href="https://claude.ai/code/cshk_01MX3aJH8vDGmGSj1xH9BYhj2HviVvLDaJbiELHyDoReYT">put it through its paces</a> and prepare a research report for me. Here's the prompt I used:</p>
<blockquote>
<p><code>Explore https://github.com/tractordev/webframe try running it and put it though its paces, build a few exploratory prototypes, then evaluate it as a potential sandboxing tool and as a tool for scraping web pages using the same patterns encouraged by the "shot-scraper JavaScript" command (see simonw/shot-scraper on GitHub, docs directory)</code></p>
</blockquote>
<p>Tags: <a href="https://simonwillison.net/tags/browsers">browsers</a>, <a href="https://simonwillison.net/tags/go">go</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a>, <a href="https://simonwillison.net/tags/jeff-lindsay">jeff-lindsay</a>, <a href="https://simonwillison.net/tags/shot-scraper">shot-scraper</a></p></summary>
<category term="browsers"/>
<category term="go"/>
<category term="javascript"/>
<category term="jeff-lindsay"/>
<category term="shot-scraper"/>
</entry>
<entry>
<title>Seam Cutter</title>
<link href="https://simonwillison.net/2026/Oct/25/seam-cutter/" rel="alternate"/>
<published>2026-10-25T15:10:19+00:00</published>
<updated>2026-10-25T15:10:19+00:00</updated>
<id>https://simonwillison.net/2026/Oct/25/seam-cutter/</id>
<summary type="html"><p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/seam-cutter">Seam Cutter</a></p>
<p>I built this weird and very specific cropping tool - it lets you create a horizontal or vertical cut across an image, then slide the two sides relative to each other. Effectively it lets you crop out a section in the middle of an image.</p>
<p>I wanted this because I often use <a href="https://apps.apple.com/us/app/tailor-screenshot-stitching/id926653095">Tailor</a> on my iPhone to stitch several screenshots together into lot long image, but sometimes I find myself wanting to crop out a section in the middle - to redact an irrelevant prompt from a transcript, for example.</p>
<p>Tags: <a href="https://simonwillison.net/tags/tools">tools</a></p></summary>
<category term="tools"/>
</entry>
<entry>
<title>battledrones v14: Compass Rose, a four player map</title>
<link href="https://simonwillison.net/2026/Oct/24/battledrones/" rel="alternate"/>
<published>2026-10-24T03:59:57+00:00</published>
<updated>2026-10-24T03:59:57+00:00</updated>
<id>https://simonwillison.net/2026/Oct/24/battledrones/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/battledrones/releases/tag/v14">battledrones v14: Compass Rose, a four player map</a></p>
<p>I added four player online mode to <a href="https://simonwillison.net/2026/Oct/20/battledrones/">Battledrones</a> - previous maps were limited to two.</p>
<p>Here's the initial prompt I used: </p>
<blockquote>
<p><code>Add a new map for a four player battle - four way rotational symmetry, up to four AI players, works with the WebSocket non-audio based multiplayer mode so up to four human players can join (any spare slots use AI)</code></p>
</blockquote>
<p>Claude Opus 5.5 added a new map called "Compass Rose" and modified the WebSockets multiplayer network code to support up to four players for that map, joining via share links or QR codes.</p>
<p><img alt="The new map does indeed look a bit like a rose - it uses the cold and ice biome. Also shown are purple robots battling on the map." src="https://raw.githubusercontent.com/simonw/battledrones/v14/progress-shots/v14/compass-rose.jpg" /></p>
<p>The new teams use robots themed in purple and green, joining the existing blue and red designs. You can preview those colors in <a href="https://simonw.github.io/battledrones/models.html">the updated model browser</a>.</p>
<p>Here's <a href="https://simonw.github.io/battledrones/v14/?replay=https://gist.githubusercontent.com/simonw/faa550a002b25a78f1c88a64217786c1/raw/4ff9b03de71d757cd33eb5d1a0e388155b6c20e5/compass.json">a replay link</a> to watch a four way AI battle with the "Goliath Armada" mutator turned on, where each side starts with four giant Goliath mech units.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/claude">claude</a></p></summary>
<category term="game-design"/>
<category term="projects"/>
<category term="claude"/>
</entry>
<entry>
<title>Quick Study</title>
<link href="https://simonwillison.net/2026/Oct/23/quick-study-painter/" rel="alternate"/>
<published>2026-10-23T21:35:13+00:00</published>
<updated>2026-10-23T21:35:13+00:00</updated>
<id>https://simonwillison.net/2026/Oct/23/quick-study-painter/</id>
<summary type="html"><p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/quick-study-painter">Quick Study</a></p>
<p>Prompt <a href="https://claude.ai/share/71adda96-193f-4f2a-97c0-454e08066afb">to Claude Opus 5.5 High</a>:</p>
<blockquote>
<p><code>Build an artifact where you open a photo and it rapidly (in a few seconds) paints a version of that photo using a canvas element and simulated paintbrush</code></p>
</blockquote>
<p>See also <a href="https://simonwillison.net/2026/Aug/25/pelican-watercolor/">my previous experiment</a> getting Claude Fable to simulate a watercolor illustration with P5.js.</p>
<p><img alt="A simulated oil painting of a photograph of a heron" src="https://static.simonwillison.net/static/2026/heron-oil.webp" /></p>
<p>Quick Study uses <a href="https://en.wikipedia.org/wiki/Sobel_operator">Sobel edge detection</a>, with no external libraries beyond Google Fonts.</p>
<p>Tags: <a href="https://simonwillison.net/tags/tools">tools</a></p></summary>
<category term="tools"/>
</entry>
<entry>
<title>Introducing Kimi K3.1 Pro</title>
<link href="https://simonwillison.net/2026/Oct/23/kimi-k31-pro/" rel="alternate"/>
<published>2026-10-23T19:40:54+00:00</published>
<updated>2026-10-23T19:40:54+00:00</updated>
<id>https://simonwillison.net/2026/Oct/23/kimi-k31-pro/</id>
<summary type="html"><p><strong><a href="https://www.kimi.ai/blog/kimi-k3-1-pro">Introducing Kimi K3.1 Pro</a></strong></p>
Kimi K3.1 Pro landed on the Kimi API today - it's not yet open weights, but Moonshot promise "Full model weights will be released by Nov 4, 2026".</p>
<p>They're also offering a "Highspeed" version that's 2-3x faster, at twice the price (except for input token cache hits, which are priced the same).</p>
<p>The <a href="https://platform.kimi.ai/docs/pricing/chat">US dollar pricing</a> is $2.00/million tokens for input and $10/million for output - the same as GPT-6.1 Sol and half the price of Claude Opus 5.5.</p>
<p>Moonshot's own benchmarks show Kimi as approximately level with Opus 5.5 and GPT-6 Astra - beating them on a few benchmarks, coming close on others.</p>
<p>Artificial Analysis <a href="https://artificialanalysis.ai/models/kimi-k3-1-pro">scored Kimi at 55</a> - ahead of Claude Fable 5.1, GPT-6 Astra, and Gemini 4 Argon (all at 53) and behind only Claude Opus 5.5 (58).</p>
<p>This is the first time a (soon-to-be) open weight model has scored this highly against the frontier.</p>
<p>I tried it out via the <a href="https://platform.kimi.ai/docs/get-your-api-key">Moonshot API</a> using the <a href="https://llm.datasette.io/en/stable/other-models.html#openai-endpoint">llm openai endpoint</a> command I added to <a href="https://llm.datasette.io/en/stable/changelog.html#v0-32">LLM 0.32</a> back in August:</p>
<pre><code>llm openai endpoint \
https://api.moonshot.ai/v1 \
--key kimi \
-m kimi-k3.1-pro \
"Generate an SVG of a pelican riding a bicycle" \
--responses \
-o reasoning_effort low \
&gt; kimi-k3.1-pro-pelican-low.stdout.txt \
2&gt; kimi-k3.1-pro-pelican-low.stderr.txt
</code></pre>
<p><code>llm openai endpoint</code> can run prompts against any OpenAI-compatible endpoint but doesn't log the results, hence the extra options to save stdout and stderr (the reasoning trace).</p>
<p>Here <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9b7181492209387da1d4f53002f26663">are the pelicans</a> I got for Kimi K3.1 Pro on the three reasoning levels it supports - low, medium, and max. This is max:</p>
<p><img alt="It's pretty solid - feet are on the pedals, bicycle frame is good, nice beak. Both legs are on the same side of the Fram though." src="https://static.simonwillison.net/static/2026-10-23/image-2.png" /></p>
<p>For comparison, I ran fresh <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Feba9a4283c9e94cbbb5325902a3921a8">pelicans against Kimi K3</a> on those three reasoning levels.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50212065">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm">llm</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a>, <a href="https://simonwillison.net/tags/ai-in-china">ai-in-china</a>, <a href="https://simonwillison.net/tags/moonshot">moonshot</a>, <a href="https://simonwillison.net/tags/kimi">kimi</a></p></summary>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="llm"/>
<category term="llm-pricing"/>
<category term="pelican-riding-a-bicycle"/>
<category term="llm-release"/>
<category term="ai-in-china"/>
<category term="moonshot"/>
<category term="kimi"/>
</entry>
<entry>
<title>DE STAAT - FREEDOM (Official Music Video)</title>
<link href="https://simonwillison.net/2026/Oct/22/de-staat-freedom/" rel="alternate"/>
<published>2026-10-22T19:42:26+00:00</published>
<updated>2026-10-22T19:42:26+00:00</updated>
<id>https://simonwillison.net/2026/Oct/22/de-staat-freedom/</id>
<summary type="html"><p><strong><a href="https://www.youtube.com/watch?v=hKO4pQtIXow">DE STAAT - FREEDOM (Official Music Video)</a></strong></p>
OK well this is a first for me... at <a href="https://www.youtube.com/watch?v=hKO4pQtIXow&amp;t=44s">00:44</a> in this new music video by Dutch alternative rock band <a href="https://en.wikipedia.org/wiki/De_Staat">De Staat</a>:</p>
<p><video
src="https://static.simonwillison.net/static/2026/freedom-pelican.mp4"
poster="https://static.simonwillison.net/static/2026/freedom-pelican-poster.jpg"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
width="1280"
height="720"
style="display: block; width: 100%; height: auto;"
> </video>
</p>
<p>The visual effects are credited to Matties Grooten of <a href="https://fakeitorleaveit.com">Fake it or Leave it</a>.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50186129#50193407">flir on Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/music">music</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a></p></summary>
<category term="music"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="pelican-riding-a-bicycle"/>
</entry>
<entry>
<title>Donating Agent Skills to the Agentic AI Foundation</title>
<link href="https://simonwillison.net/2026/Oct/22/donating-agent-skills/" rel="alternate"/>
<published>2026-10-22T18:09:56+00:00</published>
<updated>2026-10-22T18:09:56+00:00</updated>
<id>https://simonwillison.net/2026/Oct/22/donating-agent-skills/</id>
<summary type="html"><p><strong><a href="https://www.anthropic.com/news/donating-agent-skills-to-the-agentic-ai-foundation">Donating Agent Skills to the Agentic AI Foundation</a></strong></p>
News today from Anthropic:</p>
<blockquote>
<p>We’re committed to keeping Agent Skills open, community-driven, and vendor-neutral. Today, we are donating the standard to the Agentic AI Foundation (AAIF) under the Linux Foundation, <a href="https://www.anthropic.com/news/donating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation">which we co-founded</a> with Block and OpenAI last year, and to which we donated the Model Context Protocol (MCP).</p>
</blockquote>
<p>I'm pleased to note I called this one <a href="https://simonwillison.net/2025/Dec/19/agent-skills/">last December</a>, when Anthropic first declared skills to be an "open standard":</p>
<blockquote>
<p>I wouldn't be surprised to see this end up <a href="https://simonwillison.net/2025/Dec/9/agentic-ai-foundation/">in the AAIF</a>, recently the new home of the MCP specification.</p>
</blockquote>
<p>Fun side note: since my blog content is available to Claude via the <a href="https://github.com/datasette/datasette-mcp">datasette-mcp</a>
plugin I found that post by <a href="https://claude.ai/share/80b341de-590b-4834-bca9-0d9c9a3a0298">prompting Claude</a> to "<code>Use simonwillison.net MCP to find if I ever talked about how I want skills to be donated to a standards body</code>".
<p>Tags: <a href="https://simonwillison.net/tags/standards">standards</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/model-context-protocol">model-context-protocol</a>, <a href="https://simonwillison.net/tags/skills">skills</a></p></summary>
<category term="standards"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="anthropic"/>
<category term="model-context-protocol"/>
<category term="skills"/>
</entry>
<entry>
<title>Quoting Armin Ronacher</title>
<link href="https://simonwillison.net/2026/Oct/22/armin-ronacher/" rel="alternate"/>
<published>2026-10-22T15:34:13+00:00</published>
<updated>2026-10-22T15:34:13+00:00</updated>
<id>https://simonwillison.net/2026/Oct/22/armin-ronacher/</id>
<summary type="html"><blockquote cite="https://twitter.com/mitsuhiko/status/2113207589978636646"><p>As fun as AI is, we built so much bad software over the last 30 years, and now the universe is punishing us for our sins.</p></blockquote>
<p class="cite">&mdash; <a href="https://twitter.com/mitsuhiko/status/2113207589978636646">Armin Ronacher</a></p>
<p>Tags: <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/armin-ronacher">armin-ronacher</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/ai-security-research">ai-security-research</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p></summary>
<category term="security"/>
<category term="generative-ai"/>
<category term="armin-ronacher"/>
<category term="ai"/>
<category term="ai-security-research"/>
<category term="llms"/>
</entry>
<entry>
<title>Today's PHP Security Release, and How We're Strengthening PHP Security</title>
<link href="https://simonwillison.net/2026/Oct/21/php-security-release/" rel="alternate"/>
<published>2026-10-21T18:41:53+00:00</published>
<updated>2026-10-21T18:41:53+00:00</updated>
<id>https://simonwillison.net/2026/Oct/21/php-security-release/</id>
<summary type="html"><p><strong><a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/">Today&#x27;s PHP Security Release, and How We&#x27;re Strengthening PHP Security</a></strong></p>
If you're running anything on PHP it's vital you upgrade - today's updates (across the entire PHP 8.x line) address two remote code execution holes, and there have been exploits circulating since last night, thanks to a leak in the coordinated disclosure process.</p>
<p>This post from the PHP Foundation explain what went so wrong:</p>
<blockquote>
<p>On Tuesday, October 20th, at around 15:00 UTC, the two CVE IDs began circulating on online forums and social media. They came with a wrong release time and a wrong CVSS score of 10.0 (the actual score is 9.2). No technical details leaked. In response, the PHP project brought its pre-announcement forward and <a href="https://www.php.net/archive/2026.php#2026-10-20-1">published it at 19:30 UTC</a>. It also moved the release from October 22nd, 14:00 UTC, to October 21st, 14:00 UTC [...]</p>
<p>As a result of the leak and pre-announcement around 20:00 UTC, Calif, one of the security firms that had reported the issues mistakenly published a video. It showed their proof of concept working against a number of targets and revealed a few additional, though limited, details about the vulnerabilities. Copies of the deleted video started circulating on social media soon after. The video contributed to accelerated development of various PoCs (exploitation proof of concepts), which then increased circulation on October 21st.</p>
</blockquote>
<p><a href="https://www.wiz.io/blog/php2shell-php-rce">This article</a> from the team that discovered the original vulnerability includes a more detailed timeline of the original intended responsible disclosure:</p>
<blockquote>
<ul>
<li><strong>August 19, 2026:</strong> Wiz Research discovers the first PHP vulnerability using Wiz Atlas, Gemini 4 Argon, and GPT-5.6 Sol.</li>
<li><strong>August 20, 2026:</strong> Unauthenticated RCE is confirmed against Drupal.</li>
<li><strong>August 21, 2026:</strong> Unauthenticated RCE is confirmed against WordPress.</li>
<li><strong>August 24, 2026:</strong> Wiz Research reports the vulnerabilities to the PHP security team.</li>
<li><strong>September 21, 2026:</strong> PHP acknowledges the reports and begins developing a coordinated fix.</li>
<li><strong>October 21, 2026:</strong> Patched PHP releases become available.</li>
<li><strong>October 21, 2026:</strong> Public disclosure.</li>
</ul>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50182987">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/open-source">open-source</a>, <a href="https://simonwillison.net/tags/php">php</a>, <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/ai-security-research">ai-security-research</a></p></summary>
<category term="open-source"/>
<category term="php"/>
<category term="security"/>
<category term="ai"/>
<category term="ai-security-research"/>
</entry>
<entry>
<title>Panache — RTS Belle Époque pour mobile</title>
<link href="https://simonwillison.net/2026/Oct/21/panache/" rel="alternate"/>
<published>2026-10-21T16:25:16+00:00</published>
<updated>2026-10-21T16:25:16+00:00</updated>
<id>https://simonwillison.net/2026/Oct/21/panache/</id>
<summary type="html"><p><strong><a href="https://github.com/menufactory43/panache/">Panache — RTS Belle Époque pour mobile</a></strong></p>
Well this is delightful: I <a href="https://simonwillison.net/2026/Oct/20/battledrones/">released Battle Drones</a> yesterday under an Apache 2.0 License and there's already a French language fork which reskins the game to take place in steampunk 1900s France and adds an animated intro!</p>
<blockquote>
<p><strong>Panache</strong> est un jeu de stratégie en temps réel pour mobile et navigateur, dans la France de la Belle Époque (vers 1900) : dirigeables, Fardiers à vapeur, Creusot cuirassés, automates en képi, Gargantua la forteresse marchante — et beaucoup de panache.</p>
</blockquote>
<p>You can <a href="https://menufactory43.github.io/panache/">play Panache here</a> - it's worth clicking that link just to experience the new intro video.</p>
<p>So far it's mostly just aesthetic updates as opposed to gameplay changes. The music has had a French twist added to it as well.</p>
<p>The new steampunk models are so cool!</p>
<p><img alt="The new buildings are gold and red, there are dirigibles and biplanes, and the Goliath stomping mech has had a total makeover." src="https://static.simonwillison.net/static/2026/battledrones-french.jpg" /></p>
<p>Here's a page with <a href="https://simonw.github.io/battledrones/models.html">the original Battle Drones models</a> and that same page <a href="https://menufactory43.github.io/panache/models.html">with the new Panache alternatives</a>.</p>
<p>This is a comparison of the original and the new design for the Goliath:</p>
<p><img alt="On the left: blue stomping mech robot, missile launcher shoulders, classic sci-fi robot look. On the right: gold, steampunk, much more 1900s French look." src="https://static.simonwillison.net/static/2026/battledrones-goliath-diff.jpg" />
<p><small></small>Via <a href="https://twitter.com/Meffysto69/status/2112908755654365220">@Meffysto69</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/open-source">open-source</a></p></summary>
<category term="game-design"/>
<category term="open-source"/>
</entry>
<entry>
<title>eMudhra Intermediate CA Compromise</title>
<link href="https://simonwillison.net/2026/Oct/20/emudhra-certificates/" rel="alternate"/>
<published>2026-10-20T23:50:25+00:00</published>
<updated>2026-10-20T23:50:25+00:00</updated>
<id>https://simonwillison.net/2026/Oct/20/emudhra-certificates/</id>
<summary type="html"><p><strong><a href="https://emudhra.we-have-a-problem.com">eMudhra Intermediate CA Compromise</a></strong></p>
This is very, very bad news:</p>
<blockquote>
<p>The private keys of eight eMudhra intermediate CA certificates have been compromised. They chain to roots trusted by the Mozilla, Microsoft, Apple and Chrome root programs and by many downstream trust stores.</p>
</blockquote>
<p>Any software that bundles a list of trusted certificates needs to be updated. This site is tracking software updates <a href="https://github.com/galadran/we-have-a-problem.com">via this GitHub repository</a> - Linux distros need to update their <code>ca-certificates</code> packages.</p>
<p>In Python world <a href="https://github.com/astral-sh/uv/releases/tag/0.13.4">uv 0.13.4</a> and <a href="https://github.com/pypa/pip/releases/tag/26.2.2">pip 26.2.2</a> and <a href="https://github.com/certifi/python-certifi/releases/tag/2026.10.19">certifi 2026.10.19</a> have been released with upgraded certificate lists.</p>
<p>There's a <a href="https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576">very informative thread</a> about this on the official Python forum.
<p>Tags: <a href="https://simonwillison.net/tags/encryption">encryption</a>, <a href="https://simonwillison.net/tags/https">https</a>, <a href="https://simonwillison.net/tags/pip">pip</a>, <a href="https://simonwillison.net/tags/python">python</a>, <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/uv">uv</a></p></summary>
<category term="encryption"/>
<category term="https"/>
<category term="pip"/>
<category term="python"/>
<category term="security"/>
<category term="uv"/>
</entry>
<entry>
<title>Battle Drones - a vibe coded RTS with audio-based multiplayer</title>
<link href="https://simonwillison.net/2026/Oct/20/battledrones/" rel="alternate"/>
<published>2026-10-20T19:34:19+00:00</published>
<updated>2026-10-20T19:34:19+00:00</updated>
<id>https://simonwillison.net/2026/Oct/20/battledrones/</id>
<summary type="html"><p>My latest vibe coded game experiment is a Command &amp; Conquer style RTS (Real Time Strategy) game called <a href="https://github.com/simonw/battledrones#readme">Battle Drones</a> (<a href="https://simonw.github.io/battledrones/">play it here</a>). Unlike <a href="https://simonwillison.net/2026/Aug/5/raccoon-heist/">my previous experiments</a>, this one is <em>actually fun to play</em>. I'm somewhat embarrassed to admit that I got there by telling Claude to "Make it a LOT more fun". It also supports multiplayer between nearby devices using audio to synchronize game state! Here's what I've built so far, and some of the things I learned along the way.</p>
<ul>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#battle-drones">Battle Drones</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#how-i-built-this">How I built this</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v1-the-initial-prototype">v1: the initial prototype</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v2-full-sprites">v2: full sprites</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v3-varied-terrain">v3: varied terrain</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v4-the-fun-update">v4: the fun update</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v5-battle-drones-goes-3d">v5: Battle Drones goes 3D</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v8-archipelago">v8: Archipelago</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v10-goliath-and-agent-battles">v10: Goliath, and agent battles</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#agent-battles">Agent battles</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v11-random-maps">v11: Random Maps</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v12-multiplayer-via-sound">v12: Multiplayer via sound</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#some-thoughts">Some thoughts</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support">Update: Online multiplayer support</a></li>
</ul>
<h4 id="battle-drones">Battle Drones</h4>
<p>My initial goal was to build an RTS game I could play on my phone, in the style of <a href="https://en.wikipedia.org/wiki/Command_&amp;_Conquer_(1995_video_game)">Command &amp; Conquer</a>. I have fond memories of the 1995 original (I liked Red Alert too) and wanted to recapture a little bit of the magic.</p>
<p>After 12 major iterations (and <a href="https://github.com/simonw/battledrones/commits/main/">321 commits</a> by coding agents, mainly Claude Code) I now have a browser-based game that works on mobile and desktop, has multiple play modes, several maps (including a random map generator) and even supports multiplayer for two devices within microphone range of each other. (<strong>Update</strong>: also <a href="https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support">online multiplayer</a>; the audio multiplayer induced headaches!)</p>
<p>Here's a video demo of Battle Drones running in a desktop browser:</p>
<video
src="https://static.simonwillison.net/static/2026/archipelago_720p_h264.mp4"
poster="https://static.simonwillison.net/static/2026/archipelago_poster.jpg"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
width="1280"
height="706"
style="display: block; width: 100%; height: auto;"
> </video>
<p style="margin-top: 1em">Features so far include:</p>
<ul>
<li>9 buildings, 7 ground vehicles, 6 aerial vehicles, 3 infantry units - all 3D models, which you can <a href="https://simonw.github.io/battledrones/models.html">browse here</a>
</li>
<li>Fog of war</li>
<li>Different weapons are needed to target aerial or ground vehicles</li>
<li>
<strong>Six maps</strong>, across five biomes - temperate, desert, arctic, volcanic, tropical</li>
<li>A random map generator</li>
<li>
<strong>Skirmish mode</strong> - red vs. blue on a rotationally symmetrical map</li>
<li>
<strong>Last Stand mode</strong> - one player holds out against as many waves of enemies as possible</li>
<li>Area effect weapons: Barrage, EMP, Drop Pod, Sky Hammer</li>
<li>
<strong>Crate drops</strong> with bonus resources</li>
<li>In-game music that responds to events - it gets more intense as fighting breaks out</li>
<li>Different in-game <strong>AI personalities</strong> (Balanced, Rush, Air Swarm, Boom, Skyforce, Ironclad)</li>
<li>
<strong>AI vs. AI</strong> mode, to watch those personalities play each other</li>
<li>The <strong>Goliath</strong> - a giant stomping mech with laser eyes and arm cannons and the ability to establish a new base</li>
<li>
<strong>Mutators</strong> that add extra rules or twists</li>
<li>A "Daily Op" challenge</li>
<li>Ranks and achievements (<strong>Medals</strong>)</li>
<li>
<strong>Agent vs. Agent</strong> mode where two LLMs can play Battle Drones against each other</li>
<li>A <strong>multiplayer mode</strong> based on two nearby phones communicating via audio messages, an extension of my earlier experiment with <a href="https://simonwillison.net/2026/Oct/15/chirp-pong/">Chirp Pong</a>
</li>
</ul>
<h4 id="how-i-built-this">How I built this</h4>
<p>Battle Drones is heavily vibe coded - I've reviewed almost none of the code, and it's built in a language (TypeScript) that I've hardly used myself. I've playtested it quite a bit though, and it's been through a large number of iterations since I started the project.</p>
<p>Here's a rough history of the project so far, including key prompts and links to transcripts.</p>
<h4 id="v1-the-initial-prototype">v1: the initial prototype</h4>
<p>I started out with Claude Fable 5 back in July:</p>
<blockquote>
<p><code>We are going to build a mobile friendly RTS game - command and conquer style - called Battle Drones, in which two armies of drones (both flying and ground-based) battle for territory and resources</code></p>
<p><code>Let's start with a MVP design, ask me some questions</code></p>
</blockquote>
<p>Here's a <a href="https://claude.ai/code/session_015RYeKm4ji4N16oqthyX1b1">shared transcript</a>. I'd given Claude Code for Web an environment variable with an OpenAI API key and told it to use the OpenAI <a href="https://developers.openai.com/api/docs/guides/image-generation">Image Generation API</a> for assets, which got me some basic sprites.</p>
<p>You can <a href="https://simonw.github.io/battledrones/v1/">try v1 here</a> - it looked like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v1.webp" alt="Game screen. Down the right are text icons to build Fab, Airpad, Turret, Harv, Sting, Flak, Scout, Wasp, Raptor. There is a blocky fog of war on a 2D battlefield. There are some gems, an HQ building being attacked by badly rendered tanks, and some blue vehicles dotted around. It's not very visually impressive but it does look like a basic RTS." style="max-width: 100%;" /></p>
<p>It's recognizable as an RTS, has building mechanics and the ability to select and direct units, and a basic AI to play against.</p>
<p>This first version was barely a proof of concept, and it wasn't any fun to play.</p>
<p>Claude used the <a href="https://github.com/phaserjs/phaser">Phaser</a> 2D game framework for these early versions. I didn't even realize this until several iterations later!</p>
<h4 id="v2-full-sprites">v2: full sprites</h4>
<p>The second version (<a href="https://simonw.github.io/battledrones/v2/">try v2 here</a>) added sprites for all of the vehicles and the "AI vs. AI" mode, so I could watch the game playing without having to directly control it myself.</p>
<p>Claude proved reasonably competent at prompting OpenAI's image models to generate sprites. You can browse the v2 sprites in the <a href="https://github.com/simonw/battledrones/tree/v2/public/assets/sprites">public/assets/sprites</a> folder.</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v2.webp" alt="Four flying units, three turrets, a harvester and an airpad all have proper sprites now. The scrap field has a new design which doesn't look great but is at least using a graphic." style="max-width: 100%;" /></p>
<h4 id="v3-varied-terrain">v3: varied terrain</h4>
<p>It still wasn't much fun, and the graphics were boring. It was now October, and I had upgraded to Claude Opus 5.5. I told it:</p>
<blockquote>
<p><code>Massively improve this game. Make the graphics and gameplay better (keep it mobile friendly). Render new graphics using the latest OpenAI GPT image API (lookup details) with the API key in the environment variable. Add new unit types and balance the gameplay better. Also add new buildings and better, more varied terrain.</code></p>
</blockquote>
<p>This resulted in five new maps with generated background tiles in a variety of styles, <a href="https://github.com/simonw/battledrones/commit/aa22f08a34347d7d9f94b33f44a73b4deb046aa1">visible here</a>. Opus also regenerated the sprites, making them much more visually appealing. You can <a href="https://simonw.github.io/battledrones/v3/">try v3 here</a> - it looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v3.jpg" alt="The map is now an ice map with snow and ice and broken ice - it looks really good. The vehicles and buildings have all had a cosmetic upgrade too. This is starting to look like a real game." style="max-width: 100%;" /></p>
<p>This is starting to feel like a real game! It still wasn't very fun to play though - I found myself getting bored pretty quickly.</p>
<h4 id="v4-the-fun-update">v4: the fun update</h4>
<p>So far my Battle Drones experiment was confirming my <a href="https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp">previous belief</a> that coding agents can build a thing that looks like a game but can't actually make something that's genuinely compelling to play.</p>
<p>I shared this theory with someone over dinner, and then thought to myself that I should give the models a proper chance to prove me wrong. I prompted Opus 5.5 on my phone:</p>
<blockquote>
<p><code>This game isn't fun enough yet. Make it a LOT more fun.</code></p>
</blockquote>
<p>This time I was running in <a href="https://code.claude.com/docs/en/workflows">Ultracode mode</a>, where Claude Code (in this case Claude Code for Web) runs "dynamic workflows", described in their docs as:</p>
<blockquote>
<p>A dynamic workflow is a JavaScript script that orchestrates many <a href="https://code.claude.com/docs/en/sub-agents">subagents</a> at once.</p>
</blockquote>
<p>This kicked off <em>many hours</em> of work. I started it in the evening and didn't get a playable result back until late into the next morning. But the results were spectacular.</p>
<p>You can <a href="https://simonw.github.io/battledrones/v4/">try v4 here</a> - it looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v4.jpg" alt="The lava map. Uplink satellites are being taken, crystals look better, Elite text is shown above a unit, there is an arrow marked Fight to jump to a fight, the AI vs AI mode has a speed controller - plenty of new features here." style="max-width: 100%;" /></p>
<p>I had Claude <a href="https://github.com/simonw/battledrones/blob/main/Battle%20Drones%20The%20Fun%20Update%20%E2%80%94%20Release%20Notes.md">write its own release notes</a> - here are the highlights:</p>
<blockquote>
<p>Every skirmish and Daily Op now opens with a choice, gives the side that's losing a way back, and pulls the armies into the middle of the map. There are also two new ways to play.</p>
<ul>
<li>
<strong>Openers</strong>: pick Blitz, Industry or Air Wing before the clock starts.</li>
<li>
<strong>Call-down powers</strong>: Barrage, EMP, Drop Pod and the Sky Hammer orbital strike.</li>
<li>
<strong>Objectives and salvage</strong>: Uplink relays, supply drops and wrecks worth scrap.</li>
<li>
<strong>Feel</strong>: combat juice, adaptive music, unit voices and an announcer.</li>
<li>
<strong>Command</strong>: battle alerts, game speed, saved squads and touch placement.</li>
<li>
<strong>New modes</strong>: Last Stand survival waves and an 8-mission Ops campaign.</li>
<li>
<strong>Progression</strong>: heroes, an after-action report with awards, a career, 7 mutators and a Daily Op.</li>
</ul>
<p>Fights run longer and swing more. In 1,200 AI-vs-AI test matches on Normal, games still undecided after 25 minutes fell from 14% to 0.9%. The share of wins by a side that had been 800+ scrap behind rose from 24% to 46%.</p>
</blockquote>
<p>Part of the reason Claude took so long was that it ran over a thousand simulated playtest sessions, and used the results to rebalance the existing units, add new ones, and introduce new features.</p>
<h4 id="v5-battle-drones-goes-3d">v5: Battle Drones goes 3D</h4>
<p>After the success of Ultracode at "Make it a LOT more fun", I decided to be more ambitious:</p>
<blockquote>
<p><code>Port this game to three.js with 3D models for all of the buildings and vehicles and landscapes</code></p>
</blockquote>
<p>That was another overnight run. I woke up to <a href="https://simonw.github.io/battledrones/v5/">this v5 version</a>:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v5.jpg" alt="Now it is in 3D - the battlefield is at a slight angle, the buildings and vehicles are all 3D models, the rocks and trees look a bit 3D as well." style="max-width: 100%;" /></p>
<p>The new 3D models were entirely constructed by Claude in TypeScript code.</p>
<p>v6 (<a href="https://simonw.github.io/battledrones/v6/">play v6 here</a>) added some more visual polish. v7 (<a href="https://simonw.github.io/battledrones/v7/">play v7</a>) added robot infantry (troopers, rocket squads, snipers) and a "Condor" troop carrying aircraft.</p>
<h4 id="v8-archipelago">v8: Archipelago</h4>
<p>I was beginning to feel guilty at how little actual design input I had into the game - it really had been a case of me saying "make it more fun" and "add visual polish" for the past few releases.</p>
<p>I'd noticed that the AI didn't use the new infantry and troop carrying aircraft from v7 very often - there wasn't a great strategic reason to use them.</p>
<p>It would be neat if we had a new map with a new game mechanic that actively encouraged players to load up Condors with infantry robots and send them out into the map.</p>
<p>This resulted in my longest prompt yet:</p>
<blockquote>
<p><code>Design a new map. Goal is to make different strategic incentives that encourage use of Infantry and Condors and aerial vehicles.</code></p>
<p><code>To do this the map will have limited harvester resources but several more uplinks - but uplinks will be on islands that are inaccessible by land vehicles or infantry. These uplinks can also not be claimed using air vehicles. The ONLY way to get them is to fly infantry there in a Condor.</code></p>
<p><code>Armies always start with a Condor and a single squad. If an army has no Condor a new one will be provided for free, flying in from the edge closest to their HQ and landing there. That free condor will come with a single free squad on board.</code></p>
<p><code>The two HQs should be entirely separated by water, but still accessible by vehicles thanks to two bridges across the map in different places</code></p>
<p><code>I want to encourage a battle over uplinks.</code></p>
<p><code>The map should be the times the size of other maps - still square</code></p>
<p><code>First research and then critique this design. Only build after we have agreed on any modifications</code></p>
<p><code>You get to design a new biome for this</code></p>
</blockquote>
<p>The result was the tropical <strong>Archipelago</strong> map, with seven island uplinks that players can only capture by flying out infantry in a Condor. It's definitely the most fun map to play, once you've got the hang of the basic game mechanics from the simpler maps. The <a href="https://simonw.github.io/battledrones/v9/">v9 edition</a> made that map a little more interesting - it now looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v8.jpg" alt="Three islands, each with an uplink satellite. Blue holds one, red holds another, A blue condor is flying towards the red island, which is guarded by a red plane. There is a bridge nearby. The theme is tropical islands and looks very pleasant." style="max-width: 100%;" /></p>
<h4 id="v10-goliath-and-agent-battles">v10: Goliath, and agent battles</h4>
<p>I decided to add giant robot mechs to the game - think Jaegers from <a href="https://en.wikipedia.org/wiki/Pacific_Rim_(film)#Plot">Pacific Rim</a>, or Titans from Warhammer 40,000.</p>
<p>Here are some of the prompts I used to brainstorm with Claude:</p>
<blockquote>
<p><code>Help me brainstorm ideas for adding giant robots to this game - think dreadnoughts or titans from W20K - how could we do this in a way that enhanced gameplay, kept things balanced, added unique twist? Don't overthink this yet</code></p>
</blockquote>
<blockquote>
<p><code>Let's keep brainstorming. I like the idea that it's a mobile base - that can accept harvested scrap and can have buildings built near it (even if it later moves on) and can produce infantry units too. An interaction with condor would be neat but I don't know what that could be.</code></p>
</blockquote>
<blockquote>
<p><code>Idea: as it gets damage it loses the ability to fire some weapons - by default it has eye laser (like lancers) and arm canons (like titan) and two shoulder mounted mortars, plus machine guns similar to a squad of troops</code></p>
</blockquote>
<blockquote>
<p><code>Damage knocks out mortars and then laser - it always has guns. You can't build next to a building that was only put there because of the mech, you need the mech there for off-base building and only within three squares of it</code></p>
</blockquote>
<blockquote>
<p><code>[...] Lets do two condors can carry the mech</code></p>
</blockquote>
<p>The end result is <em>really cool</em>.</p>
<video
width="1644"
height="1080"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
style="display: block; width: 100%; height: auto;"
poster="https://static.simonwillison.net/static/2026/goliath-poster.jpg"
>
<source src="https://static.simonwillison.net/static/2026/goliath.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
<p style="margin-top: 1em">Goliaths can be constructed using a Gantry - a building that can only be created after first building a Fab, Bay, Airpad, and Tech Lab. You can see the Goliath under construction, and it then walks out from the Gantry and can march around the map.</p>
<p>Goliaths can "anchor", which digs them into the ground. In their anchored state they can act as a new HQ, constructing infantry units and additional buildings in a new area.</p>
<p>Two Condor aircraft can hook onto a Goliath, at which point it can be flown around the map!</p>
<p>The game now ends when you destroy the enemy's HQ building <em>and</em> any Goliaths they might have built.</p>
<p>There are also a couple of mutators relating to Goliaths:</p>
<ul>
<li>
<strong>Goliath Armada</strong> starts each side with four airborne Goliaths (each with a pair of Condors) and no other units.</li>
<li>
<strong>Robot Love</strong> adds a special rule: if enemy Goliaths get close to each other on the battlefield they fall in love and the game ends in a draw. (Thank Natalie for that one).</li>
</ul>
<h4 id="agent-battles">Agent battles</h4>
<p>The other v10 feature is <strong>agent battles</strong>. In musing about how multiplayer could work I had an idea: what if different LLMs could fight it out in the game?</p>
<blockquote>
<p><code>Fun extra challenge: think about how we might make multiplayer available to coding agents. It would be neat if we could set up a battle between eg GPT-6 Sol and Claude Opus 5.5 where each model has access to a tool which gives them information about the game (presumably non-visual, but only the information they could see through fog of war etc) and lets them control their units etc [...]</code></p>
<p><code>Consult ~/dev/llm/docs and include notes in that file about how LLM could be used here via a new tools plugin</code></p>
</blockquote>
<p>Opus 5.5 went to work on this, producing <a href="https://github.com/simonw/battledrones/blob/7001ed186c8b8aef4acb27f680ecf4c09b607e54/AGENT-BATTLES.md">this AGENT-BATTLES.md proposal</a> and then implementing and testing it. The feature also includes the ability to record and replay these battles - here's <a href="https://simonw.github.io/battledrones/v11/?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json">a replay of Claude Haiku 5.5 vs. GPT-6 Luna</a>, and here's that same battle <a href="https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1">in a separate debug tool</a> that shows the underlying prompt responses.</p>
<p><img src="https://static.simonwillison.net/static/2026/agent-v-agent.jpg" alt="Screenshot of a replay of a real-time strategy game between two AI models, shown from a top-down view of a snowy map with a dark frozen lake of cracked ice floes on the left and pine forests at the top and lower right. Top bar: pause button, &quot;6:27&quot;, &quot;1×&quot;, &quot;anthropic/claude-haiku-5-5 · industry&quot; in blue, &quot;gpt-6-luna · industry&quot; in red, a blue-and-red strength bar labeled &quot;B&quot; and &quot;R&quot;, and &quot;0:03&quot;. Left notification: &quot;Blue: Pushing turrets at the enemy's south-east edge.&quot; Replay panel: &quot;Blue anthropic/claude-haiku-5-5 · industry vs Red gpt-6-luna · industry · frostbite seed 42&quot;, a timeline slider at &quot;6:27 / 7:48&quot;, and buttons &quot;−30s&quot;, &quot;+30s&quot;, &quot;All&quot;, &quot;Blue's eyes&quot;, &quot;Red's eyes&quot;, &quot;Notes&quot;. In the scene, a group of blue tanks and a large blue Goliath mech trailing smoke advance near the ice edge at lower center, while a column of red turrets (one burning) lines the ice to their north, red tanks and trucks sit by a rocky ridge to the east, and red base buildings occupy the top right. A minimap is in the top right corner and zoom in, zoom out and lightning-bolt buttons are on the lower left." style="max-width: 100%;" /></p>
<p>The prompt that drives agent battles <a href="https://github.com/simonw/battledrones/blob/d584e351d9d28c4ba058b78ddcca9b93cd9bcd33/llm-tools-battledrones/llm_tools_battledrones.py#L106-L117">can be seen here</a>.</p>
<p>There are a few more replays like this <a href="https://github.com/simonw/battledrones/blob/main/README.md#watch-ai-models-play-it">linked in the README</a>. I hope to turn this into a full league table at some point in the future.</p>
<h4 id="v11-random-maps">v11: Random Maps</h4>
<p>This version exists purely because I glanced at my <a href="https://claude.ai/new#settings/usage">Claude Usage</a> page one day and saw that I'd only used 75% of my weekly allowance and it was resetting in 45 minutes. I decided to see if I could get an extra Battle Drones feature from my remaining tokens, and picked "random map" as the target:</p>
<blockquote>
<p><code>Design and implement a mechanism for generating a random map using any of the available biomes - it should be the size of the largest map and rivers and bridges and rocks and forest and scrap and crystals are all in play. Make them rotationally symmetric and use a seed to allow them to be selected or reused later. You have 45 minutes to build this! Be creative.</code></p>
</blockquote>
<p>Here's <a href="https://claude.ai/code/session_01CfwMwDaK1kLKnRV6di8VMT">the transcript</a>, and an image Claude generated to show me its work:</p>
<p><img src="https://static.simonwillison.net/static/2026/random-map-contact-sheet.jpg" alt="Grid of ten top-down game maps, two per biome (temperate, desert, arctic, volcanic, tropical), each with a river or lava flow, bridges and roads. Title: &quot;Battle Drones: generated maps (108x108, point-symmetric), 2 per biome, runtime ground painter&quot;. Each map is captioned with a name and layout type plus a seed and crossing counts, e.g. &quot;Hawthorn Delta · fork&quot; &quot;random-temperate-1x8a6r2 · 6 bridges, 4 fords&quot;; layout types are fork, badlands, crossing and lake." style="max-width: 100%;" /></p>
<h4 id="v12-multiplayer-via-sound">v12: Multiplayer via sound</h4>
<p>I only <em>just</em> got this working, so I've not had much time to actively test it yet. The latest Battle Drones now supports multiplayer via two devices sat within microphone distance of each other!</p>
<p>This feature started out as my <a href="https://simonwillison.net/2026/Oct/15/chirp-pong/">Chirp Pong</a> experiment from last week. I pointed Claude Code at that working proof of concept:</p>
<blockquote>
<p><code>Clone Simonw/tools from GitHub and look at recent branches for the example pong game that uses web microphone to implement multiplayer between two phones via audio signals</code></p>
<p><code>Build a version of that for battledrones</code></p>
</blockquote>
<p>Opus built <a href="https://simonw.github.io/battledrones/radio-probe.html">this Radio Probe tool</a> to measure how much bandwidth we could get between two devices and, based on positive results from that, implemented a full audio modem system. I've tried it between laptops, iPhones and iPads so far and it seems to work really well!</p>
<p>Why use sound for this? Because I <a href="https://simonwillison.net/2025/Dec/10/html-tools/#the-anatomy-of-an-html-tool">love static HTML</a> that costs nothing to run, and I don't want to spin up a server somewhere and then stay responsible for keeping it operating for as long as anyone might want to play the game.</p>
<h4 id="some-thoughts">Some thoughts</h4>
<p>I know almost <em>nothing</em> about game development. This makes it a great opportunity to try out coding agents in a field where my existing software engineering experience has less impact on the results.</p>
<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>
<p>This morning (<a href="https://news.ycombinator.com/item?id=50168190">via Hacker News</a>) I found <a href="https://www.ign.com/articles/steam-fans-are-begging-for-a-no-ai-filter-as-steam-next-fest-is-filled-with-slop">Steam Fans Are Begging for a No-AI Filter as Steam Next Fest Is Filled With Slop</a>. I wouldn't personally dream of submitting Battle Drones to an event like this - it's still way too low effort to warrant consideration as a legitimate indie gaming project.</p>
<p>... but I can now see a path to vibe coded games like this being taken seriously. Battle Drones is fun, it looks good, it has innovative features (the multiplayer-over-audio thing is a first for an RTS as far as I can tell).</p>
<p>I'd love to see what someone with better taste than me and a driving passion to produce something truly exceptional could build!</p>
<p>A few other observations from this project:</p>
<ul>
<li>Static HTML and JavaScript is a fantastic medium for games development. WebGL works great, and <a href="https://github.com/mrdoob/three.js/">Three.js</a> (and <a href="https://github.com/phaserjs/phaser">Phaser</a> before it) are excellent platforms to build on that the current models know inside out.</li>
<li>This also lets them run as <a href="https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps">Progressive Web Apps</a> - I didn't ask for it, but Battle Drones works offline. I was able to play it on a plane despite never having directly installed it - my phone had it cached.</li>
<li>Giving Claude an OpenAI API key and telling it to generate images using OpenAI's models works really well. It can view the images it has generated and iterate on the prompts.</li>
<li>Opus 5.5 is spectacular at 3D modeling using Three.js (and Blender, and no doubt other 3D applications as well). The <a href="https://til.simonwillison.net/llms/blender-coding-agents-macos">same is true</a> of GPT-6 Astra. They are absolutely capable of building models for 3D game projects.</li>
<li>For features like replay and multiplayer it's useful to have a deterministic simulation engine. At one point Claude had to replace calls to <code>Math.sin()</code> and <code>Math.cos()</code> and friends with <a href="https://github.com/simonw/battledrones/blob/v12/src/sim/fmath.ts">custom versions</a> because different browsers (Chrome vs. Safari, for example) returned very slightly different numbers, desynchronizing the replay.</li>
<li>Opus 5.5 can write music! There are no audio files in this project - the soundtrack is entirely generated through code, varies across different maps, and even gets more intense as the battle heats up. See <a href="https://simonwillison.net/2026/Oct/6/scrimshaw-jukebox/">Scrimshaw Jukebox</a> for a previous experiment with Claude for music composition.</li>
<li>I still can't get over how well the prompt "Make it a LOT more fun" worked.</li>
<li>Tools are effectively free. I prompted up the <a href="https://simonw.github.io/battledrones/radio-probe.html">Radio Probe</a>, the <a href="https://simonw.github.io/battledrones/models.html">Model browser</a>, the <a href="https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1">Agent vs. Agent debug tool</a>, and Claude Code <a href="https://github.com/simonw/battledrones/tree/main/tools">built a bunch of tools</a> for itself that I haven't even explored myself.</li>
<li>Audio-based multiplayer between static HTML games works! I hope to see a whole lot more games use this same pattern - in digging around today I've not found much prior art beyond <a href="https://github.com/AlonHor/siner">Siner</a> by Alon Horesh and <a href="https://github.com/ggerganov/ggwave">ggwave</a> by Georgi Gerganov (also of <code>llama.cpp</code> fame).</li>
<li>Claude Code "Ultracode" burns tokens like there's no tomorrow, but it can also solve complex problems (like adding audio-based multiplayer) from a single prompt.</li>
<li>I'm still not quite over the <em>guilt</em> of building software in this way. I don't feel like I've earned the right to create something this good, in a field in which I have so little prior experience! At this point I've shown it to enough people in private that it felt wrong not to publish it for everyone else to see and learn from.</li>
</ul>
<h4 id="update-online-multiplayer-support">Update: Online multiplayer support</h4>
<p>Earlier in this article I said:</p>
<blockquote>
<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>
</blockquote>
<p>Then I tried playing the multiplayer version with Natalie... and the high pitched modem sounds gave her a nasty headache!</p>
<p>That's a pretty bad bug. I <a href="https://github.com/simonw/battledrones/pull/36">added a warning</a> and was then inspired to build proper network multiplayer. I tried <a href="https://github.com/simonw/battledrones/pull/37">getting WebRTC to work</a> but couldn't get a connection going between two of my own devices even on my own WiFi network, so <a href="https://github.com/simonw/battledrones/pull/38">I had Claude build</a> a simple, stateless WebSockets relay server instead:</p>
<blockquote>
<p><code>If I wanted to support multiplayer between two devices at a very low cost without storing any state on the server could I do that with a tiny asyncio web server running on the cheapest Fly instance?</code></p>
</blockquote>
<blockquote>
<p><code>Build the server and the fly.toml for deploying it, use Fly application name battledrones-relay - put that in a folder in the repo, include deploy instructions in the README in that folder</code></p>
</blockquote>
<p>Here's <a href="https://github.com/simonw/battledrones/tree/v13/relay">the resulting server</a>. Since this scales to zero and runs on a single <a href="https://fly.io/">Fly.io</a> <code>shared-cpu-1x</code> instance it should cost me no more than $2.19/month - and that's if it stays hot and serving connections the whole time.</p>
<p>Battle Drones now supports online multiplayer. Click "Duel a friend online", then either share the resulting room URL via your messaging app of choice or have them snap a picture of the displayed QR Code.</p>
<p>I also added a feature where you can copy JSON of the match once it has ended and then feed that into the replay feature to rewatch your game.</p>
<p>I didn't expect to introduce online multiplayer this soon, but the headache bug felt like it warranted an urgent alternative.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/vibe-coding">vibe-coding</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p></summary>
<category term="game-design"/>
<category term="projects"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="claude"/>
<category term="vibe-coding"/>
<category term="coding-agents"/>
<category term="claude-code"/>
</entry>
<entry>
<title>My obituary for programming</title>
<link href="https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/" rel="alternate"/>
<published>2026-10-19T23:58:25+00:00</published>
<updated>2026-10-19T23:58:25+00:00</updated>
<id>https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/</id>
<summary type="html"><p><strong><a href="https://dumbmatter.com/2026/10/programming-obituary/">My obituary for programming</a></strong></p>
Jeremy Scheff poignantly captures the key loss caused by coding agents for career programmers who enjoyed the <em>puzzle</em> of developing code:</p>
<blockquote>
<p>Programming turned into one of the greatest jobs you could imagine. You got paid to work on tricky little logic puzzles. The trickier the puzzle, the more you got paid. But even pretty simple puzzles were worth a lot of money because regular people just couldn't do it! No, they needed us. They would give us a problem and we would solve it the way we wanted. We set the strategy, we made the timeline, we defined what was and was not possible.</p>
</blockquote>
<p>If you're a programmer who thrives on building working systems and doesn't care too deeply about the problems solved along the way, LLMs are the gift that keeps on giving.</p>
<p>If directly solving those problems was a big part of your enjoyment, the loss is very real.
<p><small></small>Via <a href="https://lobste.rs/s/wtobpt/my_obituary_for_programming">lobste.rs</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/programming">programming</a>, <a href="https://simonwillison.net/tags/careers">careers</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/deep-blue">deep-blue</a></p></summary>
<category term="programming"/>
<category term="careers"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="coding-agents"/>
<category term="deep-blue"/>
</entry>
<entry>
<title>llm-tools-datasette 0.1.1</title>
<link href="https://simonwillison.net/2026/Oct/18/llm-tools-datasette/" rel="alternate"/>
<published>2026-10-18T23:43:09+00:00</published>
<updated>2026-10-18T23:43:09+00:00</updated>
<id>https://simonwillison.net/2026/Oct/18/llm-tools-datasette/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/llm-tools-datasette/releases/tag/0.1.1">llm-tools-datasette 0.1.1</a></p>
<p>When I switched LLM over to <a href="https://github.com/pydantic/httpx2">httpx2</a> in <a href="https://llm.datasette.io/en/stable/changelog.html#v0-33">LLM 0.33</a> I forget that this would break any plugins which used <code>httpx</code> without directly depending on it. <code>llm-tools-datasette</code> was one of those plugins, now fixed.</p>
<p>Tags: <a href="https://simonwillison.net/tags/datasette">datasette</a>, <a href="https://simonwillison.net/tags/llm">llm</a></p></summary>
<category term="datasette"/>
<category term="llm"/>
</entry>
<entry>
<title>llm-echo 0.5</title>
<link href="https://simonwillison.net/2026/Oct/18/llm-echo/" rel="alternate"/>
<published>2026-10-18T23:16:16+00:00</published>
<updated>2026-10-18T23:16:16+00:00</updated>
<id>https://simonwillison.net/2026/Oct/18/llm-echo/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/llm-echo/releases/tag/0.5">llm-echo 0.5</a></p>
<p>I'm working towards a new <a href="https://llm.datasette.io/">LLM</a> release, and testing PRs caused me to revisit the <code>llm-echo</code> debug plugin. This plugin provides a "model" which doesn't involve an LLM at all - it just repeats back the prompts that have been fed to it. The new release now updates the simulated token usage counts to take tool calls, system prompts, and reasoning tokens into account.</p>
<p>Example usage:</p>
<pre><code>uvx --with llm-echo llm -m echo 'hi there' -o thinking 1 --usage
</code></pre>
<p>Outputs:</p>
<pre><code>First I consider the prompt, then I decide what to say.
{
"prompt": "hi there",
"system": "",
"attachments": [],
"stream": true,
"previous": []
}
Token usage: 2 input, 24 output
</code></pre>
<p>Tags: <a href="https://simonwillison.net/tags/llm">llm</a></p></summary>
<category term="llm"/>
</entry>
<entry>
<title>Inline rendering with document.currentScript</title>
<link href="https://simonwillison.net/2026/Oct/17/document-currentscript/" rel="alternate"/>
<published>2026-10-17T21:11:12+00:00</published>
<updated>2026-10-17T21:11:12+00:00</updated>
<id>https://simonwillison.net/2026/Oct/17/document-currentscript/</id>
<summary type="html"><p><strong><a href="https://leanrada.com/notes/inline-rendering-currentscript/">Inline rendering with document.currentScript</a></strong></p>
Lean Rada describes a neat trick that takes advantage of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript">document.currentScript</a> property. You can use that to drop in a tiny inline <code>&lt;script&gt;</code> element that replaces itself when the page loads:</p>
<pre><code>The year is &lt;script&gt;
document.currentScript.replaceWith(
new Date().getFullYear())&lt;/script&gt;
</code></pre>
<p>If you define a shortcut function like this:</p>
<pre><code>$=(...n)=&gt;document.currentScript.replaceWith(...n)
</code></pre>
<p>You get a tiny template language:</p>
<pre><code>The year is &lt;script&gt;$(new Date().getFullYear())&lt;/script&gt;
</code></pre>
<p>Tags: <a href="https://simonwillison.net/tags/javascript">javascript</a></p></summary>
<category term="javascript"/>
</entry>
<entry>
<title>web-edit 0.1a2</title>
<link href="https://simonwillison.net/2026/Oct/17/web-edit/" rel="alternate"/>
<published>2026-10-17T13:16:49+00:00</published>
<updated>2026-10-17T13:16:49+00:00</updated>
<id>https://simonwillison.net/2026/Oct/17/web-edit/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/web-edit/releases/tag/0.1a2">web-edit 0.1a2</a></p>
<p>web-edit (<a href="https://simonwillison.net/2026/Oct/12/web-edit/">previously</a>) is my tiny web app for browsing and editing files in a folder. I mainly built it for editing files on different machines via Tailscale.</p>
<p>I added a "copy to clipboard" option for both text and image data. I needed this because I was running pelican prompts on a laptop from my phone (here's <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fb1cec9726b6aa62d4de47100f90f0c1a">DeepSeek 4.1 Flash 1017</a>) and I wanted an easy way to copy the resulting logs into a Gist.</p>
<p>Tags: <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/deepseek">deepseek</a></p></summary>
<category term="projects"/>
<category term="pelican-riding-a-bicycle"/>
<category term="deepseek"/>
</entry>
<entry>
<title>Quoting Addy Osmani, Morgan Westlee Lunt, and Qing Wang</title>
<link href="https://simonwillison.net/2026/Oct/16/code-review/" rel="alternate"/>
<published>2026-10-16T22:06:37+00:00</published>
<updated>2026-10-16T22:06:37+00:00</updated>
<id>https://simonwillison.net/2026/Oct/16/code-review/</id>
<summary type="html"><blockquote cite="https://claude.dev/blog/solving-code-review-at-anthropic/"><p>We think "did a human read the code?" is an imprecise proxy for "what could go wrong with this change, and which check—automated or human—is the right one to catch it?"</p>
<p>Asking that question also changed <em>when</em> review happens. Before, review was a gate at the end of the road: write the code, open a PR, wait for your colleague.</p>
<p>Now, review runs continuously, more like spellcheck while you write. Most changes have been reviewed and fixed by Claude at least once before a human is asked to look. This catches most routine mistakes, and saves team attention for higher-level questions and scrutiny.</p></blockquote>
<p class="cite">&mdash; <a href="https://claude.dev/blog/solving-code-review-at-anthropic/">Addy Osmani, Morgan Westlee Lunt, and Qing Wang</a>, How the Claude Code team does code review</p>
<p>Tags: <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/addy-osmani">addy-osmani</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a>, <a href="https://simonwillison.net/tags/code-review">code-review</a></p></summary>
<category term="anthropic"/>
<category term="claude"/>
<category term="ai"/>
<category term="claude-code"/>
<category term="llms"/>
<category term="addy-osmani"/>
<category term="coding-agents"/>
<category term="generative-ai"/>
<category term="agentic-engineering"/>
<category term="code-review"/>
</entry>
<entry>
<title>sparqlite: SPARQL 1.1 inside SQLite, written in Rust</title>
<link href="https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/" rel="alternate"/>
<published>2026-10-16T01:58:00+00:00</published>
<updated>2026-10-16T01:58:00+00:00</updated>
<id>https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/</id>
<summary type="html"><p><strong>Research:</strong> <a href="https://github.com/simonw/research/tree/main/sqlite-sparql-rust#readme">sparqlite: SPARQL 1.1 inside SQLite, written in Rust</a></p>
<p>This research task is really an experiment in running Claude Code for web in "Ultracode" mode, as described in <a href="https://code.claude.com/docs/en/workflows">Orchestrate subagents at scale with dynamic workflows</a> in the Claude Code documentation.</p>
<p>With Ultracode turned on, Claude Code makes aggressive use of dynamic workflows - it generates JavaScript that defines and coordinates a network of subagents to take on complex problems.</p>
<p>My initial prompt was this - I meant "hit the rows directly", the word "delete" was an accidental typo on my phone:</p>
<blockquote>
<p><code>Write a SQLite extension in Rust that implants SPARQL and runs really fast because it can hit the delete rows directly</code></p>
</blockquote>
<p>This caused Claude Code for web to churn for over 12 hours. I checked in on its progress the next day and sent a single follow-up prompt when I noticed how many Rust crates it had built:</p>
<blockquote>
<p><code>Every folder in the crates/ directory needs a README</code></p>
<p><code>Include a tutorial.md teaching users how to install the extension and how to run it in the SQLite CLI and then teaching them SPARQL in addition to how to use the SQLite extension</code></p>
<p><code>Include a script with the tutorial for populating a SQLite database with useful and realistic example data for that tutorial</code></p>
</blockquote>
<p>This project feels like next-level vibe coding - it's not remotely feasible to review the code that was produced here, and even following the documentation is a significant investment in work. I'm not entirely sure what to do with this - I appear to have a full SPARQL implementation in Rust inside SQLite now, but how valuable is that if I created it on a whim and can't (or won't) invest the necessary time to understand what it can do?</p>
<p>Tags: <a href="https://simonwillison.net/tags/rdf">rdf</a>, <a href="https://simonwillison.net/tags/semantic-web">semantic-web</a>, <a href="https://simonwillison.net/tags/sqlite">sqlite</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/rust">rust</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p></summary>
<category term="rdf"/>
<category term="semantic-web"/>
<category term="sqlite"/>
<category term="ai"/>
<category term="rust"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="coding-agents"/>
<category term="claude-code"/>
</entry>
<entry>
<title>Chirp Pong</title>
<link href="https://simonwillison.net/2026/Oct/15/chirp-pong/" rel="alternate"/>
<published>2026-10-15T19:47:52+00:00</published>
<updated>2026-10-15T19:47:52+00:00</updated>
<id>https://simonwillison.net/2026/Oct/15/chirp-pong/</id>
<summary type="html"><p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/chirp-pong">Chirp Pong</a></p>
<p>Another game experiment - I wanted to see if it was feasible to have a two player game on two separate phones running in static HTML where the networking code uses chirps sent via the microphone. It seems to work!</p>
<blockquote>
<p><code>Build a two player competitive pong like game where two players use their phones close to each other and the game state is sent via audio noises which the web microphone API can interpret - but add graphical and gameplay twists to make it a lot more fun and intertwine than pong</code></p>
</blockquote>
<p>Claude Opus 5.5 Extra <a href="https://claude.ai/code/session_019awUnNB7NoYd7noBNAsNdd">in Claude Code</a>.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p></summary>
<category term="game-design"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="claude-code"/>
</entry>
<entry>
<title>Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO</title>
<link href="https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/" rel="alternate"/>
<published>2026-10-15T13:04:03+00:00</published>
<updated>2026-10-15T13:04:03+00:00</updated>
<id>https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/</id>
<summary type="html"><p><strong><a href="https://www.ft.com/content/11632d03-358c-454b-af95-d06d4072932b?syn-25a6b1a6=1">Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO</a></strong></p>
The phrase "told investors" appears four times in this FT article, which reports on Anthropic's day of hosting investors on Wednesday. Lots of details in here from "<a href="https://simonwillison.net/2023/Nov/22/deciphering-clues/#hints-to-look-out-for">people with knowledge of the matter</a>".</p>
<p>Key things I learned from the article:</p>
<ul>
<li>Q1 revenue (Jan/Feb/Mar) was "about $4.8bn"</li>
<li>Q2 (Apr/May/Jun) was $11.5bn</li>
<li>Q3 (Jul/Aug/Sep) was $16.8bn</li>
<li>In Q3: $1.70 in revenue for every $1 spent on "computing power"</li>
<li>Adjusted operating margins (excluding stock-based compensation) were 11%</li>
</ul>
<p>This point about distillation is worth quoting in full (highlight mine):</p>
<blockquote>
<p>The start-up has also clamped down on “distillation” — a controversial practice whereby rival AI labs train their models on the outputs of more advanced ones.</p>
<p>When rival companies “distil” their models from Anthropic’s models, that involves heavy usage and spending.</p>
<p>Anthropic told investors on Wednesday <strong>distillation accounted for 5 per cent to 7 per cent of revenue</strong> and that they had cut it back “materially” in the third quarter of the year, said four people with direct knowledge of the matter.</p>
</blockquote>
<p>Napkin maths says that if distillation was 5% of their Q2 revenue (before they cut it back in Q3) then unnamed "other labs" spent over half a billion dollars distilling Anthropic's models in that quarter!</p>
<p>Also notable: Anthropic appear to no longer be leaning on "annualized run-rate revenue" (<a href="https://simonwillison.net/2026/May/29/anthropic/">previously</a>) in these communications to their investors.
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a></p></summary>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="anthropic"/>
</entry>
<entry>
<title>LaTeX renderer</title>
<link href="https://simonwillison.net/2026/Oct/15/latex/" rel="alternate"/>
<published>2026-10-15T02:07:28+00:00</published>
<updated>2026-10-15T02:07:28+00:00</updated>
<id>https://simonwillison.net/2026/Oct/15/latex/</id>
<summary type="html"><p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/latex">LaTeX renderer</a></p>
<p>Inspired by Paul Ford and Aboard Foundary's new web app <a href="https://tinylittleoffice.com/">Tiny Little Office</a>, which provides a suite of web app content editors (a Word Processor, Outliner, Presentation Builder, Spreadsheet, Calculator, Drawing Tool, Diagram Maker, Animator, Calendar, and Trip Planner).</p>
<p>Tiny Little Office's signature trick is to store all of the document data in the <code>#fragment</code> section of the URL, so every document created using it becomes a bookmarkable and shareable link.</p>
<p>It also has <a href="https://tinylittleoffice.com/llms.txt">an llms.txt file</a> telling agents how to construct URLs that will render as documents. Claude <a href="https://claude.ai/share/239301ff-edde-420e-b433-b9c16fe40a6c">used that file</a> to generate <a href="https://tinylittleoffice.com/#/v1/deck/zXVVdb9tGEHznr1hED2kBSbZcO4UFtIHTuCgQtylstwH6Uq7Io3gRdcfeHS1T_fjtnV1Ssp038r52d2Z2djabZcmmxizpJ78jpnvrerqxCUv0sapsYaixbkM7HzYxS7XZ4ujWls6u65SlwC7aZL1bUmxsabIZHpxMaCmXlnRfG9rVHm~Vvui2xiWykfDK8Ojfc439b5bN6BdP0YQHE6bkPJWceMXR6A8Xhe9cwqFr7Peptm5NXCUT9Kl8klNM3EeyjnrfBVoFv8Nj2TGbaDgU9ZKuHCe_7clXKFVSkMh5Qs2Nluy14nnhtyeTk4fFSWmKzUn_7e~f5_N5LkcfFvlSg1Y~bDkR8omoXrbkLDZ3tS1q4rYl3xqHnCTvvB~vbX2J2k1C7rI8vjzsHSCaEuK3wcRoSmJXknEFrpVZ9r0CWgVeK5QDBBOB1BlkAgCxmry~dgAz~hePj0i1wT5wMnIY_Ohl0FQ~cTN_Aq~yIo~7ZFpaoL5gcc8iOg6bx5QdaHlB8f3Nxykg_pnDpvQ7Rw8cLCuFdyKTSLEF4uQd5QiTS0gTsftDzSHFKZWBd2A5av3sLLAGzPgNqB94AJlV44uN3LmvEVDQl8C88l2iBX14JyS3DUMTY5pjOS0XG14fKjqDcP_qjNlLTVLLLe_o_fWPN1f319MBSN4a4mbtUXi9lbL3ttW81vgQFvcgcIg0XjwwPv7SDjeBhnBqEpW2kGI49HIu4Bw0fqAcGwRdcdMc6O6fXdAKAcBurA9dWSrYR_AjddGIuH1ayqNbvHft1o2N9RTqc5IIUi~5J4fCAHVEXC5jbZBa1TkNheUjdbF3iR_ndGtaw3i_9RYcr1jwdtAPaLQuJrwhGa2MNGdsTdOAI3DxTEii4hH2b2AivFEd_XZ7M4tcGQH_XZ~gjZVB4oak_9~cd6FZ0htaWQkNmRZQCBdj_1zN_iCe7el0dpkLWZDTf7kWmP~p_Yq_YMBNYQZpd7HjBprLp8OpmViHbRpSDKiCDNWLBo9xxpQatQCyM21DLD8rSNQ6uBwKtgU71eGUVj1Fu0dJeZ4rsnplPL7ioL93CTKkf4aiMyFRhIqFi_PLs~y9qRp0aDmIp8fy4vzsIrsR32y5bzzwxtrl6UKCiFgu5hejLNSKozTg2EdjGz11EioV2kYXpM6VgPZsenp6~gSwaKP2IcF_fLeuxfKgoJjkRBKHi8~43Zh~SZ_qXgyYAMTrpJAKwQDD9ErvJ5Qi7amGdBT1lGpuKl1cKf~DwhDDDTxoj3N6HeFVvfSR9pp1ChBVbJs4oPSqtLA3uAN8zWMjqExfaZshma~~zqVmbWqYGN7j1s4_q3l4MSXG7BunwnFwpCQ~tKTrRwy7KI4l940rdXS8BUK7fLR6HlxI29ylIfH8bZkfJ4HYrSRyGBfztk2PJzIBSFpNOI2jtaLLYbs4~KsWK~MGpgAz10G8pHyYTRP0_Xc5EOm~0CmE89L2ihrnoVUxkfRi8sJzHYTonVE_Ua0cR3Shm1H9CXPLNP2XjovGNI3M0_1smG4C4P8">this link to a deck</a> that explains how the URL format works:</p>
<p><img alt="Screenshot of a slide deck editor in a web app with a dark-themed presentation open. The document title field reads &quot;How a Tiny Little Office link works&quot;, with a progress ring, share icon and menu icon at top right. Below is a formatting toolbar with an &quot;Insert&quot; dropdown followed by icon buttons for play, bold, italic, underline, strikethrough, highlight, code, link, superscript, emoji, outdent, indent, layout and color palette. The main canvas shows slide 1 with a blue chain-link icon and the text: &quot;The whole document is the link&quot; &quot;No server, no database, no account&quot; &quot;Everything after the # stays in your browser&quot; and a slide counter &quot;1 / 9&quot;. Below the canvas is a &quot;SPEAKER NOTES&quot; heading. A sidebar on the right shows slide thumbnails. Slide 1 (selected): &quot;The whole document is the link&quot; &quot;No server, no database, no account&quot; &quot;Everything after the # stays in your browser&quot;. Slide 2: &quot;Anatomy of a link&quot; with bullets &quot;tinylittleoffice.com/#/v1/deck/y7Vj...&quot; &quot;v1: the format version&quot; &quot;deck: which app opens it&quot; &quot;y: the mode letter&quot; &quot;7Vj...: the document, compressed and encoded&quot;. Slide 3: &quot;Step 1: write it as text&quot; with bullets &quot;Every document is TLO, a Markdown variant&quot; &quot;Slides split on --- lines&quot; &quot;Charts, drawings and animations are fenced blocks&quot; &quot;This deck is about 1 KB of plain text&quot;. Slide 4: &quot;Step 2: squeeze it&quot; with bullets &quot;Raw DEFLATE, the same algorithm as zip and gzip&quot; &quot;z: plain DEFLATE&quot; &quot;y: DEFLATE with a preset dictionary&quot; &quot;r: no compression at all&quot;." src="https://static.simonwillison.net/static/2026/tiny-little-office.webp" /></p>
<p>Tiny Little Office inspired me <a href="https://claude.ai/code/session_017KJrPqqWVHLqr4E7TLPnpt">to have Claude Code</a> (Opus 5.5 Extra) build a similar tool that works with LaTeX. Here's the sequence of prompts I used:</p>
<blockquote>
<p><code>I want a tool where you can link to it with a fragment hash #code-here and it treats that code as LaTeX and renders it really effectively. It should also support a prefix which means the latex is compressed with a custom compression dictionary optimized for latex. Use the best available latex render library from a CDN (consider WebAssembly too). If loaded without a fragment hash show an editor you can paste latex into and then toggle to a "rendered" view. That rendered view should be bookmarkable. The #fragment view should let you switch to edit source too.</code></p>
</blockquote>
<p>Since it was working in <a href="https://github.com/simonw/tools">my tools repo</a> I told it to take inspiration from the <code>&lt;iframe sandbox="..."&gt;</code> mechanism used by my existing <a href="https://tools.simonwillison.net/markdown-svg-renderer">SVG in Markdown tool</a> as protection against XSS risks:</p>
<blockquote>
<p><code>Safe from XSS? We could run in an iframe sandbox like we do on the SVG markdown render project</code></p>
</blockquote>
<p>I had it copy the Gist/URL loading feature from that tool as well:</p>
<blockquote>
<p><code>We should have an option to load latex from a URL (or gist) similar to the markdown SVG tool</code></p>
</blockquote>
<p>Here's <a href="https://tools.simonwillison.net/latex#~1jZq9DoIwEIB3nuKGbigJJS5svoAOMJuQ4EBEJWJjGHh3765A_8DIQtJfIMdR-n0uCV9l4DOs_p8ua3ZZKK2anOsaTqya9AZnHhMo3qqewKWPMh2SOQOFkhSJtmruY1QungBJFk-cQLsspAF8qgFPWKQ6FmdYdCB7oseX5HVNfgE-HGmM2OPATDfAlCssyLcLGI4BONwZ7E8pby5KWoilFBK0n5T4lMeHgQaMMsYjS6hrG61G4Micmcj2EN48tyVgHpzNKMBEHuxEbV0dZhsJwZB7_Lux0mR4YDc9HTd1bnGaki0V1nr6kGHSI8NAwCWaVjeAPyYUNAYxUZt8k2aKlODPRQq7JIYMS-VKaQwHrMmoxqWeLlT6Ag">an example link</a>. The tool uses <a href="https://github.com/nodeca/pako">Pako 2.1.0</a>, <a href="https://github.com/mathjax/MathJax">MathJax 4.1.3</a>, <a href="https://github.com/arena-ai/faster-latex">faster-latex 0.3.1</a>, and <a href="https://github.com/cure53/DOMPurify">DOMPurify 3.4.16</a>.</p>
<p><img alt="Screenshot of a web app titled &quot;LaTeX renderer&quot; with a split-pane layout. The top bar has an Edit/Rendered toggle, a blue Copy link button, and a Share button. The left pane, labeled LaTeX source with a &quot;Document · faster-latex (WASM)&quot; badge, has a URL/GitHub Gist input with a Load button, a code editor containing a LaTeX document, and rows of example buttons (Quadratic formula, Gaussian integral, Maxwell, Attention, Matrix, Chemistry, Prose, TikZ, Document). The right pane shows the typeset output: a paper titled &quot;Sums of Odd Numbers&quot; by A. Student, with a section stating a theorem that the first n odd numbers sum to n squared, a Proof section with numbered equations, and a bulleted list of small cases." src="https://static.simonwillison.net/static/2026/latex-tool.webp" /></p>
<p>Tags: <a href="https://simonwillison.net/tags/latex">latex</a>, <a href="https://simonwillison.net/tags/paul-ford">paul-ford</a>, <a href="https://simonwillison.net/tags/tools">tools</a>, <a href="https://simonwillison.net/tags/urls">urls</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p></summary>
<category term="latex"/>
<category term="paul-ford"/>
<category term="tools"/>
<category term="urls"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
</entry>
<entry>
<title>Tree Appreciator</title>
<link href="https://simonwillison.net/2026/Oct/14/tree-appreciator/" rel="alternate"/>
<published>2026-10-14T21:23:01+00:00</published>
<updated>2026-10-14T21:23:01+00:00</updated>
<id>https://simonwillison.net/2026/Oct/14/tree-appreciator/</id>
<summary type="html"><p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/tree-appreciator">Tree Appreciator</a></p>
<p>Another game experiment with Claude. This one used the default Claude iPhone app (chat mode, not Claude Code mode), where I prompted Claude Opus 5.5 Max with:</p>
<blockquote>
<p><code>Build a three js game called "Tree appreciator" - it shows you two algorithmically generated trees and the game mechanics is about appreciating the differences between them. Think hard about how to make sure it is both fun and beautiful.</code></p>
</blockquote>
<p>Somewhat embarrassingly given <a href="https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp">my recent talk</a>, I've found that telling Opus 5.5 "make sure it is fun" works uncomfortably well. In this case Claude <a href="https://claude.ai/share/ee7de555-f85c-4ff0-96cb-d51ed5e479e9">crunched for 3 hours and 7 minutes</a> before retuning a cosy little spot-the-difference game with music and animation and achievements that's quite compelling to play.</p>
<p><img alt="Screenshot of a mobile spot-the-difference puzzle game with a dark interface. Header reads &quot;No. 003 Acer autumnalis ‘Hid…&quot; with subtitle &quot;Autumn maple · A country lane in late a…&quot; and icons for sound, a book, and help. Two nearly identical 3D-rendered scenes are stacked vertically, labeled &quot;Fig. i&quot; and &quot;Fig. ii&quot;, each showing a dark-trunked maple tree with red, orange and pale peach leaves, leaves falling through the air, a golden grassy field with a few small rocks, and hazy hills with pine silhouettes under a pale sky. Two differences are circled in blue in both images: circle &quot;a&quot; at the base of the trunk, where Fig. i has a small red mushroom that is missing in Fig. ii, and circle &quot;b&quot; in the right side of the canopy, where Fig. i has a patch of green leaves that are red in Fig. ii. The bottom bar shows &quot;2 of 4&quot;, a reset button, a &quot;Hint&quot; button with three filled and two empty dots, and a score of &quot;1,803&quot;." src="https://static.simonwillison.net/static/2026-10-14/image_crop_1320x2195_w1320_q0.7.webp" /></p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/vibe-coding">vibe-coding</a>, <a href="https://simonwillison.net/tags/three-js">three-js</a></p></summary>
<category term="game-design"/>
<category term="javascript"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="claude"/>
<category term="vibe-coding"/>
<category term="three-js"/>
</entry>
<entry>
<title>AI is mass decompiling games. That's both awesome and scary.</title>
<link href="https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/" rel="alternate"/>
<published>2026-10-14T16:26:53+00:00</published>
<updated>2026-10-14T16:26:53+00:00</updated>
<id>https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/</id>
<summary type="html"><p><strong><a href="https://popcar.bearblog.dev/ai-is-mass-decompiling-games-thats-both-awesome-and-scary/">AI is mass decompiling games. That&#x27;s both awesome and scary.</a></strong></p>
Indie game developer Popcar talks about the recent wave of AI-powered decompilation of existing games, enabling weird mashups between existing games, and producing a boom in game preservation projects to get old games working on new hardware (often in a browser using WebAssembly).</p>
<p>I like how this piece captures both the positives and the negatives of this new development:</p>
<blockquote>
<p>Most people already realized the scary part by now. If AI can decompile games and software, then the entire tech industry is about to explode. Anybody can decompile other software and use it any way they'd like, and nobody can stop them. Companies can steal from competitors. Your paid game or app can be open-sourced against your will. This isn't exclusive to old video games, we can apply this to <em>any</em> software. [...]</p>
<p>This is also a big win for preservation. Old games can be ported, modified, enhanced, and made much more easily accessible than before. [...[</p>
<p>With console makers going all in on digital and games becoming entirely unplayable due to servers shutting down, this is <em>fantastic</em> news. We could own software we bought regardless of what the company thinks.</p>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50088534">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/computer-history">computer-history</a>, <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/webassembly">webassembly</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/ai-ethics">ai-ethics</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a></p></summary>
<category term="computer-history"/>
<category term="game-design"/>
<category term="ai"/>
<category term="webassembly"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="ai-ethics"/>
<category term="coding-agents"/>
</entry>
<entry>
<title>Redesigning source control at Anthropic</title>
<link href="https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/" rel="alternate"/>
<published>2026-10-13T23:00:06+00:00</published>
<updated>2026-10-13T23:00:06+00:00</updated>
<id>https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/</id>
<summary type="html"><p><strong><a href="https://www.anthropic.com/engineering/redesigning-source-control">Redesigning source control at Anthropic</a></strong></p>
Interesting piece from Anthropic describing why and how they built their own custom alternative to Git, based on the dramatic increase in rate of changes to their code after the past six months.</p>
<blockquote>
<p>In May 2026, Anthropic averaged around 2,500 code changes merged per day; as of September, we merged over 30,000 per day.</p>
</blockquote>
<p>They included a chart showing those changes. I <a href="https://claude.ai/share/aefcdd4a-9364-40c1-927a-29bf445894fc">had Claude modify their chart</a> (<a href="https://gist.github.com/simonw/4a16dff066fd9763faf8642f797905be">code here</a>) to add markers for the public releases of each of their models in 2026:</p>
<p><img alt="Stacked bar chart titled “Changes merged per day”, for the Anthropic monorepo, January–September 2026. Each day’s bar is split into pull requests (blue) and antique change requests (orange), with a black line for the 7-day average. Weekdays start at around 1,000 merges in January and climb slowly to about 3,000 by late May. Antique change requests appear in late May, overtake pull requests in mid-June and have almost fully replaced them by mid-July, when weekdays reach 6,000–8,000. A labelled “Quiet week” at the end of July dips below 1,000 a day. After that, growth turns steep: over 10,000 a day by mid-August, about 17,000 in early September, and a peak of 30,401 on Sep 9. Dotted lines mark Claude model releases: Opus 4.6 (Feb 5), Sonnet 4.6 (Feb 17), Mythos Preview (Apr 7), Opus 4.7 (Apr 16), Opus 4.8 (May 28), Fable 5 and Mythos 5 (Jun 9), Sonnet 5 (Jun 30), Opus 5 (Jul 24, just before the quiet week), and Fable 5.1 and Mythos 5.1 (Sep 1)." src="https://static.simonwillison.net/static/2026/anthropic-merges-per-day.webp" /></p>
<p>This shows public release dates, not the date when models became available for Anthropic's internal use. My guess is that the introduction of Fable/Mythos class models is a key factor in the increased coding velocity.</p>
<p>"Antique" is their new code review system. The source control system is called Scion, and sounds to me like a reinvention of centralized source control along the lines of Subversion.</p>
<p>(<strong>Update</strong>: Anthropic credit Google's <a href="https://en.wikipedia.org/wiki/Piper_(source_control_system)">Piper</a> and Meta's <a href="https://sapling-scm.com/">Sapling</a> as "prior art" - it looks like the core concept of "derived data" <a href="https://sunshowers.io/posts/anthropic-mononoke/">was heavily inspired by Mononoke</a>, the server component of Sapling.)</p>
<p>They had some pretty extreme requirements:</p>
<blockquote>
<p>The history of our main branch alone is almost 100 GB, and a <em>compressed</em> working copy is over 25 GB. We perform on the order of 25 million code checkouts per day for CI, before counting developer environments, agent sandboxes, and research jobs. Fetched naively, that would be over 600 PB of git traffic per day.</p>
</blockquote>
<p>The new system was built by a team of seven people, and the migration from Git was completed in five months.</p>
<p>When asked on Hacker News about the lack of offline support, Scion engineer Nick G <a href="https://news.ycombinator.com/item?id=50073633#50079495">replied</a>:</p>
<blockquote>
<p>Since Claude is by far the heaviest user of Scion and is necessarily online, this just wasn't important to do.</p>
</blockquote>
<p>As an aside, I've been trying adversarial review in my own projects recently, where you have a model try and find flaws (I often play Claude and GPT off against each other). This note from the article reflected my own experience with that:</p>
<blockquote>
<p>Anthropic also makes extensive use of adversarial review, and, while this is incredibly effective in many ways, it can also be myopic, so skilled engineers needed to steer Claude away from over-engineering parts of the system in response to hypothetical concerns.</p>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50073633">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/git">git</a>, <a href="https://simonwillison.net/tags/migrations">migrations</a>, <a href="https://simonwillison.net/tags/version-control">version-control</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a></p></summary>
<category term="git"/>
<category term="migrations"/>
<category term="version-control"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="anthropic"/>
<category term="agentic-engineering"/>
</entry>
<entry>
<title>llm-gemini 0.35</title>
<link href="https://simonwillison.net/2026/Oct/13/llm-gemini/" rel="alternate"/>
<published>2026-10-13T22:28:54+00:00</published>
<updated>2026-10-13T22:28:54+00:00</updated>
<id>https://simonwillison.net/2026/Oct/13/llm-gemini/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/llm-gemini/releases/tag/0.35">llm-gemini 0.35</a></p>
<p>I added support to <a href="https://github.com/simonw/llm-gemini">llm-gemini</a> for the <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/">new Gemini 4 Argon</a> model, made available today via the Gemini API and for customers of their $100/month subscription plan.</p>
<p>Here are <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fd741e4420dea14c460f0108ac22dbc26">the low, medium and high pelicans</a>. As expected, they are all excellent: Gemini has a track record of producing great SVGs, and are the only lab where I know their <a href="https://twitter.com/sunjiao123sun_/status/2024555516551372920">staff have invested in SVG specifically</a> (and who have <a href="https://simonwillison.net/2026/Feb/19/gemini-31-pro/#jeff-dean">boasted about their pelicans</a> before.)</p>
<p>Here's the "high" illustration, which cost me 17.166 cents:</p>
<p><img alt="Stylish, accurate bicycle frame. Fish in the basket. Snazzy scarf. Feet on either side of the frame touching the pedals. Spokes, a little hat, a good beak and pouch, a somewhat fierce expression." src="https://static.simonwillison.net/static/2026/gemini-4-argon-high.webp" /></p>
<p>The pricing is interesting. At launch, Argon is $2/million input and $10/million output - the same price as GPT-6 Sol, half the price of Claude Opus 5.5 and 1/5th the price of Claude Fable 5.1 and GPT-6 Astra.</p>
<p>But on December 1st Argon is set to double in price - so it will be the same price as Opus 5.5.</p>
<p>Prices like this aren't really comparable these days since what really matters is how many tokens a model takes to achieve a goal within an agentic harness.</p>
<p>One useful clue for that comes from Artificial Analysis, who publish <a href="https://artificialanalysis.ai/#total-cost-tabs">the total cost to run their benchmark</a> using each model. Argon is looking very good there - costing $2,407 to run the benchmark, putting it close to GLM-5.3 and significantly cheaper than OpenAI, Anthropic, and Meta's latest models.</p>
<p>When the price doubles it will still be a little cheaper than GPT-6 Astra.</p>
<p><img alt="Screenshot of a stacked bar chart from Artificial Analysis comparing dollar costs for 14 AI models, sorted from lowest to highest, with bars colored by provider, the provider's logo beneath each bar and angled model names along the bottom. Logo at top right: Artificial Analysis. A hover tooltip pointing at the Gemini 4 Argon bar reads: Gemini 4 Argon (High), $2,407, Output $313, Reasoning $815, Cache Write $897, Cache Read $264, Non-Cache Input $118, Click for more info. Bars from left to right, with the total above each bar and some segment values printed inside: Qwen3.8 27B (xhigh), $1,336, Alibaba logo; Mistral Large 4 Preview, $1,607, Mistral logo; Gemini 3.8 Flash (high), $1,623, Google logo; Muse Spark 1.3 (max), $2,000, segment $769, Meta logo; Gemini 4 Argon (high), $2,407, segments $815 and $897, Google logo; GLM-5.3 (max), $2,503, segment $790, Z.ai logo; Kimi K3 (max), $3,658, Kimi logo; Qwen3.8 Max (0902), $4,935, segments $893 and $1,441, Alibaba logo; Grok 4.7 (xhigh), $4,967, segments $1,861 and $1,618, xAI logo; GPT-6 Astra (max), $5,324, segments $778 and $978, OpenAI logo; Muse Wonder (max), $5,733, segment $1,748, Meta logo; Claude Sonnet 5.5 (max with fallback), $7,260, segments $1,216 and $1,815, Anthropic logo; Claude Opus 5.5 (max with fallback), $8,708, segment $921, Anthropic logo; Claude Fable 5.1 (max with fallback), $13,129, segment $7,219, Anthropic logo." src="https://static.simonwillison.net/static/2026/gemini-4-argon-artificial-analysis.webp" /></p>
<p><small>(I <a href="https://chatgpt.com/share/6acebe13-5378-83e8-bf2f-9f4d05b206f4">used ChatGPT to edit that chart</a>! The data is all correct, I checked - I needed to get that Gemini 4 Argon info box to display without overlapping the other numbers.)</small></p>
<p>Some bonus examples using Gemini 4 Argon: here's <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9589ff9e0c977bbf3b012b7a11f5bd71">Generate an SVG of an armadillo in fishnet tights jaywalking on Mars</a>, here's <a href="https://tools.simonwillison.net/blender-viewer?url=https%3A%2F%2Fstatic.simonwillison.net%2Fstatic%2Fcors-allow%2F2026%2Fgemini-4-astra-egg.blend">a Fabergé egg</a> it created for me using Blender, and DeepMind staffer @fofrAI shared <a href="https://twitter.com/fofrai/status/2110043023954284889">a video of a pelican riding a bike, using fourier epicycles</a>. That's a fun new twist!</p>
<p>Tags: <a href="https://simonwillison.net/tags/google">google</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm">llm</a>, <a href="https://simonwillison.net/tags/gemini">gemini</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a></p></summary>
<category term="google"/>
<category term="ai"/>
<category term="generative-ai"/>
<category term="llms"/>
<category term="llm"/>
<category term="gemini"/>
<category term="llm-pricing"/>
<category term="pelican-riding-a-bicycle"/>
<category term="llm-release"/>
</entry>
<entry>
<title>Quoting Geoffrey Huntley</title>
<link href="https://simonwillison.net/2026/Oct/13/geoffrey-huntley/" rel="alternate"/>
<published>2026-10-13T13:32:00+00:00</published>
<updated>2026-10-13T13:32:00+00:00</updated>
<id>https://simonwillison.net/2026/Oct/13/geoffrey-huntley/</id>
<summary type="html"><blockquote cite="https://ghuntley.com/agency/"><p>If the agent isn't using my diagnostics library, I could introspect and update AGENTS.md, but there's still a delta, and it'll drift. Instead, I write a pre-commit hook that checks the git diff for direct calls to observability modules that bypass my diagnostics module. Boom: fail the commit, inject a prompt telling the agent to use the diagnostics library. All of a sudden it's ten out of ten.</p></blockquote>
<p class="cite">&mdash; <a href="https://ghuntley.com/agency/">Geoffrey Huntley</a>, nobody should type code by hand anymore. here's what's left.</p>
<p>Tags: <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/git">git</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/geoffrey-huntley">geoffrey-huntley</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p></summary>
<category term="coding-agents"/>
<category term="generative-ai"/>
<category term="git"/>
<category term="agentic-engineering"/>
<category term="ai"/>
<category term="geoffrey-huntley"/>
<category term="llms"/>
</entry>
<entry>
<title>web-edit 0.1a1</title>
<link href="https://simonwillison.net/2026/Oct/13/web-edit/" rel="alternate"/>
<published>2026-10-13T01:40:05+00:00</published>
<updated>2026-10-13T01:40:05+00:00</updated>
<id>https://simonwillison.net/2026/Oct/13/web-edit/</id>
<summary type="html"><p><strong>Release:</strong> <a href="https://github.com/simonw/web-edit/releases/tag/0.1a1">web-edit 0.1a1</a></p>
<p>Includes <a href="https://github.com/simonw/web-edit/pull/1">performance optimizations</a> written <a href="https://claude.ai/code/session_01LE2R4P74P9GGUbE6yQ5YBt">by Claude Opus 5.5</a> after I fed it <a href="https://simonwillison.net/2026/Oct/12/python-3-15-web-edit-profiling/">this Python 3.15 profiling report</a> generated by GPT-6 Astra.</p>
<p>Tags: <a href="https://simonwillison.net/tags/profiling">profiling</a>, <a href="https://simonwillison.net/tags/projects">projects</a></p></summary>
<category term="profiling"/>
<category term="projects"/>
</entry>
</feed>
Raw text
<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/atom/everything/" rel="self"/><id>http://simonwillison.net/</id><updated>2026-10-26T23:53:07+00:00</updated><author><name>Simon Willison</name></author><entry><title>GPT-6.1 Terra</title><link href="https://simonwillison.net/2026/Oct/26/gpt-61-terra/" rel="alternate"/><published>2026-10-26T23:53:07+00:00</published><updated>2026-10-26T23:53:07+00:00</updated><id>https://simonwillison.net/2026/Oct/26/gpt-61-terra/</id><summary type="html">
<p><strong><a href="https://openai.com/index/introducing-gpt-6-1-terra/">GPT-6.1 Terra</a></strong></p>
It's always interesting to note which aspects of a new model are emphasized in the release announcement.</p>
<p>In the case of GPT-6.1 Terra, OpenAI went with visual reasoning and computer use:</p>
<blockquote>
<p>We’re introducing <strong>GPT-6.1 Terra</strong>, a fast, efficient model that combines detailed visual reasoning and precise computer use alongside clearer, more natural writing. A significant step up from GPT‑5.6 Terra, it excels at the communication and computer-based tasks that fill the workday, from drafting proposals and interpreting technical drawings to filling out forms and editing videos.</p>
</blockquote>
<p>Terra sits in the same position as Sonnet in the Anthropic model collection - not the cheapest or the most expensive, making it harder to decide when to use it.</p>
<p>Computer use is a good example of a task that benefits from a less expensive model, since you might put it to work on automated, repetitive tasks.</p>
<p>OpenAI's Ted Sanders provided some useful advice in <a href="https://news.ycombinator.com/item?id=50248124#50249160">a comment</a> on Hacker News:</p>
<blockquote>
<p>In the case of GPT-6.1 Terra, I'd say Terra is probably better than Astra and Sol at technical communication, similar on vision and computer use (but much faster!), and a bit worse on most other things. For API developers, it's a nice midrange option if you want something cheaper than Sol but a lot smarter than Luna (especially for vision / computer use / communication). For subscribers, it's not a bombshell release - if you're hitting usage limits, maybe it helps you go a bit further, and if you want clearer communication or faster computer use, it can be a nice option to select.</p>
</blockquote>
<p>Here are <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e">the pelicans</a> for the different reasoning levels. This pelican <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e#reasoning-2">for "max"</a> cost <a href="https://www.llm-prices.com/#it=16&amp;ot=22629&amp;sel=gpt-6.1-terra">11.3161 cents</a> and took 4 minutes and 11 seconds:</p>
<p><img alt="It's a good pelican and a good bicycle - correctly shaped frame, feet n pedals either side of the frame, has the same color scheme as the others in the GPT-6 and GPT-6.1 families." src="https://static.simonwillison.net/static/2026-10-26/terra-max.webp" /></p>
<p>Here's <a href="https://static.simonwillison.net/static/2026/openai-pelicans-october-2026.html">a new comparison grid</a> showing pelicans for every reasoning level of OpenAI's current frontier lineup: GPT-6 Astra, GPT-6.1 Sol, GPT-6.1 Terra, and GPT-6 Luna.</p>
<p>GPT-6.1 Terra is priced at $1/million input tokens and $5/million output - almost half the price of GPT-5.6 Terra and GPT-6.1 Sol, and around 10x the price of GPT-6 Luna.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50248124">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/openai">openai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a>, <a href="https://simonwillison.net/tags/gpt">gpt</a></p>
</summary><category term="ai"/><category term="openai"/><category term="generative-ai"/><category term="llms"/><category term="llm-pricing"/><category term="pelican-riding-a-bicycle"/><category term="llm-release"/><category term="gpt"/></entry><entry><title>Quoting Jason Koebler</title><link href="https://simonwillison.net/2026/Oct/26/jason-koebler/" rel="alternate"/><published>2026-10-26T19:00:25+00:00</published><updated>2026-10-26T19:00:25+00:00</updated><id>https://simonwillison.net/2026/Oct/26/jason-koebler/</id><summary type="html">
<blockquote cite="https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/"><p>Because big tech platforms essentially do not have customer support and make it impossible for their users to contact a human, many people experiencing run-of-the-mill tech problems have turned to ChatGPT. And, increasingly, ChatGPT is telling people that have normal tech support problems that they have discovered something journalistically notable and that 404 Media, specifically, can help them.</p></blockquote>
<p class="cite">&mdash; <a href="https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/">Jason Koebler</a>, ChatGPT Keeps Telling People 404 Media Can Solve Their Tech Support Problems</p>
<p>Tags: <a href="https://simonwillison.net/tags/jason-koebler">jason-koebler</a>, <a href="https://simonwillison.net/tags/openai">openai</a>, <a href="https://simonwillison.net/tags/journalism">journalism</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/ai-ethics">ai-ethics</a>, <a href="https://simonwillison.net/tags/ai-misuse">ai-misuse</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/chatgpt">chatgpt</a>, <a href="https://simonwillison.net/tags/404-media">404-media</a></p>
</summary><category term="jason-koebler"/><category term="openai"/><category term="journalism"/><category term="ai"/><category term="llms"/><category term="ai-ethics"/><category term="ai-misuse"/><category term="generative-ai"/><category term="chatgpt"/><category term="404-media"/></entry><entry><title>webframe: evaluated as a scraper and a sandbox</title><link href="https://simonwillison.net/2026/Oct/26/webframe-evaluation/" rel="alternate"/><published>2026-10-26T16:15:00+00:00</published><updated>2026-10-26T16:15:00+00:00</updated><id>https://simonwillison.net/2026/Oct/26/webframe-evaluation/</id><summary type="html">
<p><strong>Research:</strong> <a href="https://github.com/simonw/research/tree/main/webframe-evaluation#readme">webframe: evaluated as a scraper and a sandbox</a></p>
<p><a href="https://github.com/tractordev/webframe">webframe</a> is a neat little project from Jeff Lindsay which lets you "run a web page like a program" - you point it at a URL or file and it executes it in a hidden headless web view and outputs <code>console.log()</code> to standard output and any exceptions to standard error.</p>
<p>It's written in Go on top of the <a href="https://github.com/crgimenes/glaze">glaze</a> library, which provides access to a system browser ("WKWebView on macOS, WebKitGTK on Linux, WebView2 on Windows") so it doesn't need to bundle its own browser engine.</p>
<p>It reminds me of my own <a href="https://shot-scraper.datasette.io/en/stable/javascript.html">shot-scraper javascript</a> tool, albeit in a much smaller package that doesn't depend on Playwright.</p>
<p>I had Claude Opus 5.5 <a href="https://claude.ai/code/cshk_01MX3aJH8vDGmGSj1xH9BYhj2HviVvLDaJbiELHyDoReYT">put it through its paces</a> and prepare a research report for me. Here's the prompt I used:</p>
<blockquote>
<p><code>Explore https://github.com/tractordev/webframe try running it and put it though its paces, build a few exploratory prototypes, then evaluate it as a potential sandboxing tool and as a tool for scraping web pages using the same patterns encouraged by the "shot-scraper JavaScript" command (see simonw/shot-scraper on GitHub, docs directory)</code></p>
</blockquote>
<p>Tags: <a href="https://simonwillison.net/tags/browsers">browsers</a>, <a href="https://simonwillison.net/tags/go">go</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a>, <a href="https://simonwillison.net/tags/jeff-lindsay">jeff-lindsay</a>, <a href="https://simonwillison.net/tags/shot-scraper">shot-scraper</a></p>
</summary><category term="browsers"/><category term="go"/><category term="javascript"/><category term="jeff-lindsay"/><category term="shot-scraper"/></entry><entry><title>Seam Cutter</title><link href="https://simonwillison.net/2026/Oct/25/seam-cutter/" rel="alternate"/><published>2026-10-25T15:10:19+00:00</published><updated>2026-10-25T15:10:19+00:00</updated><id>https://simonwillison.net/2026/Oct/25/seam-cutter/</id><summary type="html">
<p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/seam-cutter">Seam Cutter</a></p>
<p>I built this weird and very specific cropping tool - it lets you create a horizontal or vertical cut across an image, then slide the two sides relative to each other. Effectively it lets you crop out a section in the middle of an image.</p>
<p>I wanted this because I often use <a href="https://apps.apple.com/us/app/tailor-screenshot-stitching/id926653095">Tailor</a> on my iPhone to stitch several screenshots together into lot long image, but sometimes I find myself wanting to crop out a section in the middle - to redact an irrelevant prompt from a transcript, for example.</p>
<p>Tags: <a href="https://simonwillison.net/tags/tools">tools</a></p>
</summary><category term="tools"/></entry><entry><title>battledrones v14: Compass Rose, a four player map</title><link href="https://simonwillison.net/2026/Oct/24/battledrones/" rel="alternate"/><published>2026-10-24T03:59:57+00:00</published><updated>2026-10-24T03:59:57+00:00</updated><id>https://simonwillison.net/2026/Oct/24/battledrones/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/battledrones/releases/tag/v14">battledrones v14: Compass Rose, a four player map</a></p>
<p>I added four player online mode to <a href="https://simonwillison.net/2026/Oct/20/battledrones/">Battledrones</a> - previous maps were limited to two.</p>
<p>Here's the initial prompt I used: </p>
<blockquote>
<p><code>Add a new map for a four player battle - four way rotational symmetry, up to four AI players, works with the WebSocket non-audio based multiplayer mode so up to four human players can join (any spare slots use AI)</code></p>
</blockquote>
<p>Claude Opus 5.5 added a new map called "Compass Rose" and modified the WebSockets multiplayer network code to support up to four players for that map, joining via share links or QR codes.</p>
<p><img alt="The new map does indeed look a bit like a rose - it uses the cold and ice biome. Also shown are purple robots battling on the map." src="https://raw.githubusercontent.com/simonw/battledrones/v14/progress-shots/v14/compass-rose.jpg" /></p>
<p>The new teams use robots themed in purple and green, joining the existing blue and red designs. You can preview those colors in <a href="https://simonw.github.io/battledrones/models.html">the updated model browser</a>.</p>
<p>Here's <a href="https://simonw.github.io/battledrones/v14/?replay=https://gist.githubusercontent.com/simonw/faa550a002b25a78f1c88a64217786c1/raw/4ff9b03de71d757cd33eb5d1a0e388155b6c20e5/compass.json">a replay link</a> to watch a four way AI battle with the "Goliath Armada" mutator turned on, where each side starts with four giant Goliath mech units.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/claude">claude</a></p>
</summary><category term="game-design"/><category term="projects"/><category term="claude"/></entry><entry><title>Quick Study</title><link href="https://simonwillison.net/2026/Oct/23/quick-study-painter/" rel="alternate"/><published>2026-10-23T21:35:13+00:00</published><updated>2026-10-23T21:35:13+00:00</updated><id>https://simonwillison.net/2026/Oct/23/quick-study-painter/</id><summary type="html">
<p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/quick-study-painter">Quick Study</a></p>
<p>Prompt <a href="https://claude.ai/share/71adda96-193f-4f2a-97c0-454e08066afb">to Claude Opus 5.5 High</a>:</p>
<blockquote>
<p><code>Build an artifact where you open a photo and it rapidly (in a few seconds) paints a version of that photo using a canvas element and simulated paintbrush</code></p>
</blockquote>
<p>See also <a href="https://simonwillison.net/2026/Aug/25/pelican-watercolor/">my previous experiment</a> getting Claude Fable to simulate a watercolor illustration with P5.js.</p>
<p><img alt="A simulated oil painting of a photograph of a heron" src="https://static.simonwillison.net/static/2026/heron-oil.webp" /></p>
<p>Quick Study uses <a href="https://en.wikipedia.org/wiki/Sobel_operator">Sobel edge detection</a>, with no external libraries beyond Google Fonts.</p>
<p>Tags: <a href="https://simonwillison.net/tags/tools">tools</a></p>
</summary><category term="tools"/></entry><entry><title>Introducing Kimi K3.1 Pro</title><link href="https://simonwillison.net/2026/Oct/23/kimi-k31-pro/" rel="alternate"/><published>2026-10-23T19:40:54+00:00</published><updated>2026-10-23T19:40:54+00:00</updated><id>https://simonwillison.net/2026/Oct/23/kimi-k31-pro/</id><summary type="html">
<p><strong><a href="https://www.kimi.ai/blog/kimi-k3-1-pro">Introducing Kimi K3.1 Pro</a></strong></p>
Kimi K3.1 Pro landed on the Kimi API today - it's not yet open weights, but Moonshot promise "Full model weights will be released by Nov 4, 2026".</p>
<p>They're also offering a "Highspeed" version that's 2-3x faster, at twice the price (except for input token cache hits, which are priced the same).</p>
<p>The <a href="https://platform.kimi.ai/docs/pricing/chat">US dollar pricing</a> is $2.00/million tokens for input and $10/million for output - the same as GPT-6.1 Sol and half the price of Claude Opus 5.5.</p>
<p>Moonshot's own benchmarks show Kimi as approximately level with Opus 5.5 and GPT-6 Astra - beating them on a few benchmarks, coming close on others.</p>
<p>Artificial Analysis <a href="https://artificialanalysis.ai/models/kimi-k3-1-pro">scored Kimi at 55</a> - ahead of Claude Fable 5.1, GPT-6 Astra, and Gemini 4 Argon (all at 53) and behind only Claude Opus 5.5 (58).</p>
<p>This is the first time a (soon-to-be) open weight model has scored this highly against the frontier.</p>
<p>I tried it out via the <a href="https://platform.kimi.ai/docs/get-your-api-key">Moonshot API</a> using the <a href="https://llm.datasette.io/en/stable/other-models.html#openai-endpoint">llm openai endpoint</a> command I added to <a href="https://llm.datasette.io/en/stable/changelog.html#v0-32">LLM 0.32</a> back in August:</p>
<pre><code>llm openai endpoint \
https://api.moonshot.ai/v1 \
--key kimi \
-m kimi-k3.1-pro \
"Generate an SVG of a pelican riding a bicycle" \
--responses \
-o reasoning_effort low \
&gt; kimi-k3.1-pro-pelican-low.stdout.txt \
2&gt; kimi-k3.1-pro-pelican-low.stderr.txt
</code></pre>
<p><code>llm openai endpoint</code> can run prompts against any OpenAI-compatible endpoint but doesn't log the results, hence the extra options to save stdout and stderr (the reasoning trace).</p>
<p>Here <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9b7181492209387da1d4f53002f26663">are the pelicans</a> I got for Kimi K3.1 Pro on the three reasoning levels it supports - low, medium, and max. This is max:</p>
<p><img alt="It's pretty solid - feet are on the pedals, bicycle frame is good, nice beak. Both legs are on the same side of the Fram though." src="https://static.simonwillison.net/static/2026-10-23/image-2.png" /></p>
<p>For comparison, I ran fresh <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Feba9a4283c9e94cbbb5325902a3921a8">pelicans against Kimi K3</a> on those three reasoning levels.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50212065">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm">llm</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a>, <a href="https://simonwillison.net/tags/ai-in-china">ai-in-china</a>, <a href="https://simonwillison.net/tags/moonshot">moonshot</a>, <a href="https://simonwillison.net/tags/kimi">kimi</a></p>
</summary><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="llm"/><category term="llm-pricing"/><category term="pelican-riding-a-bicycle"/><category term="llm-release"/><category term="ai-in-china"/><category term="moonshot"/><category term="kimi"/></entry><entry><title>DE STAAT - FREEDOM (Official Music Video)</title><link href="https://simonwillison.net/2026/Oct/22/de-staat-freedom/" rel="alternate"/><published>2026-10-22T19:42:26+00:00</published><updated>2026-10-22T19:42:26+00:00</updated><id>https://simonwillison.net/2026/Oct/22/de-staat-freedom/</id><summary type="html">
<p><strong><a href="https://www.youtube.com/watch?v=hKO4pQtIXow">DE STAAT - FREEDOM (Official Music Video)</a></strong></p>
OK well this is a first for me... at <a href="https://www.youtube.com/watch?v=hKO4pQtIXow&amp;t=44s">00:44</a> in this new music video by Dutch alternative rock band <a href="https://en.wikipedia.org/wiki/De_Staat">De Staat</a>:</p>
<p><video
src="https://static.simonwillison.net/static/2026/freedom-pelican.mp4"
poster="https://static.simonwillison.net/static/2026/freedom-pelican-poster.jpg"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
width="1280"
height="720"
style="display: block; width: 100%; height: auto;"
> </video>
</p>
<p>The visual effects are credited to Matties Grooten of <a href="https://fakeitorleaveit.com">Fake it or Leave it</a>.
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50186129#50193407">flir on Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/music">music</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a></p>
</summary><category term="music"/><category term="ai"/><category term="generative-ai"/><category term="pelican-riding-a-bicycle"/></entry><entry><title>Donating Agent Skills to the Agentic AI Foundation</title><link href="https://simonwillison.net/2026/Oct/22/donating-agent-skills/" rel="alternate"/><published>2026-10-22T18:09:56+00:00</published><updated>2026-10-22T18:09:56+00:00</updated><id>https://simonwillison.net/2026/Oct/22/donating-agent-skills/</id><summary type="html">
<p><strong><a href="https://www.anthropic.com/news/donating-agent-skills-to-the-agentic-ai-foundation">Donating Agent Skills to the Agentic AI Foundation</a></strong></p>
News today from Anthropic:</p>
<blockquote>
<p>We’re committed to keeping Agent Skills open, community-driven, and vendor-neutral. Today, we are donating the standard to the Agentic AI Foundation (AAIF) under the Linux Foundation, <a href="https://www.anthropic.com/news/donating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation">which we co-founded</a> with Block and OpenAI last year, and to which we donated the Model Context Protocol (MCP).</p>
</blockquote>
<p>I'm pleased to note I called this one <a href="https://simonwillison.net/2025/Dec/19/agent-skills/">last December</a>, when Anthropic first declared skills to be an "open standard":</p>
<blockquote>
<p>I wouldn't be surprised to see this end up <a href="https://simonwillison.net/2025/Dec/9/agentic-ai-foundation/">in the AAIF</a>, recently the new home of the MCP specification.</p>
</blockquote>
<p>Fun side note: since my blog content is available to Claude via the <a href="https://github.com/datasette/datasette-mcp">datasette-mcp</a>
plugin I found that post by <a href="https://claude.ai/share/80b341de-590b-4834-bca9-0d9c9a3a0298">prompting Claude</a> to "<code>Use simonwillison.net MCP to find if I ever talked about how I want skills to be donated to a standards body</code>".
<p>Tags: <a href="https://simonwillison.net/tags/standards">standards</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/model-context-protocol">model-context-protocol</a>, <a href="https://simonwillison.net/tags/skills">skills</a></p>
</summary><category term="standards"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="anthropic"/><category term="model-context-protocol"/><category term="skills"/></entry><entry><title>Quoting Armin Ronacher</title><link href="https://simonwillison.net/2026/Oct/22/armin-ronacher/" rel="alternate"/><published>2026-10-22T15:34:13+00:00</published><updated>2026-10-22T15:34:13+00:00</updated><id>https://simonwillison.net/2026/Oct/22/armin-ronacher/</id><summary type="html">
<blockquote cite="https://twitter.com/mitsuhiko/status/2113207589978636646"><p>As fun as AI is, we built so much bad software over the last 30 years, and now the universe is punishing us for our sins.</p></blockquote>
<p class="cite">&mdash; <a href="https://twitter.com/mitsuhiko/status/2113207589978636646">Armin Ronacher</a></p>
<p>Tags: <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/armin-ronacher">armin-ronacher</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/ai-security-research">ai-security-research</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p>
</summary><category term="security"/><category term="generative-ai"/><category term="armin-ronacher"/><category term="ai"/><category term="ai-security-research"/><category term="llms"/></entry><entry><title>Today's PHP Security Release, and How We're Strengthening PHP Security</title><link href="https://simonwillison.net/2026/Oct/21/php-security-release/" rel="alternate"/><published>2026-10-21T18:41:53+00:00</published><updated>2026-10-21T18:41:53+00:00</updated><id>https://simonwillison.net/2026/Oct/21/php-security-release/</id><summary type="html">
<p><strong><a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/">Today&#x27;s PHP Security Release, and How We&#x27;re Strengthening PHP Security</a></strong></p>
If you're running anything on PHP it's vital you upgrade - today's updates (across the entire PHP 8.x line) address two remote code execution holes, and there have been exploits circulating since last night, thanks to a leak in the coordinated disclosure process.</p>
<p>This post from the PHP Foundation explain what went so wrong:</p>
<blockquote>
<p>On Tuesday, October 20th, at around 15:00 UTC, the two CVE IDs began circulating on online forums and social media. They came with a wrong release time and a wrong CVSS score of 10.0 (the actual score is 9.2). No technical details leaked. In response, the PHP project brought its pre-announcement forward and <a href="https://www.php.net/archive/2026.php#2026-10-20-1">published it at 19:30 UTC</a>. It also moved the release from October 22nd, 14:00 UTC, to October 21st, 14:00 UTC [...]</p>
<p>As a result of the leak and pre-announcement around 20:00 UTC, Calif, one of the security firms that had reported the issues mistakenly published a video. It showed their proof of concept working against a number of targets and revealed a few additional, though limited, details about the vulnerabilities. Copies of the deleted video started circulating on social media soon after. The video contributed to accelerated development of various PoCs (exploitation proof of concepts), which then increased circulation on October 21st.</p>
</blockquote>
<p><a href="https://www.wiz.io/blog/php2shell-php-rce">This article</a> from the team that discovered the original vulnerability includes a more detailed timeline of the original intended responsible disclosure:</p>
<blockquote>
<ul>
<li><strong>August 19, 2026:</strong> Wiz Research discovers the first PHP vulnerability using Wiz Atlas, Gemini 4 Argon, and GPT-5.6 Sol.</li>
<li><strong>August 20, 2026:</strong> Unauthenticated RCE is confirmed against Drupal.</li>
<li><strong>August 21, 2026:</strong> Unauthenticated RCE is confirmed against WordPress.</li>
<li><strong>August 24, 2026:</strong> Wiz Research reports the vulnerabilities to the PHP security team.</li>
<li><strong>September 21, 2026:</strong> PHP acknowledges the reports and begins developing a coordinated fix.</li>
<li><strong>October 21, 2026:</strong> Patched PHP releases become available.</li>
<li><strong>October 21, 2026:</strong> Public disclosure.</li>
</ul>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50182987">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/open-source">open-source</a>, <a href="https://simonwillison.net/tags/php">php</a>, <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/ai-security-research">ai-security-research</a></p>
</summary><category term="open-source"/><category term="php"/><category term="security"/><category term="ai"/><category term="ai-security-research"/></entry><entry><title>Panache — RTS Belle Époque pour mobile</title><link href="https://simonwillison.net/2026/Oct/21/panache/" rel="alternate"/><published>2026-10-21T16:25:16+00:00</published><updated>2026-10-21T16:25:16+00:00</updated><id>https://simonwillison.net/2026/Oct/21/panache/</id><summary type="html">
<p><strong><a href="https://github.com/menufactory43/panache/">Panache — RTS Belle Époque pour mobile</a></strong></p>
Well this is delightful: I <a href="https://simonwillison.net/2026/Oct/20/battledrones/">released Battle Drones</a> yesterday under an Apache 2.0 License and there's already a French language fork which reskins the game to take place in steampunk 1900s France and adds an animated intro!</p>
<blockquote>
<p><strong>Panache</strong> est un jeu de stratégie en temps réel pour mobile et navigateur, dans la France de la Belle Époque (vers 1900) : dirigeables, Fardiers à vapeur, Creusot cuirassés, automates en képi, Gargantua la forteresse marchante — et beaucoup de panache.</p>
</blockquote>
<p>You can <a href="https://menufactory43.github.io/panache/">play Panache here</a> - it's worth clicking that link just to experience the new intro video.</p>
<p>So far it's mostly just aesthetic updates as opposed to gameplay changes. The music has had a French twist added to it as well.</p>
<p>The new steampunk models are so cool!</p>
<p><img alt="The new buildings are gold and red, there are dirigibles and biplanes, and the Goliath stomping mech has had a total makeover." src="https://static.simonwillison.net/static/2026/battledrones-french.jpg" /></p>
<p>Here's a page with <a href="https://simonw.github.io/battledrones/models.html">the original Battle Drones models</a> and that same page <a href="https://menufactory43.github.io/panache/models.html">with the new Panache alternatives</a>.</p>
<p>This is a comparison of the original and the new design for the Goliath:</p>
<p><img alt="On the left: blue stomping mech robot, missile launcher shoulders, classic sci-fi robot look. On the right: gold, steampunk, much more 1900s French look." src="https://static.simonwillison.net/static/2026/battledrones-goliath-diff.jpg" />
<p><small></small>Via <a href="https://twitter.com/Meffysto69/status/2112908755654365220">@Meffysto69</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/open-source">open-source</a></p>
</summary><category term="game-design"/><category term="open-source"/></entry><entry><title>eMudhra Intermediate CA Compromise</title><link href="https://simonwillison.net/2026/Oct/20/emudhra-certificates/" rel="alternate"/><published>2026-10-20T23:50:25+00:00</published><updated>2026-10-20T23:50:25+00:00</updated><id>https://simonwillison.net/2026/Oct/20/emudhra-certificates/</id><summary type="html">
<p><strong><a href="https://emudhra.we-have-a-problem.com">eMudhra Intermediate CA Compromise</a></strong></p>
This is very, very bad news:</p>
<blockquote>
<p>The private keys of eight eMudhra intermediate CA certificates have been compromised. They chain to roots trusted by the Mozilla, Microsoft, Apple and Chrome root programs and by many downstream trust stores.</p>
</blockquote>
<p>Any software that bundles a list of trusted certificates needs to be updated. This site is tracking software updates <a href="https://github.com/galadran/we-have-a-problem.com">via this GitHub repository</a> - Linux distros need to update their <code>ca-certificates</code> packages.</p>
<p>In Python world <a href="https://github.com/astral-sh/uv/releases/tag/0.13.4">uv 0.13.4</a> and <a href="https://github.com/pypa/pip/releases/tag/26.2.2">pip 26.2.2</a> and <a href="https://github.com/certifi/python-certifi/releases/tag/2026.10.19">certifi 2026.10.19</a> have been released with upgraded certificate lists.</p>
<p>There's a <a href="https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576">very informative thread</a> about this on the official Python forum.
<p>Tags: <a href="https://simonwillison.net/tags/encryption">encryption</a>, <a href="https://simonwillison.net/tags/https">https</a>, <a href="https://simonwillison.net/tags/pip">pip</a>, <a href="https://simonwillison.net/tags/python">python</a>, <a href="https://simonwillison.net/tags/security">security</a>, <a href="https://simonwillison.net/tags/uv">uv</a></p>
</summary><category term="encryption"/><category term="https"/><category term="pip"/><category term="python"/><category term="security"/><category term="uv"/></entry><entry><title>Battle Drones - a vibe coded RTS with audio-based multiplayer</title><link href="https://simonwillison.net/2026/Oct/20/battledrones/" rel="alternate"/><published>2026-10-20T19:34:19+00:00</published><updated>2026-10-20T19:34:19+00:00</updated><id>https://simonwillison.net/2026/Oct/20/battledrones/</id><summary type="html">
<p>My latest vibe coded game experiment is a Command &amp; Conquer style RTS (Real Time Strategy) game called <a href="https://github.com/simonw/battledrones#readme">Battle Drones</a> (<a href="https://simonw.github.io/battledrones/">play it here</a>). Unlike <a href="https://simonwillison.net/2026/Aug/5/raccoon-heist/">my previous experiments</a>, this one is <em>actually fun to play</em>. I'm somewhat embarrassed to admit that I got there by telling Claude to "Make it a LOT more fun". It also supports multiplayer between nearby devices using audio to synchronize game state! Here's what I've built so far, and some of the things I learned along the way.</p>
<ul>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#battle-drones">Battle Drones</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#how-i-built-this">How I built this</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v1-the-initial-prototype">v1: the initial prototype</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v2-full-sprites">v2: full sprites</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v3-varied-terrain">v3: varied terrain</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v4-the-fun-update">v4: the fun update</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v5-battle-drones-goes-3d">v5: Battle Drones goes 3D</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v8-archipelago">v8: Archipelago</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v10-goliath-and-agent-battles">v10: Goliath, and agent battles</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#agent-battles">Agent battles</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v11-random-maps">v11: Random Maps</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#v12-multiplayer-via-sound">v12: Multiplayer via sound</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#some-thoughts">Some thoughts</a></li>
<li><a href="https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support">Update: Online multiplayer support</a></li>
</ul>
<h4 id="battle-drones">Battle Drones</h4>
<p>My initial goal was to build an RTS game I could play on my phone, in the style of <a href="https://en.wikipedia.org/wiki/Command_&amp;_Conquer_(1995_video_game)">Command &amp; Conquer</a>. I have fond memories of the 1995 original (I liked Red Alert too) and wanted to recapture a little bit of the magic.</p>
<p>After 12 major iterations (and <a href="https://github.com/simonw/battledrones/commits/main/">321 commits</a> by coding agents, mainly Claude Code) I now have a browser-based game that works on mobile and desktop, has multiple play modes, several maps (including a random map generator) and even supports multiplayer for two devices within microphone range of each other. (<strong>Update</strong>: also <a href="https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support">online multiplayer</a>; the audio multiplayer induced headaches!)</p>
<p>Here's a video demo of Battle Drones running in a desktop browser:</p>
<video
src="https://static.simonwillison.net/static/2026/archipelago_720p_h264.mp4"
poster="https://static.simonwillison.net/static/2026/archipelago_poster.jpg"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
width="1280"
height="706"
style="display: block; width: 100%; height: auto;"
> </video>
<p style="margin-top: 1em">Features so far include:</p>
<ul>
<li>9 buildings, 7 ground vehicles, 6 aerial vehicles, 3 infantry units - all 3D models, which you can <a href="https://simonw.github.io/battledrones/models.html">browse here</a>
</li>
<li>Fog of war</li>
<li>Different weapons are needed to target aerial or ground vehicles</li>
<li>
<strong>Six maps</strong>, across five biomes - temperate, desert, arctic, volcanic, tropical</li>
<li>A random map generator</li>
<li>
<strong>Skirmish mode</strong> - red vs. blue on a rotationally symmetrical map</li>
<li>
<strong>Last Stand mode</strong> - one player holds out against as many waves of enemies as possible</li>
<li>Area effect weapons: Barrage, EMP, Drop Pod, Sky Hammer</li>
<li>
<strong>Crate drops</strong> with bonus resources</li>
<li>In-game music that responds to events - it gets more intense as fighting breaks out</li>
<li>Different in-game <strong>AI personalities</strong> (Balanced, Rush, Air Swarm, Boom, Skyforce, Ironclad)</li>
<li>
<strong>AI vs. AI</strong> mode, to watch those personalities play each other</li>
<li>The <strong>Goliath</strong> - a giant stomping mech with laser eyes and arm cannons and the ability to establish a new base</li>
<li>
<strong>Mutators</strong> that add extra rules or twists</li>
<li>A "Daily Op" challenge</li>
<li>Ranks and achievements (<strong>Medals</strong>)</li>
<li>
<strong>Agent vs. Agent</strong> mode where two LLMs can play Battle Drones against each other</li>
<li>A <strong>multiplayer mode</strong> based on two nearby phones communicating via audio messages, an extension of my earlier experiment with <a href="https://simonwillison.net/2026/Oct/15/chirp-pong/">Chirp Pong</a>
</li>
</ul>
<h4 id="how-i-built-this">How I built this</h4>
<p>Battle Drones is heavily vibe coded - I've reviewed almost none of the code, and it's built in a language (TypeScript) that I've hardly used myself. I've playtested it quite a bit though, and it's been through a large number of iterations since I started the project.</p>
<p>Here's a rough history of the project so far, including key prompts and links to transcripts.</p>
<h4 id="v1-the-initial-prototype">v1: the initial prototype</h4>
<p>I started out with Claude Fable 5 back in July:</p>
<blockquote>
<p><code>We are going to build a mobile friendly RTS game - command and conquer style - called Battle Drones, in which two armies of drones (both flying and ground-based) battle for territory and resources</code></p>
<p><code>Let's start with a MVP design, ask me some questions</code></p>
</blockquote>
<p>Here's a <a href="https://claude.ai/code/session_015RYeKm4ji4N16oqthyX1b1">shared transcript</a>. I'd given Claude Code for Web an environment variable with an OpenAI API key and told it to use the OpenAI <a href="https://developers.openai.com/api/docs/guides/image-generation">Image Generation API</a> for assets, which got me some basic sprites.</p>
<p>You can <a href="https://simonw.github.io/battledrones/v1/">try v1 here</a> - it looked like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v1.webp" alt="Game screen. Down the right are text icons to build Fab, Airpad, Turret, Harv, Sting, Flak, Scout, Wasp, Raptor. There is a blocky fog of war on a 2D battlefield. There are some gems, an HQ building being attacked by badly rendered tanks, and some blue vehicles dotted around. It's not very visually impressive but it does look like a basic RTS." style="max-width: 100%;" /></p>
<p>It's recognizable as an RTS, has building mechanics and the ability to select and direct units, and a basic AI to play against.</p>
<p>This first version was barely a proof of concept, and it wasn't any fun to play.</p>
<p>Claude used the <a href="https://github.com/phaserjs/phaser">Phaser</a> 2D game framework for these early versions. I didn't even realize this until several iterations later!</p>
<h4 id="v2-full-sprites">v2: full sprites</h4>
<p>The second version (<a href="https://simonw.github.io/battledrones/v2/">try v2 here</a>) added sprites for all of the vehicles and the "AI vs. AI" mode, so I could watch the game playing without having to directly control it myself.</p>
<p>Claude proved reasonably competent at prompting OpenAI's image models to generate sprites. You can browse the v2 sprites in the <a href="https://github.com/simonw/battledrones/tree/v2/public/assets/sprites">public/assets/sprites</a> folder.</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v2.webp" alt="Four flying units, three turrets, a harvester and an airpad all have proper sprites now. The scrap field has a new design which doesn't look great but is at least using a graphic." style="max-width: 100%;" /></p>
<h4 id="v3-varied-terrain">v3: varied terrain</h4>
<p>It still wasn't much fun, and the graphics were boring. It was now October, and I had upgraded to Claude Opus 5.5. I told it:</p>
<blockquote>
<p><code>Massively improve this game. Make the graphics and gameplay better (keep it mobile friendly). Render new graphics using the latest OpenAI GPT image API (lookup details) with the API key in the environment variable. Add new unit types and balance the gameplay better. Also add new buildings and better, more varied terrain.</code></p>
</blockquote>
<p>This resulted in five new maps with generated background tiles in a variety of styles, <a href="https://github.com/simonw/battledrones/commit/aa22f08a34347d7d9f94b33f44a73b4deb046aa1">visible here</a>. Opus also regenerated the sprites, making them much more visually appealing. You can <a href="https://simonw.github.io/battledrones/v3/">try v3 here</a> - it looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v3.jpg" alt="The map is now an ice map with snow and ice and broken ice - it looks really good. The vehicles and buildings have all had a cosmetic upgrade too. This is starting to look like a real game." style="max-width: 100%;" /></p>
<p>This is starting to feel like a real game! It still wasn't very fun to play though - I found myself getting bored pretty quickly.</p>
<h4 id="v4-the-fun-update">v4: the fun update</h4>
<p>So far my Battle Drones experiment was confirming my <a href="https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp">previous belief</a> that coding agents can build a thing that looks like a game but can't actually make something that's genuinely compelling to play.</p>
<p>I shared this theory with someone over dinner, and then thought to myself that I should give the models a proper chance to prove me wrong. I prompted Opus 5.5 on my phone:</p>
<blockquote>
<p><code>This game isn't fun enough yet. Make it a LOT more fun.</code></p>
</blockquote>
<p>This time I was running in <a href="https://code.claude.com/docs/en/workflows">Ultracode mode</a>, where Claude Code (in this case Claude Code for Web) runs "dynamic workflows", described in their docs as:</p>
<blockquote>
<p>A dynamic workflow is a JavaScript script that orchestrates many <a href="https://code.claude.com/docs/en/sub-agents">subagents</a> at once.</p>
</blockquote>
<p>This kicked off <em>many hours</em> of work. I started it in the evening and didn't get a playable result back until late into the next morning. But the results were spectacular.</p>
<p>You can <a href="https://simonw.github.io/battledrones/v4/">try v4 here</a> - it looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v4.jpg" alt="The lava map. Uplink satellites are being taken, crystals look better, Elite text is shown above a unit, there is an arrow marked Fight to jump to a fight, the AI vs AI mode has a speed controller - plenty of new features here." style="max-width: 100%;" /></p>
<p>I had Claude <a href="https://github.com/simonw/battledrones/blob/main/Battle%20Drones%20The%20Fun%20Update%20%E2%80%94%20Release%20Notes.md">write its own release notes</a> - here are the highlights:</p>
<blockquote>
<p>Every skirmish and Daily Op now opens with a choice, gives the side that's losing a way back, and pulls the armies into the middle of the map. There are also two new ways to play.</p>
<ul>
<li>
<strong>Openers</strong>: pick Blitz, Industry or Air Wing before the clock starts.</li>
<li>
<strong>Call-down powers</strong>: Barrage, EMP, Drop Pod and the Sky Hammer orbital strike.</li>
<li>
<strong>Objectives and salvage</strong>: Uplink relays, supply drops and wrecks worth scrap.</li>
<li>
<strong>Feel</strong>: combat juice, adaptive music, unit voices and an announcer.</li>
<li>
<strong>Command</strong>: battle alerts, game speed, saved squads and touch placement.</li>
<li>
<strong>New modes</strong>: Last Stand survival waves and an 8-mission Ops campaign.</li>
<li>
<strong>Progression</strong>: heroes, an after-action report with awards, a career, 7 mutators and a Daily Op.</li>
</ul>
<p>Fights run longer and swing more. In 1,200 AI-vs-AI test matches on Normal, games still undecided after 25 minutes fell from 14% to 0.9%. The share of wins by a side that had been 800+ scrap behind rose from 24% to 46%.</p>
</blockquote>
<p>Part of the reason Claude took so long was that it ran over a thousand simulated playtest sessions, and used the results to rebalance the existing units, add new ones, and introduce new features.</p>
<h4 id="v5-battle-drones-goes-3d">v5: Battle Drones goes 3D</h4>
<p>After the success of Ultracode at "Make it a LOT more fun", I decided to be more ambitious:</p>
<blockquote>
<p><code>Port this game to three.js with 3D models for all of the buildings and vehicles and landscapes</code></p>
</blockquote>
<p>That was another overnight run. I woke up to <a href="https://simonw.github.io/battledrones/v5/">this v5 version</a>:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v5.jpg" alt="Now it is in 3D - the battlefield is at a slight angle, the buildings and vehicles are all 3D models, the rocks and trees look a bit 3D as well." style="max-width: 100%;" /></p>
<p>The new 3D models were entirely constructed by Claude in TypeScript code.</p>
<p>v6 (<a href="https://simonw.github.io/battledrones/v6/">play v6 here</a>) added some more visual polish. v7 (<a href="https://simonw.github.io/battledrones/v7/">play v7</a>) added robot infantry (troopers, rocket squads, snipers) and a "Condor" troop carrying aircraft.</p>
<h4 id="v8-archipelago">v8: Archipelago</h4>
<p>I was beginning to feel guilty at how little actual design input I had into the game - it really had been a case of me saying "make it more fun" and "add visual polish" for the past few releases.</p>
<p>I'd noticed that the AI didn't use the new infantry and troop carrying aircraft from v7 very often - there wasn't a great strategic reason to use them.</p>
<p>It would be neat if we had a new map with a new game mechanic that actively encouraged players to load up Condors with infantry robots and send them out into the map.</p>
<p>This resulted in my longest prompt yet:</p>
<blockquote>
<p><code>Design a new map. Goal is to make different strategic incentives that encourage use of Infantry and Condors and aerial vehicles.</code></p>
<p><code>To do this the map will have limited harvester resources but several more uplinks - but uplinks will be on islands that are inaccessible by land vehicles or infantry. These uplinks can also not be claimed using air vehicles. The ONLY way to get them is to fly infantry there in a Condor.</code></p>
<p><code>Armies always start with a Condor and a single squad. If an army has no Condor a new one will be provided for free, flying in from the edge closest to their HQ and landing there. That free condor will come with a single free squad on board.</code></p>
<p><code>The two HQs should be entirely separated by water, but still accessible by vehicles thanks to two bridges across the map in different places</code></p>
<p><code>I want to encourage a battle over uplinks.</code></p>
<p><code>The map should be the times the size of other maps - still square</code></p>
<p><code>First research and then critique this design. Only build after we have agreed on any modifications</code></p>
<p><code>You get to design a new biome for this</code></p>
</blockquote>
<p>The result was the tropical <strong>Archipelago</strong> map, with seven island uplinks that players can only capture by flying out infantry in a Condor. It's definitely the most fun map to play, once you've got the hang of the basic game mechanics from the simpler maps. The <a href="https://simonw.github.io/battledrones/v9/">v9 edition</a> made that map a little more interesting - it now looks like this:</p>
<p><img src="https://static.simonwillison.net/static/2026/battledrones-v8.jpg" alt="Three islands, each with an uplink satellite. Blue holds one, red holds another, A blue condor is flying towards the red island, which is guarded by a red plane. There is a bridge nearby. The theme is tropical islands and looks very pleasant." style="max-width: 100%;" /></p>
<h4 id="v10-goliath-and-agent-battles">v10: Goliath, and agent battles</h4>
<p>I decided to add giant robot mechs to the game - think Jaegers from <a href="https://en.wikipedia.org/wiki/Pacific_Rim_(film)#Plot">Pacific Rim</a>, or Titans from Warhammer 40,000.</p>
<p>Here are some of the prompts I used to brainstorm with Claude:</p>
<blockquote>
<p><code>Help me brainstorm ideas for adding giant robots to this game - think dreadnoughts or titans from W20K - how could we do this in a way that enhanced gameplay, kept things balanced, added unique twist? Don't overthink this yet</code></p>
</blockquote>
<blockquote>
<p><code>Let's keep brainstorming. I like the idea that it's a mobile base - that can accept harvested scrap and can have buildings built near it (even if it later moves on) and can produce infantry units too. An interaction with condor would be neat but I don't know what that could be.</code></p>
</blockquote>
<blockquote>
<p><code>Idea: as it gets damage it loses the ability to fire some weapons - by default it has eye laser (like lancers) and arm canons (like titan) and two shoulder mounted mortars, plus machine guns similar to a squad of troops</code></p>
</blockquote>
<blockquote>
<p><code>Damage knocks out mortars and then laser - it always has guns. You can't build next to a building that was only put there because of the mech, you need the mech there for off-base building and only within three squares of it</code></p>
</blockquote>
<blockquote>
<p><code>[...] Lets do two condors can carry the mech</code></p>
</blockquote>
<p>The end result is <em>really cool</em>.</p>
<video
width="1644"
height="1080"
preload="none"
loop="1" controls="1"
playsinline="1" muted="1"
style="display: block; width: 100%; height: auto;"
poster="https://static.simonwillison.net/static/2026/goliath-poster.jpg"
>
<source src="https://static.simonwillison.net/static/2026/goliath.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
<p style="margin-top: 1em">Goliaths can be constructed using a Gantry - a building that can only be created after first building a Fab, Bay, Airpad, and Tech Lab. You can see the Goliath under construction, and it then walks out from the Gantry and can march around the map.</p>
<p>Goliaths can "anchor", which digs them into the ground. In their anchored state they can act as a new HQ, constructing infantry units and additional buildings in a new area.</p>
<p>Two Condor aircraft can hook onto a Goliath, at which point it can be flown around the map!</p>
<p>The game now ends when you destroy the enemy's HQ building <em>and</em> any Goliaths they might have built.</p>
<p>There are also a couple of mutators relating to Goliaths:</p>
<ul>
<li>
<strong>Goliath Armada</strong> starts each side with four airborne Goliaths (each with a pair of Condors) and no other units.</li>
<li>
<strong>Robot Love</strong> adds a special rule: if enemy Goliaths get close to each other on the battlefield they fall in love and the game ends in a draw. (Thank Natalie for that one).</li>
</ul>
<h4 id="agent-battles">Agent battles</h4>
<p>The other v10 feature is <strong>agent battles</strong>. In musing about how multiplayer could work I had an idea: what if different LLMs could fight it out in the game?</p>
<blockquote>
<p><code>Fun extra challenge: think about how we might make multiplayer available to coding agents. It would be neat if we could set up a battle between eg GPT-6 Sol and Claude Opus 5.5 where each model has access to a tool which gives them information about the game (presumably non-visual, but only the information they could see through fog of war etc) and lets them control their units etc [...]</code></p>
<p><code>Consult ~/dev/llm/docs and include notes in that file about how LLM could be used here via a new tools plugin</code></p>
</blockquote>
<p>Opus 5.5 went to work on this, producing <a href="https://github.com/simonw/battledrones/blob/7001ed186c8b8aef4acb27f680ecf4c09b607e54/AGENT-BATTLES.md">this AGENT-BATTLES.md proposal</a> and then implementing and testing it. The feature also includes the ability to record and replay these battles - here's <a href="https://simonw.github.io/battledrones/v11/?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json">a replay of Claude Haiku 5.5 vs. GPT-6 Luna</a>, and here's that same battle <a href="https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1">in a separate debug tool</a> that shows the underlying prompt responses.</p>
<p><img src="https://static.simonwillison.net/static/2026/agent-v-agent.jpg" alt="Screenshot of a replay of a real-time strategy game between two AI models, shown from a top-down view of a snowy map with a dark frozen lake of cracked ice floes on the left and pine forests at the top and lower right. Top bar: pause button, &quot;6:27&quot;, &quot;1×&quot;, &quot;anthropic/claude-haiku-5-5 · industry&quot; in blue, &quot;gpt-6-luna · industry&quot; in red, a blue-and-red strength bar labeled &quot;B&quot; and &quot;R&quot;, and &quot;0:03&quot;. Left notification: &quot;Blue: Pushing turrets at the enemy's south-east edge.&quot; Replay panel: &quot;Blue anthropic/claude-haiku-5-5 · industry vs Red gpt-6-luna · industry · frostbite seed 42&quot;, a timeline slider at &quot;6:27 / 7:48&quot;, and buttons &quot;−30s&quot;, &quot;+30s&quot;, &quot;All&quot;, &quot;Blue's eyes&quot;, &quot;Red's eyes&quot;, &quot;Notes&quot;. In the scene, a group of blue tanks and a large blue Goliath mech trailing smoke advance near the ice edge at lower center, while a column of red turrets (one burning) lines the ice to their north, red tanks and trucks sit by a rocky ridge to the east, and red base buildings occupy the top right. A minimap is in the top right corner and zoom in, zoom out and lightning-bolt buttons are on the lower left." style="max-width: 100%;" /></p>
<p>The prompt that drives agent battles <a href="https://github.com/simonw/battledrones/blob/d584e351d9d28c4ba058b78ddcca9b93cd9bcd33/llm-tools-battledrones/llm_tools_battledrones.py#L106-L117">can be seen here</a>.</p>
<p>There are a few more replays like this <a href="https://github.com/simonw/battledrones/blob/main/README.md#watch-ai-models-play-it">linked in the README</a>. I hope to turn this into a full league table at some point in the future.</p>
<h4 id="v11-random-maps">v11: Random Maps</h4>
<p>This version exists purely because I glanced at my <a href="https://claude.ai/new#settings/usage">Claude Usage</a> page one day and saw that I'd only used 75% of my weekly allowance and it was resetting in 45 minutes. I decided to see if I could get an extra Battle Drones feature from my remaining tokens, and picked "random map" as the target:</p>
<blockquote>
<p><code>Design and implement a mechanism for generating a random map using any of the available biomes - it should be the size of the largest map and rivers and bridges and rocks and forest and scrap and crystals are all in play. Make them rotationally symmetric and use a seed to allow them to be selected or reused later. You have 45 minutes to build this! Be creative.</code></p>
</blockquote>
<p>Here's <a href="https://claude.ai/code/session_01CfwMwDaK1kLKnRV6di8VMT">the transcript</a>, and an image Claude generated to show me its work:</p>
<p><img src="https://static.simonwillison.net/static/2026/random-map-contact-sheet.jpg" alt="Grid of ten top-down game maps, two per biome (temperate, desert, arctic, volcanic, tropical), each with a river or lava flow, bridges and roads. Title: &quot;Battle Drones: generated maps (108x108, point-symmetric), 2 per biome, runtime ground painter&quot;. Each map is captioned with a name and layout type plus a seed and crossing counts, e.g. &quot;Hawthorn Delta · fork&quot; &quot;random-temperate-1x8a6r2 · 6 bridges, 4 fords&quot;; layout types are fork, badlands, crossing and lake." style="max-width: 100%;" /></p>
<h4 id="v12-multiplayer-via-sound">v12: Multiplayer via sound</h4>
<p>I only <em>just</em> got this working, so I've not had much time to actively test it yet. The latest Battle Drones now supports multiplayer via two devices sat within microphone distance of each other!</p>
<p>This feature started out as my <a href="https://simonwillison.net/2026/Oct/15/chirp-pong/">Chirp Pong</a> experiment from last week. I pointed Claude Code at that working proof of concept:</p>
<blockquote>
<p><code>Clone Simonw/tools from GitHub and look at recent branches for the example pong game that uses web microphone to implement multiplayer between two phones via audio signals</code></p>
<p><code>Build a version of that for battledrones</code></p>
</blockquote>
<p>Opus built <a href="https://simonw.github.io/battledrones/radio-probe.html">this Radio Probe tool</a> to measure how much bandwidth we could get between two devices and, based on positive results from that, implemented a full audio modem system. I've tried it between laptops, iPhones and iPads so far and it seems to work really well!</p>
<p>Why use sound for this? Because I <a href="https://simonwillison.net/2025/Dec/10/html-tools/#the-anatomy-of-an-html-tool">love static HTML</a> that costs nothing to run, and I don't want to spin up a server somewhere and then stay responsible for keeping it operating for as long as anyone might want to play the game.</p>
<h4 id="some-thoughts">Some thoughts</h4>
<p>I know almost <em>nothing</em> about game development. This makes it a great opportunity to try out coding agents in a field where my existing software engineering experience has less impact on the results.</p>
<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>
<p>This morning (<a href="https://news.ycombinator.com/item?id=50168190">via Hacker News</a>) I found <a href="https://www.ign.com/articles/steam-fans-are-begging-for-a-no-ai-filter-as-steam-next-fest-is-filled-with-slop">Steam Fans Are Begging for a No-AI Filter as Steam Next Fest Is Filled With Slop</a>. I wouldn't personally dream of submitting Battle Drones to an event like this - it's still way too low effort to warrant consideration as a legitimate indie gaming project.</p>
<p>... but I can now see a path to vibe coded games like this being taken seriously. Battle Drones is fun, it looks good, it has innovative features (the multiplayer-over-audio thing is a first for an RTS as far as I can tell).</p>
<p>I'd love to see what someone with better taste than me and a driving passion to produce something truly exceptional could build!</p>
<p>A few other observations from this project:</p>
<ul>
<li>Static HTML and JavaScript is a fantastic medium for games development. WebGL works great, and <a href="https://github.com/mrdoob/three.js/">Three.js</a> (and <a href="https://github.com/phaserjs/phaser">Phaser</a> before it) are excellent platforms to build on that the current models know inside out.</li>
<li>This also lets them run as <a href="https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps">Progressive Web Apps</a> - I didn't ask for it, but Battle Drones works offline. I was able to play it on a plane despite never having directly installed it - my phone had it cached.</li>
<li>Giving Claude an OpenAI API key and telling it to generate images using OpenAI's models works really well. It can view the images it has generated and iterate on the prompts.</li>
<li>Opus 5.5 is spectacular at 3D modeling using Three.js (and Blender, and no doubt other 3D applications as well). The <a href="https://til.simonwillison.net/llms/blender-coding-agents-macos">same is true</a> of GPT-6 Astra. They are absolutely capable of building models for 3D game projects.</li>
<li>For features like replay and multiplayer it's useful to have a deterministic simulation engine. At one point Claude had to replace calls to <code>Math.sin()</code> and <code>Math.cos()</code> and friends with <a href="https://github.com/simonw/battledrones/blob/v12/src/sim/fmath.ts">custom versions</a> because different browsers (Chrome vs. Safari, for example) returned very slightly different numbers, desynchronizing the replay.</li>
<li>Opus 5.5 can write music! There are no audio files in this project - the soundtrack is entirely generated through code, varies across different maps, and even gets more intense as the battle heats up. See <a href="https://simonwillison.net/2026/Oct/6/scrimshaw-jukebox/">Scrimshaw Jukebox</a> for a previous experiment with Claude for music composition.</li>
<li>I still can't get over how well the prompt "Make it a LOT more fun" worked.</li>
<li>Tools are effectively free. I prompted up the <a href="https://simonw.github.io/battledrones/radio-probe.html">Radio Probe</a>, the <a href="https://simonw.github.io/battledrones/models.html">Model browser</a>, the <a href="https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1">Agent vs. Agent debug tool</a>, and Claude Code <a href="https://github.com/simonw/battledrones/tree/main/tools">built a bunch of tools</a> for itself that I haven't even explored myself.</li>
<li>Audio-based multiplayer between static HTML games works! I hope to see a whole lot more games use this same pattern - in digging around today I've not found much prior art beyond <a href="https://github.com/AlonHor/siner">Siner</a> by Alon Horesh and <a href="https://github.com/ggerganov/ggwave">ggwave</a> by Georgi Gerganov (also of <code>llama.cpp</code> fame).</li>
<li>Claude Code "Ultracode" burns tokens like there's no tomorrow, but it can also solve complex problems (like adding audio-based multiplayer) from a single prompt.</li>
<li>I'm still not quite over the <em>guilt</em> of building software in this way. I don't feel like I've earned the right to create something this good, in a field in which I have so little prior experience! At this point I've shown it to enough people in private that it felt wrong not to publish it for everyone else to see and learn from.</li>
</ul>
<h4 id="update-online-multiplayer-support">Update: Online multiplayer support</h4>
<p>Earlier in this article I said:</p>
<blockquote>
<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>
</blockquote>
<p>Then I tried playing the multiplayer version with Natalie... and the high pitched modem sounds gave her a nasty headache!</p>
<p>That's a pretty bad bug. I <a href="https://github.com/simonw/battledrones/pull/36">added a warning</a> and was then inspired to build proper network multiplayer. I tried <a href="https://github.com/simonw/battledrones/pull/37">getting WebRTC to work</a> but couldn't get a connection going between two of my own devices even on my own WiFi network, so <a href="https://github.com/simonw/battledrones/pull/38">I had Claude build</a> a simple, stateless WebSockets relay server instead:</p>
<blockquote>
<p><code>If I wanted to support multiplayer between two devices at a very low cost without storing any state on the server could I do that with a tiny asyncio web server running on the cheapest Fly instance?</code></p>
</blockquote>
<blockquote>
<p><code>Build the server and the fly.toml for deploying it, use Fly application name battledrones-relay - put that in a folder in the repo, include deploy instructions in the README in that folder</code></p>
</blockquote>
<p>Here's <a href="https://github.com/simonw/battledrones/tree/v13/relay">the resulting server</a>. Since this scales to zero and runs on a single <a href="https://fly.io/">Fly.io</a> <code>shared-cpu-1x</code> instance it should cost me no more than $2.19/month - and that's if it stays hot and serving connections the whole time.</p>
<p>Battle Drones now supports online multiplayer. Click "Duel a friend online", then either share the resulting room URL via your messaging app of choice or have them snap a picture of the displayed QR Code.</p>
<p>I also added a feature where you can copy JSON of the match once it has ended and then feed that into the replay feature to rewatch your game.</p>
<p>I didn't expect to introduce online multiplayer this soon, but the headache bug felt like it warranted an urgent alternative.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/vibe-coding">vibe-coding</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p>
</summary><category term="game-design"/><category term="projects"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="claude"/><category term="vibe-coding"/><category term="coding-agents"/><category term="claude-code"/></entry><entry><title>My obituary for programming</title><link href="https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/" rel="alternate"/><published>2026-10-19T23:58:25+00:00</published><updated>2026-10-19T23:58:25+00:00</updated><id>https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/</id><summary type="html">
<p><strong><a href="https://dumbmatter.com/2026/10/programming-obituary/">My obituary for programming</a></strong></p>
Jeremy Scheff poignantly captures the key loss caused by coding agents for career programmers who enjoyed the <em>puzzle</em> of developing code:</p>
<blockquote>
<p>Programming turned into one of the greatest jobs you could imagine. You got paid to work on tricky little logic puzzles. The trickier the puzzle, the more you got paid. But even pretty simple puzzles were worth a lot of money because regular people just couldn't do it! No, they needed us. They would give us a problem and we would solve it the way we wanted. We set the strategy, we made the timeline, we defined what was and was not possible.</p>
</blockquote>
<p>If you're a programmer who thrives on building working systems and doesn't care too deeply about the problems solved along the way, LLMs are the gift that keeps on giving.</p>
<p>If directly solving those problems was a big part of your enjoyment, the loss is very real.
<p><small></small>Via <a href="https://lobste.rs/s/wtobpt/my_obituary_for_programming">lobste.rs</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/programming">programming</a>, <a href="https://simonwillison.net/tags/careers">careers</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/deep-blue">deep-blue</a></p>
</summary><category term="programming"/><category term="careers"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="coding-agents"/><category term="deep-blue"/></entry><entry><title>llm-tools-datasette 0.1.1</title><link href="https://simonwillison.net/2026/Oct/18/llm-tools-datasette/" rel="alternate"/><published>2026-10-18T23:43:09+00:00</published><updated>2026-10-18T23:43:09+00:00</updated><id>https://simonwillison.net/2026/Oct/18/llm-tools-datasette/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/llm-tools-datasette/releases/tag/0.1.1">llm-tools-datasette 0.1.1</a></p>
<p>When I switched LLM over to <a href="https://github.com/pydantic/httpx2">httpx2</a> in <a href="https://llm.datasette.io/en/stable/changelog.html#v0-33">LLM 0.33</a> I forget that this would break any plugins which used <code>httpx</code> without directly depending on it. <code>llm-tools-datasette</code> was one of those plugins, now fixed.</p>
<p>Tags: <a href="https://simonwillison.net/tags/datasette">datasette</a>, <a href="https://simonwillison.net/tags/llm">llm</a></p>
</summary><category term="datasette"/><category term="llm"/></entry><entry><title>llm-echo 0.5</title><link href="https://simonwillison.net/2026/Oct/18/llm-echo/" rel="alternate"/><published>2026-10-18T23:16:16+00:00</published><updated>2026-10-18T23:16:16+00:00</updated><id>https://simonwillison.net/2026/Oct/18/llm-echo/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/llm-echo/releases/tag/0.5">llm-echo 0.5</a></p>
<p>I'm working towards a new <a href="https://llm.datasette.io/">LLM</a> release, and testing PRs caused me to revisit the <code>llm-echo</code> debug plugin. This plugin provides a "model" which doesn't involve an LLM at all - it just repeats back the prompts that have been fed to it. The new release now updates the simulated token usage counts to take tool calls, system prompts, and reasoning tokens into account.</p>
<p>Example usage:</p>
<pre><code>uvx --with llm-echo llm -m echo 'hi there' -o thinking 1 --usage
</code></pre>
<p>Outputs:</p>
<pre><code>First I consider the prompt, then I decide what to say.
{
"prompt": "hi there",
"system": "",
"attachments": [],
"stream": true,
"previous": []
}
Token usage: 2 input, 24 output
</code></pre>
<p>Tags: <a href="https://simonwillison.net/tags/llm">llm</a></p>
</summary><category term="llm"/></entry><entry><title>Inline rendering with document.currentScript</title><link href="https://simonwillison.net/2026/Oct/17/document-currentscript/" rel="alternate"/><published>2026-10-17T21:11:12+00:00</published><updated>2026-10-17T21:11:12+00:00</updated><id>https://simonwillison.net/2026/Oct/17/document-currentscript/</id><summary type="html">
<p><strong><a href="https://leanrada.com/notes/inline-rendering-currentscript/">Inline rendering with document.currentScript</a></strong></p>
Lean Rada describes a neat trick that takes advantage of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript">document.currentScript</a> property. You can use that to drop in a tiny inline <code>&lt;script&gt;</code> element that replaces itself when the page loads:</p>
<pre><code>The year is &lt;script&gt;
document.currentScript.replaceWith(
new Date().getFullYear())&lt;/script&gt;
</code></pre>
<p>If you define a shortcut function like this:</p>
<pre><code>$=(...n)=&gt;document.currentScript.replaceWith(...n)
</code></pre>
<p>You get a tiny template language:</p>
<pre><code>The year is &lt;script&gt;$(new Date().getFullYear())&lt;/script&gt;
</code></pre>
<p>Tags: <a href="https://simonwillison.net/tags/javascript">javascript</a></p>
</summary><category term="javascript"/></entry><entry><title>web-edit 0.1a2</title><link href="https://simonwillison.net/2026/Oct/17/web-edit/" rel="alternate"/><published>2026-10-17T13:16:49+00:00</published><updated>2026-10-17T13:16:49+00:00</updated><id>https://simonwillison.net/2026/Oct/17/web-edit/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/web-edit/releases/tag/0.1a2">web-edit 0.1a2</a></p>
<p>web-edit (<a href="https://simonwillison.net/2026/Oct/12/web-edit/">previously</a>) is my tiny web app for browsing and editing files in a folder. I mainly built it for editing files on different machines via Tailscale.</p>
<p>I added a "copy to clipboard" option for both text and image data. I needed this because I was running pelican prompts on a laptop from my phone (here's <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fb1cec9726b6aa62d4de47100f90f0c1a">DeepSeek 4.1 Flash 1017</a>) and I wanted an easy way to copy the resulting logs into a Gist.</p>
<p>Tags: <a href="https://simonwillison.net/tags/projects">projects</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/deepseek">deepseek</a></p>
</summary><category term="projects"/><category term="pelican-riding-a-bicycle"/><category term="deepseek"/></entry><entry><title>Quoting Addy Osmani, Morgan Westlee Lunt, and Qing Wang</title><link href="https://simonwillison.net/2026/Oct/16/code-review/" rel="alternate"/><published>2026-10-16T22:06:37+00:00</published><updated>2026-10-16T22:06:37+00:00</updated><id>https://simonwillison.net/2026/Oct/16/code-review/</id><summary type="html">
<blockquote cite="https://claude.dev/blog/solving-code-review-at-anthropic/"><p>We think "did a human read the code?" is an imprecise proxy for "what could go wrong with this change, and which check—automated or human—is the right one to catch it?"</p>
<p>Asking that question also changed <em>when</em> review happens. Before, review was a gate at the end of the road: write the code, open a PR, wait for your colleague.</p>
<p>Now, review runs continuously, more like spellcheck while you write. Most changes have been reviewed and fixed by Claude at least once before a human is asked to look. This catches most routine mistakes, and saves team attention for higher-level questions and scrutiny.</p></blockquote>
<p class="cite">&mdash; <a href="https://claude.dev/blog/solving-code-review-at-anthropic/">Addy Osmani, Morgan Westlee Lunt, and Qing Wang</a>, How the Claude Code team does code review</p>
<p>Tags: <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/addy-osmani">addy-osmani</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a>, <a href="https://simonwillison.net/tags/code-review">code-review</a></p>
</summary><category term="anthropic"/><category term="claude"/><category term="ai"/><category term="claude-code"/><category term="llms"/><category term="addy-osmani"/><category term="coding-agents"/><category term="generative-ai"/><category term="agentic-engineering"/><category term="code-review"/></entry><entry><title>sparqlite: SPARQL 1.1 inside SQLite, written in Rust</title><link href="https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/" rel="alternate"/><published>2026-10-16T01:58:00+00:00</published><updated>2026-10-16T01:58:00+00:00</updated><id>https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/</id><summary type="html">
<p><strong>Research:</strong> <a href="https://github.com/simonw/research/tree/main/sqlite-sparql-rust#readme">sparqlite: SPARQL 1.1 inside SQLite, written in Rust</a></p>
<p>This research task is really an experiment in running Claude Code for web in "Ultracode" mode, as described in <a href="https://code.claude.com/docs/en/workflows">Orchestrate subagents at scale with dynamic workflows</a> in the Claude Code documentation.</p>
<p>With Ultracode turned on, Claude Code makes aggressive use of dynamic workflows - it generates JavaScript that defines and coordinates a network of subagents to take on complex problems.</p>
<p>My initial prompt was this - I meant "hit the rows directly", the word "delete" was an accidental typo on my phone:</p>
<blockquote>
<p><code>Write a SQLite extension in Rust that implants SPARQL and runs really fast because it can hit the delete rows directly</code></p>
</blockquote>
<p>This caused Claude Code for web to churn for over 12 hours. I checked in on its progress the next day and sent a single follow-up prompt when I noticed how many Rust crates it had built:</p>
<blockquote>
<p><code>Every folder in the crates/ directory needs a README</code></p>
<p><code>Include a tutorial.md teaching users how to install the extension and how to run it in the SQLite CLI and then teaching them SPARQL in addition to how to use the SQLite extension</code></p>
<p><code>Include a script with the tutorial for populating a SQLite database with useful and realistic example data for that tutorial</code></p>
</blockquote>
<p>This project feels like next-level vibe coding - it's not remotely feasible to review the code that was produced here, and even following the documentation is a significant investment in work. I'm not entirely sure what to do with this - I appear to have a full SPARQL implementation in Rust inside SQLite now, but how valuable is that if I created it on a whim and can't (or won't) invest the necessary time to understand what it can do?</p>
<p>Tags: <a href="https://simonwillison.net/tags/rdf">rdf</a>, <a href="https://simonwillison.net/tags/semantic-web">semantic-web</a>, <a href="https://simonwillison.net/tags/sqlite">sqlite</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/rust">rust</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p>
</summary><category term="rdf"/><category term="semantic-web"/><category term="sqlite"/><category term="ai"/><category term="rust"/><category term="generative-ai"/><category term="llms"/><category term="coding-agents"/><category term="claude-code"/></entry><entry><title>Chirp Pong</title><link href="https://simonwillison.net/2026/Oct/15/chirp-pong/" rel="alternate"/><published>2026-10-15T19:47:52+00:00</published><updated>2026-10-15T19:47:52+00:00</updated><id>https://simonwillison.net/2026/Oct/15/chirp-pong/</id><summary type="html">
<p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/chirp-pong">Chirp Pong</a></p>
<p>Another game experiment - I wanted to see if it was feasible to have a two player game on two separate phones running in static HTML where the networking code uses chirps sent via the microphone. It seems to work!</p>
<blockquote>
<p><code>Build a two player competitive pong like game where two players use their phones close to each other and the game state is sent via audio noises which the web microphone API can interpret - but add graphical and gameplay twists to make it a lot more fun and intertwine than pong</code></p>
</blockquote>
<p>Claude Opus 5.5 Extra <a href="https://claude.ai/code/session_019awUnNB7NoYd7noBNAsNdd">in Claude Code</a>.</p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude-code">claude-code</a></p>
</summary><category term="game-design"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="claude-code"/></entry><entry><title>Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO</title><link href="https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/" rel="alternate"/><published>2026-10-15T13:04:03+00:00</published><updated>2026-10-15T13:04:03+00:00</updated><id>https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/</id><summary type="html">
<p><strong><a href="https://www.ft.com/content/11632d03-358c-454b-af95-d06d4072932b?syn-25a6b1a6=1">Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO</a></strong></p>
The phrase "told investors" appears four times in this FT article, which reports on Anthropic's day of hosting investors on Wednesday. Lots of details in here from "<a href="https://simonwillison.net/2023/Nov/22/deciphering-clues/#hints-to-look-out-for">people with knowledge of the matter</a>".</p>
<p>Key things I learned from the article:</p>
<ul>
<li>Q1 revenue (Jan/Feb/Mar) was "about $4.8bn"</li>
<li>Q2 (Apr/May/Jun) was $11.5bn</li>
<li>Q3 (Jul/Aug/Sep) was $16.8bn</li>
<li>In Q3: $1.70 in revenue for every $1 spent on "computing power"</li>
<li>Adjusted operating margins (excluding stock-based compensation) were 11%</li>
</ul>
<p>This point about distillation is worth quoting in full (highlight mine):</p>
<blockquote>
<p>The start-up has also clamped down on “distillation” — a controversial practice whereby rival AI labs train their models on the outputs of more advanced ones.</p>
<p>When rival companies “distil” their models from Anthropic’s models, that involves heavy usage and spending.</p>
<p>Anthropic told investors on Wednesday <strong>distillation accounted for 5 per cent to 7 per cent of revenue</strong> and that they had cut it back “materially” in the third quarter of the year, said four people with direct knowledge of the matter.</p>
</blockquote>
<p>Napkin maths says that if distillation was 5% of their Q2 revenue (before they cut it back in Q3) then unnamed "other labs" spent over half a billion dollars distilling Anthropic's models in that quarter!</p>
<p>Also notable: Anthropic appear to no longer be leaning on "annualized run-rate revenue" (<a href="https://simonwillison.net/2026/May/29/anthropic/">previously</a>) in these communications to their investors.
<p>Tags: <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a></p>
</summary><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="anthropic"/></entry><entry><title>LaTeX renderer</title><link href="https://simonwillison.net/2026/Oct/15/latex/" rel="alternate"/><published>2026-10-15T02:07:28+00:00</published><updated>2026-10-15T02:07:28+00:00</updated><id>https://simonwillison.net/2026/Oct/15/latex/</id><summary type="html">
<p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/latex">LaTeX renderer</a></p>
<p>Inspired by Paul Ford and Aboard Foundary's new web app <a href="https://tinylittleoffice.com/">Tiny Little Office</a>, which provides a suite of web app content editors (a Word Processor, Outliner, Presentation Builder, Spreadsheet, Calculator, Drawing Tool, Diagram Maker, Animator, Calendar, and Trip Planner).</p>
<p>Tiny Little Office's signature trick is to store all of the document data in the <code>#fragment</code> section of the URL, so every document created using it becomes a bookmarkable and shareable link.</p>
<p>It also has <a href="https://tinylittleoffice.com/llms.txt">an llms.txt file</a> telling agents how to construct URLs that will render as documents. Claude <a href="https://claude.ai/share/239301ff-edde-420e-b433-b9c16fe40a6c">used that file</a> to generate <a href="https://tinylittleoffice.com/#/v1/deck/zXVVdb9tGEHznr1hED2kBSbZcO4UFtIHTuCgQtylstwH6Uq7Io3gRdcfeHS1T_fjtnV1Ssp038r52d2Z2djabZcmmxizpJ78jpnvrerqxCUv0sapsYaixbkM7HzYxS7XZ4ujWls6u65SlwC7aZL1bUmxsabIZHpxMaCmXlnRfG9rVHm~Vvui2xiWykfDK8Ojfc439b5bN6BdP0YQHE6bkPJWceMXR6A8Xhe9cwqFr7Peptm5NXCUT9Kl8klNM3EeyjnrfBVoFv8Nj2TGbaDgU9ZKuHCe_7clXKFVSkMh5Qs2Nluy14nnhtyeTk4fFSWmKzUn_7e~f5_N5LkcfFvlSg1Y~bDkR8omoXrbkLDZ3tS1q4rYl3xqHnCTvvB~vbX2J2k1C7rI8vjzsHSCaEuK3wcRoSmJXknEFrpVZ9r0CWgVeK5QDBBOB1BlkAgCxmry~dgAz~hePj0i1wT5wMnIY_Ohl0FQ~cTN_Aq~yIo~7ZFpaoL5gcc8iOg6bx5QdaHlB8f3Nxykg_pnDpvQ7Rw8cLCuFdyKTSLEF4uQd5QiTS0gTsftDzSHFKZWBd2A5av3sLLAGzPgNqB94AJlV44uN3LmvEVDQl8C88l2iBX14JyS3DUMTY5pjOS0XG14fKjqDcP_qjNlLTVLLLe_o_fWPN1f319MBSN4a4mbtUXi9lbL3ttW81vgQFvcgcIg0XjwwPv7SDjeBhnBqEpW2kGI49HIu4Bw0fqAcGwRdcdMc6O6fXdAKAcBurA9dWSrYR_AjddGIuH1ayqNbvHft1o2N9RTqc5IIUi~5J4fCAHVEXC5jbZBa1TkNheUjdbF3iR_ndGtaw3i_9RYcr1jwdtAPaLQuJrwhGa2MNGdsTdOAI3DxTEii4hH2b2AivFEd_XZ7M4tcGQH_XZ~gjZVB4oak_9~cd6FZ0htaWQkNmRZQCBdj_1zN_iCe7el0dpkLWZDTf7kWmP~p_Yq_YMBNYQZpd7HjBprLp8OpmViHbRpSDKiCDNWLBo9xxpQatQCyM21DLD8rSNQ6uBwKtgU71eGUVj1Fu0dJeZ4rsnplPL7ioL93CTKkf4aiMyFRhIqFi_PLs~y9qRp0aDmIp8fy4vzsIrsR32y5bzzwxtrl6UKCiFgu5hejLNSKozTg2EdjGz11EioV2kYXpM6VgPZsenp6~gSwaKP2IcF_fLeuxfKgoJjkRBKHi8~43Zh~SZ_qXgyYAMTrpJAKwQDD9ErvJ5Qi7amGdBT1lGpuKl1cKf~DwhDDDTxoj3N6HeFVvfSR9pp1ChBVbJs4oPSqtLA3uAN8zWMjqExfaZshma~~zqVmbWqYGN7j1s4_q3l4MSXG7BunwnFwpCQ~tKTrRwy7KI4l940rdXS8BUK7fLR6HlxI29ylIfH8bZkfJ4HYrSRyGBfztk2PJzIBSFpNOI2jtaLLYbs4~KsWK~MGpgAz10G8pHyYTRP0_Xc5EOm~0CmE89L2ihrnoVUxkfRi8sJzHYTonVE_Ua0cR3Shm1H9CXPLNP2XjovGNI3M0_1smG4C4P8">this link to a deck</a> that explains how the URL format works:</p>
<p><img alt="Screenshot of a slide deck editor in a web app with a dark-themed presentation open. The document title field reads &quot;How a Tiny Little Office link works&quot;, with a progress ring, share icon and menu icon at top right. Below is a formatting toolbar with an &quot;Insert&quot; dropdown followed by icon buttons for play, bold, italic, underline, strikethrough, highlight, code, link, superscript, emoji, outdent, indent, layout and color palette. The main canvas shows slide 1 with a blue chain-link icon and the text: &quot;The whole document is the link&quot; &quot;No server, no database, no account&quot; &quot;Everything after the # stays in your browser&quot; and a slide counter &quot;1 / 9&quot;. Below the canvas is a &quot;SPEAKER NOTES&quot; heading. A sidebar on the right shows slide thumbnails. Slide 1 (selected): &quot;The whole document is the link&quot; &quot;No server, no database, no account&quot; &quot;Everything after the # stays in your browser&quot;. Slide 2: &quot;Anatomy of a link&quot; with bullets &quot;tinylittleoffice.com/#/v1/deck/y7Vj...&quot; &quot;v1: the format version&quot; &quot;deck: which app opens it&quot; &quot;y: the mode letter&quot; &quot;7Vj...: the document, compressed and encoded&quot;. Slide 3: &quot;Step 1: write it as text&quot; with bullets &quot;Every document is TLO, a Markdown variant&quot; &quot;Slides split on --- lines&quot; &quot;Charts, drawings and animations are fenced blocks&quot; &quot;This deck is about 1 KB of plain text&quot;. Slide 4: &quot;Step 2: squeeze it&quot; with bullets &quot;Raw DEFLATE, the same algorithm as zip and gzip&quot; &quot;z: plain DEFLATE&quot; &quot;y: DEFLATE with a preset dictionary&quot; &quot;r: no compression at all&quot;." src="https://static.simonwillison.net/static/2026/tiny-little-office.webp" /></p>
<p>Tiny Little Office inspired me <a href="https://claude.ai/code/session_017KJrPqqWVHLqr4E7TLPnpt">to have Claude Code</a> (Opus 5.5 Extra) build a similar tool that works with LaTeX. Here's the sequence of prompts I used:</p>
<blockquote>
<p><code>I want a tool where you can link to it with a fragment hash #code-here and it treats that code as LaTeX and renders it really effectively. It should also support a prefix which means the latex is compressed with a custom compression dictionary optimized for latex. Use the best available latex render library from a CDN (consider WebAssembly too). If loaded without a fragment hash show an editor you can paste latex into and then toggle to a "rendered" view. That rendered view should be bookmarkable. The #fragment view should let you switch to edit source too.</code></p>
</blockquote>
<p>Since it was working in <a href="https://github.com/simonw/tools">my tools repo</a> I told it to take inspiration from the <code>&lt;iframe sandbox="..."&gt;</code> mechanism used by my existing <a href="https://tools.simonwillison.net/markdown-svg-renderer">SVG in Markdown tool</a> as protection against XSS risks:</p>
<blockquote>
<p><code>Safe from XSS? We could run in an iframe sandbox like we do on the SVG markdown render project</code></p>
</blockquote>
<p>I had it copy the Gist/URL loading feature from that tool as well:</p>
<blockquote>
<p><code>We should have an option to load latex from a URL (or gist) similar to the markdown SVG tool</code></p>
</blockquote>
<p>Here's <a href="https://tools.simonwillison.net/latex#~1jZq9DoIwEIB3nuKGbigJJS5svoAOMJuQ4EBEJWJjGHh3765A_8DIQtJfIMdR-n0uCV9l4DOs_p8ua3ZZKK2anOsaTqya9AZnHhMo3qqewKWPMh2SOQOFkhSJtmruY1QungBJFk-cQLsspAF8qgFPWKQ6FmdYdCB7oseX5HVNfgE-HGmM2OPATDfAlCssyLcLGI4BONwZ7E8pby5KWoilFBK0n5T4lMeHgQaMMsYjS6hrG61G4Micmcj2EN48tyVgHpzNKMBEHuxEbV0dZhsJwZB7_Lux0mR4YDc9HTd1bnGaki0V1nr6kGHSI8NAwCWaVjeAPyYUNAYxUZt8k2aKlODPRQq7JIYMS-VKaQwHrMmoxqWeLlT6Ag">an example link</a>. The tool uses <a href="https://github.com/nodeca/pako">Pako 2.1.0</a>, <a href="https://github.com/mathjax/MathJax">MathJax 4.1.3</a>, <a href="https://github.com/arena-ai/faster-latex">faster-latex 0.3.1</a>, and <a href="https://github.com/cure53/DOMPurify">DOMPurify 3.4.16</a>.</p>
<p><img alt="Screenshot of a web app titled &quot;LaTeX renderer&quot; with a split-pane layout. The top bar has an Edit/Rendered toggle, a blue Copy link button, and a Share button. The left pane, labeled LaTeX source with a &quot;Document · faster-latex (WASM)&quot; badge, has a URL/GitHub Gist input with a Load button, a code editor containing a LaTeX document, and rows of example buttons (Quadratic formula, Gaussian integral, Maxwell, Attention, Matrix, Chemistry, Prose, TikZ, Document). The right pane shows the typeset output: a paper titled &quot;Sums of Odd Numbers&quot; by A. Student, with a section stating a theorem that the first n odd numbers sum to n squared, a Proof section with numbered equations, and a bulleted list of small cases." src="https://static.simonwillison.net/static/2026/latex-tool.webp" /></p>
<p>Tags: <a href="https://simonwillison.net/tags/latex">latex</a>, <a href="https://simonwillison.net/tags/paul-ford">paul-ford</a>, <a href="https://simonwillison.net/tags/tools">tools</a>, <a href="https://simonwillison.net/tags/urls">urls</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p>
</summary><category term="latex"/><category term="paul-ford"/><category term="tools"/><category term="urls"/><category term="ai"/><category term="generative-ai"/><category term="llms"/></entry><entry><title>Tree Appreciator</title><link href="https://simonwillison.net/2026/Oct/14/tree-appreciator/" rel="alternate"/><published>2026-10-14T21:23:01+00:00</published><updated>2026-10-14T21:23:01+00:00</updated><id>https://simonwillison.net/2026/Oct/14/tree-appreciator/</id><summary type="html">
<p><strong>Tool:</strong> <a href="https://tools.simonwillison.net/tree-appreciator">Tree Appreciator</a></p>
<p>Another game experiment with Claude. This one used the default Claude iPhone app (chat mode, not Claude Code mode), where I prompted Claude Opus 5.5 Max with:</p>
<blockquote>
<p><code>Build a three js game called "Tree appreciator" - it shows you two algorithmically generated trees and the game mechanics is about appreciating the differences between them. Think hard about how to make sure it is both fun and beautiful.</code></p>
</blockquote>
<p>Somewhat embarrassingly given <a href="https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp">my recent talk</a>, I've found that telling Opus 5.5 "make sure it is fun" works uncomfortably well. In this case Claude <a href="https://claude.ai/share/ee7de555-f85c-4ff0-96cb-d51ed5e479e9">crunched for 3 hours and 7 minutes</a> before retuning a cosy little spot-the-difference game with music and animation and achievements that's quite compelling to play.</p>
<p><img alt="Screenshot of a mobile spot-the-difference puzzle game with a dark interface. Header reads &quot;No. 003 Acer autumnalis ‘Hid…&quot; with subtitle &quot;Autumn maple · A country lane in late a…&quot; and icons for sound, a book, and help. Two nearly identical 3D-rendered scenes are stacked vertically, labeled &quot;Fig. i&quot; and &quot;Fig. ii&quot;, each showing a dark-trunked maple tree with red, orange and pale peach leaves, leaves falling through the air, a golden grassy field with a few small rocks, and hazy hills with pine silhouettes under a pale sky. Two differences are circled in blue in both images: circle &quot;a&quot; at the base of the trunk, where Fig. i has a small red mushroom that is missing in Fig. ii, and circle &quot;b&quot; in the right side of the canopy, where Fig. i has a patch of green leaves that are red in Fig. ii. The bottom bar shows &quot;2 of 4&quot;, a reset button, a &quot;Hint&quot; button with three filled and two empty dots, and a score of &quot;1,803&quot;." src="https://static.simonwillison.net/static/2026-10-14/image_crop_1320x2195_w1320_q0.7.webp" /></p>
<p>Tags: <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/claude">claude</a>, <a href="https://simonwillison.net/tags/vibe-coding">vibe-coding</a>, <a href="https://simonwillison.net/tags/three-js">three-js</a></p>
</summary><category term="game-design"/><category term="javascript"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="claude"/><category term="vibe-coding"/><category term="three-js"/></entry><entry><title>AI is mass decompiling games. That's both awesome and scary.</title><link href="https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/" rel="alternate"/><published>2026-10-14T16:26:53+00:00</published><updated>2026-10-14T16:26:53+00:00</updated><id>https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/</id><summary type="html">
<p><strong><a href="https://popcar.bearblog.dev/ai-is-mass-decompiling-games-thats-both-awesome-and-scary/">AI is mass decompiling games. That&#x27;s both awesome and scary.</a></strong></p>
Indie game developer Popcar talks about the recent wave of AI-powered decompilation of existing games, enabling weird mashups between existing games, and producing a boom in game preservation projects to get old games working on new hardware (often in a browser using WebAssembly).</p>
<p>I like how this piece captures both the positives and the negatives of this new development:</p>
<blockquote>
<p>Most people already realized the scary part by now. If AI can decompile games and software, then the entire tech industry is about to explode. Anybody can decompile other software and use it any way they'd like, and nobody can stop them. Companies can steal from competitors. Your paid game or app can be open-sourced against your will. This isn't exclusive to old video games, we can apply this to <em>any</em> software. [...]</p>
<p>This is also a big win for preservation. Old games can be ported, modified, enhanced, and made much more easily accessible than before. [...[</p>
<p>With console makers going all in on digital and games becoming entirely unplayable due to servers shutting down, this is <em>fantastic</em> news. We could own software we bought regardless of what the company thinks.</p>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50088534">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/computer-history">computer-history</a>, <a href="https://simonwillison.net/tags/game-design">game-design</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/webassembly">webassembly</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/ai-ethics">ai-ethics</a>, <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a></p>
</summary><category term="computer-history"/><category term="game-design"/><category term="ai"/><category term="webassembly"/><category term="generative-ai"/><category term="llms"/><category term="ai-ethics"/><category term="coding-agents"/></entry><entry><title>Redesigning source control at Anthropic</title><link href="https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/" rel="alternate"/><published>2026-10-13T23:00:06+00:00</published><updated>2026-10-13T23:00:06+00:00</updated><id>https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/</id><summary type="html">
<p><strong><a href="https://www.anthropic.com/engineering/redesigning-source-control">Redesigning source control at Anthropic</a></strong></p>
Interesting piece from Anthropic describing why and how they built their own custom alternative to Git, based on the dramatic increase in rate of changes to their code after the past six months.</p>
<blockquote>
<p>In May 2026, Anthropic averaged around 2,500 code changes merged per day; as of September, we merged over 30,000 per day.</p>
</blockquote>
<p>They included a chart showing those changes. I <a href="https://claude.ai/share/aefcdd4a-9364-40c1-927a-29bf445894fc">had Claude modify their chart</a> (<a href="https://gist.github.com/simonw/4a16dff066fd9763faf8642f797905be">code here</a>) to add markers for the public releases of each of their models in 2026:</p>
<p><img alt="Stacked bar chart titled “Changes merged per day”, for the Anthropic monorepo, January–September 2026. Each day’s bar is split into pull requests (blue) and antique change requests (orange), with a black line for the 7-day average. Weekdays start at around 1,000 merges in January and climb slowly to about 3,000 by late May. Antique change requests appear in late May, overtake pull requests in mid-June and have almost fully replaced them by mid-July, when weekdays reach 6,000–8,000. A labelled “Quiet week” at the end of July dips below 1,000 a day. After that, growth turns steep: over 10,000 a day by mid-August, about 17,000 in early September, and a peak of 30,401 on Sep 9. Dotted lines mark Claude model releases: Opus 4.6 (Feb 5), Sonnet 4.6 (Feb 17), Mythos Preview (Apr 7), Opus 4.7 (Apr 16), Opus 4.8 (May 28), Fable 5 and Mythos 5 (Jun 9), Sonnet 5 (Jun 30), Opus 5 (Jul 24, just before the quiet week), and Fable 5.1 and Mythos 5.1 (Sep 1)." src="https://static.simonwillison.net/static/2026/anthropic-merges-per-day.webp" /></p>
<p>This shows public release dates, not the date when models became available for Anthropic's internal use. My guess is that the introduction of Fable/Mythos class models is a key factor in the increased coding velocity.</p>
<p>"Antique" is their new code review system. The source control system is called Scion, and sounds to me like a reinvention of centralized source control along the lines of Subversion.</p>
<p>(<strong>Update</strong>: Anthropic credit Google's <a href="https://en.wikipedia.org/wiki/Piper_(source_control_system)">Piper</a> and Meta's <a href="https://sapling-scm.com/">Sapling</a> as "prior art" - it looks like the core concept of "derived data" <a href="https://sunshowers.io/posts/anthropic-mononoke/">was heavily inspired by Mononoke</a>, the server component of Sapling.)</p>
<p>They had some pretty extreme requirements:</p>
<blockquote>
<p>The history of our main branch alone is almost 100 GB, and a <em>compressed</em> working copy is over 25 GB. We perform on the order of 25 million code checkouts per day for CI, before counting developer environments, agent sandboxes, and research jobs. Fetched naively, that would be over 600 PB of git traffic per day.</p>
</blockquote>
<p>The new system was built by a team of seven people, and the migration from Git was completed in five months.</p>
<p>When asked on Hacker News about the lack of offline support, Scion engineer Nick G <a href="https://news.ycombinator.com/item?id=50073633#50079495">replied</a>:</p>
<blockquote>
<p>Since Claude is by far the heaviest user of Scion and is necessarily online, this just wasn't important to do.</p>
</blockquote>
<p>As an aside, I've been trying adversarial review in my own projects recently, where you have a model try and find flaws (I often play Claude and GPT off against each other). This note from the article reflected my own experience with that:</p>
<blockquote>
<p>Anthropic also makes extensive use of adversarial review, and, while this is incredibly effective in many ways, it can also be myopic, so skilled engineers needed to steer Claude away from over-engineering parts of the system in response to hypothetical concerns.</p>
</blockquote>
<p><small></small>Via <a href="https://news.ycombinator.com/item?id=50073633">Hacker News</a></small></p>
<p>Tags: <a href="https://simonwillison.net/tags/git">git</a>, <a href="https://simonwillison.net/tags/migrations">migrations</a>, <a href="https://simonwillison.net/tags/version-control">version-control</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/anthropic">anthropic</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a></p>
</summary><category term="git"/><category term="migrations"/><category term="version-control"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="anthropic"/><category term="agentic-engineering"/></entry><entry><title>llm-gemini 0.35</title><link href="https://simonwillison.net/2026/Oct/13/llm-gemini/" rel="alternate"/><published>2026-10-13T22:28:54+00:00</published><updated>2026-10-13T22:28:54+00:00</updated><id>https://simonwillison.net/2026/Oct/13/llm-gemini/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/llm-gemini/releases/tag/0.35">llm-gemini 0.35</a></p>
<p>I added support to <a href="https://github.com/simonw/llm-gemini">llm-gemini</a> for the <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/">new Gemini 4 Argon</a> model, made available today via the Gemini API and for customers of their $100/month subscription plan.</p>
<p>Here are <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fd741e4420dea14c460f0108ac22dbc26">the low, medium and high pelicans</a>. As expected, they are all excellent: Gemini has a track record of producing great SVGs, and are the only lab where I know their <a href="https://twitter.com/sunjiao123sun_/status/2024555516551372920">staff have invested in SVG specifically</a> (and who have <a href="https://simonwillison.net/2026/Feb/19/gemini-31-pro/#jeff-dean">boasted about their pelicans</a> before.)</p>
<p>Here's the "high" illustration, which cost me 17.166 cents:</p>
<p><img alt="Stylish, accurate bicycle frame. Fish in the basket. Snazzy scarf. Feet on either side of the frame touching the pedals. Spokes, a little hat, a good beak and pouch, a somewhat fierce expression." src="https://static.simonwillison.net/static/2026/gemini-4-argon-high.webp" /></p>
<p>The pricing is interesting. At launch, Argon is $2/million input and $10/million output - the same price as GPT-6 Sol, half the price of Claude Opus 5.5 and 1/5th the price of Claude Fable 5.1 and GPT-6 Astra.</p>
<p>But on December 1st Argon is set to double in price - so it will be the same price as Opus 5.5.</p>
<p>Prices like this aren't really comparable these days since what really matters is how many tokens a model takes to achieve a goal within an agentic harness.</p>
<p>One useful clue for that comes from Artificial Analysis, who publish <a href="https://artificialanalysis.ai/#total-cost-tabs">the total cost to run their benchmark</a> using each model. Argon is looking very good there - costing $2,407 to run the benchmark, putting it close to GLM-5.3 and significantly cheaper than OpenAI, Anthropic, and Meta's latest models.</p>
<p>When the price doubles it will still be a little cheaper than GPT-6 Astra.</p>
<p><img alt="Screenshot of a stacked bar chart from Artificial Analysis comparing dollar costs for 14 AI models, sorted from lowest to highest, with bars colored by provider, the provider's logo beneath each bar and angled model names along the bottom. Logo at top right: Artificial Analysis. A hover tooltip pointing at the Gemini 4 Argon bar reads: Gemini 4 Argon (High), $2,407, Output $313, Reasoning $815, Cache Write $897, Cache Read $264, Non-Cache Input $118, Click for more info. Bars from left to right, with the total above each bar and some segment values printed inside: Qwen3.8 27B (xhigh), $1,336, Alibaba logo; Mistral Large 4 Preview, $1,607, Mistral logo; Gemini 3.8 Flash (high), $1,623, Google logo; Muse Spark 1.3 (max), $2,000, segment $769, Meta logo; Gemini 4 Argon (high), $2,407, segments $815 and $897, Google logo; GLM-5.3 (max), $2,503, segment $790, Z.ai logo; Kimi K3 (max), $3,658, Kimi logo; Qwen3.8 Max (0902), $4,935, segments $893 and $1,441, Alibaba logo; Grok 4.7 (xhigh), $4,967, segments $1,861 and $1,618, xAI logo; GPT-6 Astra (max), $5,324, segments $778 and $978, OpenAI logo; Muse Wonder (max), $5,733, segment $1,748, Meta logo; Claude Sonnet 5.5 (max with fallback), $7,260, segments $1,216 and $1,815, Anthropic logo; Claude Opus 5.5 (max with fallback), $8,708, segment $921, Anthropic logo; Claude Fable 5.1 (max with fallback), $13,129, segment $7,219, Anthropic logo." src="https://static.simonwillison.net/static/2026/gemini-4-argon-artificial-analysis.webp" /></p>
<p><small>(I <a href="https://chatgpt.com/share/6acebe13-5378-83e8-bf2f-9f4d05b206f4">used ChatGPT to edit that chart</a>! The data is all correct, I checked - I needed to get that Gemini 4 Argon info box to display without overlapping the other numbers.)</small></p>
<p>Some bonus examples using Gemini 4 Argon: here's <a href="https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9589ff9e0c977bbf3b012b7a11f5bd71">Generate an SVG of an armadillo in fishnet tights jaywalking on Mars</a>, here's <a href="https://tools.simonwillison.net/blender-viewer?url=https%3A%2F%2Fstatic.simonwillison.net%2Fstatic%2Fcors-allow%2F2026%2Fgemini-4-astra-egg.blend">a Fabergé egg</a> it created for me using Blender, and DeepMind staffer @fofrAI shared <a href="https://twitter.com/fofrai/status/2110043023954284889">a video of a pelican riding a bike, using fourier epicycles</a>. That's a fun new twist!</p>
<p>Tags: <a href="https://simonwillison.net/tags/google">google</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/llms">llms</a>, <a href="https://simonwillison.net/tags/llm">llm</a>, <a href="https://simonwillison.net/tags/gemini">gemini</a>, <a href="https://simonwillison.net/tags/llm-pricing">llm-pricing</a>, <a href="https://simonwillison.net/tags/pelican-riding-a-bicycle">pelican-riding-a-bicycle</a>, <a href="https://simonwillison.net/tags/llm-release">llm-release</a></p>
</summary><category term="google"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="llm"/><category term="gemini"/><category term="llm-pricing"/><category term="pelican-riding-a-bicycle"/><category term="llm-release"/></entry><entry><title>Quoting Geoffrey Huntley</title><link href="https://simonwillison.net/2026/Oct/13/geoffrey-huntley/" rel="alternate"/><published>2026-10-13T13:32:00+00:00</published><updated>2026-10-13T13:32:00+00:00</updated><id>https://simonwillison.net/2026/Oct/13/geoffrey-huntley/</id><summary type="html">
<blockquote cite="https://ghuntley.com/agency/"><p>If the agent isn't using my diagnostics library, I could introspect and update AGENTS.md, but there's still a delta, and it'll drift. Instead, I write a pre-commit hook that checks the git diff for direct calls to observability modules that bypass my diagnostics module. Boom: fail the commit, inject a prompt telling the agent to use the diagnostics library. All of a sudden it's ten out of ten.</p></blockquote>
<p class="cite">&mdash; <a href="https://ghuntley.com/agency/">Geoffrey Huntley</a>, nobody should type code by hand anymore. here's what's left.</p>
<p>Tags: <a href="https://simonwillison.net/tags/coding-agents">coding-agents</a>, <a href="https://simonwillison.net/tags/generative-ai">generative-ai</a>, <a href="https://simonwillison.net/tags/git">git</a>, <a href="https://simonwillison.net/tags/agentic-engineering">agentic-engineering</a>, <a href="https://simonwillison.net/tags/ai">ai</a>, <a href="https://simonwillison.net/tags/geoffrey-huntley">geoffrey-huntley</a>, <a href="https://simonwillison.net/tags/llms">llms</a></p>
</summary><category term="coding-agents"/><category term="generative-ai"/><category term="git"/><category term="agentic-engineering"/><category term="ai"/><category term="geoffrey-huntley"/><category term="llms"/></entry><entry><title>web-edit 0.1a1</title><link href="https://simonwillison.net/2026/Oct/13/web-edit/" rel="alternate"/><published>2026-10-13T01:40:05+00:00</published><updated>2026-10-13T01:40:05+00:00</updated><id>https://simonwillison.net/2026/Oct/13/web-edit/</id><summary type="html">
<p><strong>Release:</strong> <a href="https://github.com/simonw/web-edit/releases/tag/0.1a1">web-edit 0.1a1</a></p>
<p>Includes <a href="https://github.com/simonw/web-edit/pull/1">performance optimizations</a> written <a href="https://claude.ai/code/session_01LE2R4P74P9GGUbE6yQ5YBt">by Claude Opus 5.5</a> after I fed it <a href="https://simonwillison.net/2026/Oct/12/python-3-15-web-edit-profiling/">this Python 3.15 profiling report</a> generated by GPT-6 Astra.</p>
<p>Tags: <a href="https://simonwillison.net/tags/profiling">profiling</a>, <a href="https://simonwillison.net/tags/projects">projects</a></p>
</summary><category term="profiling"/><category term="projects"/></entry></feed>
Raw headers
{
"accept-ranges": "bytes",
"access-control-allow-methods": "GET, OPTIONS",
"access-control-allow-origin": "*",
"access-control-max-age": "1000",
"age": "440",
"cache-control": "s-maxage=600",
"cf-cache-status": "HIT",
"cf-ray": "a510aa6a8e9f26ee-CMH",
"connection": "close",
"content-length": "123969",
"content-type": "application/xml; charset=utf-8",
"date": "Tue, 27 Oct 2026 09:27:34 GMT",
"django-composition": "Two Improvised Guitar Choruses",
"last-modified": "Mon, 26 Oct 2026 23:53:07 GMT",
"nel": "{\"report_to\":\"heroku-nel\",\"response_headers\":[\"Via\"],\"max_age\":3600,\"success_fraction\":0.01,\"failure_fraction\":0.1}",
"referrer-policy": "strict-origin-when-cross-origin",
"report-to": "{\"group\":\"heroku-nel\",\"endpoints\":[{\"url\":\"https://nel.heroku.com/reports?s=jrsgjUkb9%2FcOnH5EUPC%2FYv7g3haXaDMOLfggvpNh3bM%3D\\u0026sid=c46efe9b-d3d2-4a0c-8c76-bfafa16c5add\\u0026ts=1793092814\"}],\"max_age\":3600}",
"reporting-endpoints": "heroku-nel=\"https://nel.heroku.com/reports?s=jrsgjUkb9%2FcOnH5EUPC%2FYv7g3haXaDMOLfggvpNh3bM%3D&sid=c46efe9b-d3d2-4a0c-8c76-bfafa16c5add&ts=1793092814\"",
"server": "cloudflare",
"via": "1.1 heroku-router",
"x-content-type-options": "nosniff"
}
Parsed with @rowanmanning/feed-parser
{
"meta": {
"type": "atom",
"version": "1.0"
},
"language": "en-us",
"title": "Simon Willison's Weblog",
"description": null,
"copyright": null,
"url": "http://simonwillison.net/",
"self": "http://simonwillison.net/atom/everything/",
"published": null,
"updated": "2026-10-26T23:53:07.000Z",
"generator": null,
"image": null,
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [],
"items": [
{
"id": "https://simonwillison.net/2026/Oct/26/gpt-61-terra/",
"title": "GPT-6.1 Terra",
"description": "<p><strong><a href=\"https://openai.com/index/introducing-gpt-6-1-terra/\">GPT-6.1 Terra</a></strong></p>\nIt's always interesting to note which aspects of a new model are emphasized in the release announcement.</p>\n<p>In the case of GPT-6.1 Terra, OpenAI went with visual reasoning and computer use:</p>\n<blockquote>\n<p>We’re introducing <strong>GPT-6.1 Terra</strong>, a fast, efficient model that combines detailed visual reasoning and precise computer use alongside clearer, more natural writing. A significant step up from GPT‑5.6 Terra, it excels at the communication and computer-based tasks that fill the workday, from drafting proposals and interpreting technical drawings to filling out forms and editing videos.</p>\n</blockquote>\n<p>Terra sits in the same position as Sonnet in the Anthropic model collection - not the cheapest or the most expensive, making it harder to decide when to use it.</p>\n<p>Computer use is a good example of a task that benefits from a less expensive model, since you might put it to work on automated, repetitive tasks.</p>\n<p>OpenAI's Ted Sanders provided some useful advice in <a href=\"https://news.ycombinator.com/item?id=50248124#50249160\">a comment</a> on Hacker News:</p>\n<blockquote>\n<p>In the case of GPT-6.1 Terra, I'd say Terra is probably better than Astra and Sol at technical communication, similar on vision and computer use (but much faster!), and a bit worse on most other things. For API developers, it's a nice midrange option if you want something cheaper than Sol but a lot smarter than Luna (especially for vision / computer use / communication). For subscribers, it's not a bombshell release - if you're hitting usage limits, maybe it helps you go a bit further, and if you want clearer communication or faster computer use, it can be a nice option to select.</p>\n</blockquote>\n<p>Here are <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e\">the pelicans</a> for the different reasoning levels. This pelican <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F855d951d12c68eccca5374cd7d4f834e#reasoning-2\">for \"max\"</a> cost <a href=\"https://www.llm-prices.com/#it=16&ot=22629&sel=gpt-6.1-terra\">11.3161 cents</a> and took 4 minutes and 11 seconds:</p>\n<p><img alt=\"It's a good pelican and a good bicycle - correctly shaped frame, feet n pedals either side of the frame, has the same color scheme as the others in the GPT-6 and GPT-6.1 families.\" src=\"https://static.simonwillison.net/static/2026-10-26/terra-max.webp\" /></p>\n<p>Here's <a href=\"https://static.simonwillison.net/static/2026/openai-pelicans-october-2026.html\">a new comparison grid</a> showing pelicans for every reasoning level of OpenAI's current frontier lineup: GPT-6 Astra, GPT-6.1 Sol, GPT-6.1 Terra, and GPT-6 Luna.</p>\n<p>GPT-6.1 Terra is priced at $1/million input tokens and $5/million output - almost half the price of GPT-5.6 Terra and GPT-6.1 Sol, and around 10x the price of GPT-6 Luna.\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50248124\">Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/openai\">openai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/llm-pricing\">llm-pricing</a>, <a href=\"https://simonwillison.net/tags/pelican-riding-a-bicycle\">pelican-riding-a-bicycle</a>, <a href=\"https://simonwillison.net/tags/llm-release\">llm-release</a>, <a href=\"https://simonwillison.net/tags/gpt\">gpt</a></p>",
"url": "https://simonwillison.net/2026/Oct/26/gpt-61-terra/",
"published": "2026-10-26T23:53:07.000Z",
"updated": "2026-10-26T23:53:07.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "openai",
"term": "openai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "llm-pricing",
"term": "llm-pricing",
"url": null
},
{
"label": "pelican-riding-a-bicycle",
"term": "pelican-riding-a-bicycle",
"url": null
},
{
"label": "llm-release",
"term": "llm-release",
"url": null
},
{
"label": "gpt",
"term": "gpt",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/26/jason-koebler/",
"title": "Quoting Jason Koebler",
"description": "<blockquote cite=\"https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/\"><p>Because big tech platforms essentially do not have customer support and make it impossible for their users to contact a human, many people experiencing run-of-the-mill tech problems have turned to ChatGPT. And, increasingly, ChatGPT is telling people that have normal tech support problems that they have discovered something journalistically notable and that 404 Media, specifically, can help them.</p></blockquote>\n<p class=\"cite\">— <a href=\"https://www.404media.co/chatgpt-keeps-telling-people-404-media-can-solve-their-tech-support-problems/\">Jason Koebler</a>, ChatGPT Keeps Telling People 404 Media Can Solve Their Tech Support Problems</p>\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/jason-koebler\">jason-koebler</a>, <a href=\"https://simonwillison.net/tags/openai\">openai</a>, <a href=\"https://simonwillison.net/tags/journalism\">journalism</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/ai-ethics\">ai-ethics</a>, <a href=\"https://simonwillison.net/tags/ai-misuse\">ai-misuse</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/chatgpt\">chatgpt</a>, <a href=\"https://simonwillison.net/tags/404-media\">404-media</a></p>",
"url": "https://simonwillison.net/2026/Oct/26/jason-koebler/",
"published": "2026-10-26T19:00:25.000Z",
"updated": "2026-10-26T19:00:25.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "jason-koebler",
"term": "jason-koebler",
"url": null
},
{
"label": "openai",
"term": "openai",
"url": null
},
{
"label": "journalism",
"term": "journalism",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "ai-ethics",
"term": "ai-ethics",
"url": null
},
{
"label": "ai-misuse",
"term": "ai-misuse",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "chatgpt",
"term": "chatgpt",
"url": null
},
{
"label": "404-media",
"term": "404-media",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/26/webframe-evaluation/",
"title": "webframe: evaluated as a scraper and a sandbox",
"description": "<p><strong>Research:</strong> <a href=\"https://github.com/simonw/research/tree/main/webframe-evaluation#readme\">webframe: evaluated as a scraper and a sandbox</a></p>\n <p><a href=\"https://github.com/tractordev/webframe\">webframe</a> is a neat little project from Jeff Lindsay which lets you \"run a web page like a program\" - you point it at a URL or file and it executes it in a hidden headless web view and outputs <code>console.log()</code> to standard output and any exceptions to standard error.</p>\n<p>It's written in Go on top of the <a href=\"https://github.com/crgimenes/glaze\">glaze</a> library, which provides access to a system browser (\"WKWebView on macOS, WebKitGTK on Linux, WebView2 on Windows\") so it doesn't need to bundle its own browser engine.</p>\n<p>It reminds me of my own <a href=\"https://shot-scraper.datasette.io/en/stable/javascript.html\">shot-scraper javascript</a> tool, albeit in a much smaller package that doesn't depend on Playwright.</p>\n<p>I had Claude Opus 5.5 <a href=\"https://claude.ai/code/cshk_01MX3aJH8vDGmGSj1xH9BYhj2HviVvLDaJbiELHyDoReYT\">put it through its paces</a> and prepare a research report for me. Here's the prompt I used:</p>\n<blockquote>\n<p><code>Explore https://github.com/tractordev/webframe try running it and put it though its paces, build a few exploratory prototypes, then evaluate it as a potential sandboxing tool and as a tool for scraping web pages using the same patterns encouraged by the \"shot-scraper JavaScript\" command (see simonw/shot-scraper on GitHub, docs directory)</code></p>\n</blockquote>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/browsers\">browsers</a>, <a href=\"https://simonwillison.net/tags/go\">go</a>, <a href=\"https://simonwillison.net/tags/javascript\">javascript</a>, <a href=\"https://simonwillison.net/tags/jeff-lindsay\">jeff-lindsay</a>, <a href=\"https://simonwillison.net/tags/shot-scraper\">shot-scraper</a></p>",
"url": "https://simonwillison.net/2026/Oct/26/webframe-evaluation/",
"published": "2026-10-26T16:15:00.000Z",
"updated": "2026-10-26T16:15:00.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "browsers",
"term": "browsers",
"url": null
},
{
"label": "go",
"term": "go",
"url": null
},
{
"label": "javascript",
"term": "javascript",
"url": null
},
{
"label": "jeff-lindsay",
"term": "jeff-lindsay",
"url": null
},
{
"label": "shot-scraper",
"term": "shot-scraper",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/25/seam-cutter/",
"title": "Seam Cutter",
"description": "<p><strong>Tool:</strong> <a href=\"https://tools.simonwillison.net/seam-cutter\">Seam Cutter</a></p>\n <p>I built this weird and very specific cropping tool - it lets you create a horizontal or vertical cut across an image, then slide the two sides relative to each other. Effectively it lets you crop out a section in the middle of an image.</p>\n<p>I wanted this because I often use <a href=\"https://apps.apple.com/us/app/tailor-screenshot-stitching/id926653095\">Tailor</a> on my iPhone to stitch several screenshots together into lot long image, but sometimes I find myself wanting to crop out a section in the middle - to redact an irrelevant prompt from a transcript, for example.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/tools\">tools</a></p>",
"url": "https://simonwillison.net/2026/Oct/25/seam-cutter/",
"published": "2026-10-25T15:10:19.000Z",
"updated": "2026-10-25T15:10:19.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "tools",
"term": "tools",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/24/battledrones/",
"title": "battledrones v14: Compass Rose, a four player map",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/battledrones/releases/tag/v14\">battledrones v14: Compass Rose, a four player map</a></p>\n <p>I added four player online mode to <a href=\"https://simonwillison.net/2026/Oct/20/battledrones/\">Battledrones</a> - previous maps were limited to two.</p>\n<p>Here's the initial prompt I used: </p>\n<blockquote>\n<p><code>Add a new map for a four player battle - four way rotational symmetry, up to four AI players, works with the WebSocket non-audio based multiplayer mode so up to four human players can join (any spare slots use AI)</code></p>\n</blockquote>\n<p>Claude Opus 5.5 added a new map called \"Compass Rose\" and modified the WebSockets multiplayer network code to support up to four players for that map, joining via share links or QR codes.</p>\n<p><img alt=\"The new map does indeed look a bit like a rose - it uses the cold and ice biome. Also shown are purple robots battling on the map.\" src=\"https://raw.githubusercontent.com/simonw/battledrones/v14/progress-shots/v14/compass-rose.jpg\" /></p>\n<p>The new teams use robots themed in purple and green, joining the existing blue and red designs. You can preview those colors in <a href=\"https://simonw.github.io/battledrones/models.html\">the updated model browser</a>.</p>\n<p>Here's <a href=\"https://simonw.github.io/battledrones/v14/?replay=https://gist.githubusercontent.com/simonw/faa550a002b25a78f1c88a64217786c1/raw/4ff9b03de71d757cd33eb5d1a0e388155b6c20e5/compass.json\">a replay link</a> to watch a four way AI battle with the \"Goliath Armada\" mutator turned on, where each side starts with four giant Goliath mech units.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/projects\">projects</a>, <a href=\"https://simonwillison.net/tags/claude\">claude</a></p>",
"url": "https://simonwillison.net/2026/Oct/24/battledrones/",
"published": "2026-10-24T03:59:57.000Z",
"updated": "2026-10-24T03:59:57.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "projects",
"term": "projects",
"url": null
},
{
"label": "claude",
"term": "claude",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/23/quick-study-painter/",
"title": "Quick Study",
"description": "<p><strong>Tool:</strong> <a href=\"https://tools.simonwillison.net/quick-study-painter\">Quick Study</a></p>\n <p>Prompt <a href=\"https://claude.ai/share/71adda96-193f-4f2a-97c0-454e08066afb\">to Claude Opus 5.5 High</a>:</p>\n<blockquote>\n<p><code>Build an artifact where you open a photo and it rapidly (in a few seconds) paints a version of that photo using a canvas element and simulated paintbrush</code></p>\n</blockquote>\n<p>See also <a href=\"https://simonwillison.net/2026/Aug/25/pelican-watercolor/\">my previous experiment</a> getting Claude Fable to simulate a watercolor illustration with P5.js.</p>\n<p><img alt=\"A simulated oil painting of a photograph of a heron\" src=\"https://static.simonwillison.net/static/2026/heron-oil.webp\" /></p>\n<p>Quick Study uses <a href=\"https://en.wikipedia.org/wiki/Sobel_operator\">Sobel edge detection</a>, with no external libraries beyond Google Fonts.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/tools\">tools</a></p>",
"url": "https://simonwillison.net/2026/Oct/23/quick-study-painter/",
"published": "2026-10-23T21:35:13.000Z",
"updated": "2026-10-23T21:35:13.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "tools",
"term": "tools",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/23/kimi-k31-pro/",
"title": "Introducing Kimi K3.1 Pro",
"description": "<p><strong><a href=\"https://www.kimi.ai/blog/kimi-k3-1-pro\">Introducing Kimi K3.1 Pro</a></strong></p>\nKimi K3.1 Pro landed on the Kimi API today - it's not yet open weights, but Moonshot promise \"Full model weights will be released by Nov 4, 2026\".</p>\n<p>They're also offering a \"Highspeed\" version that's 2-3x faster, at twice the price (except for input token cache hits, which are priced the same).</p>\n<p>The <a href=\"https://platform.kimi.ai/docs/pricing/chat\">US dollar pricing</a> is $2.00/million tokens for input and $10/million for output - the same as GPT-6.1 Sol and half the price of Claude Opus 5.5.</p>\n<p>Moonshot's own benchmarks show Kimi as approximately level with Opus 5.5 and GPT-6 Astra - beating them on a few benchmarks, coming close on others.</p>\n<p>Artificial Analysis <a href=\"https://artificialanalysis.ai/models/kimi-k3-1-pro\">scored Kimi at 55</a> - ahead of Claude Fable 5.1, GPT-6 Astra, and Gemini 4 Argon (all at 53) and behind only Claude Opus 5.5 (58).</p>\n<p>This is the first time a (soon-to-be) open weight model has scored this highly against the frontier.</p>\n<p>I tried it out via the <a href=\"https://platform.kimi.ai/docs/get-your-api-key\">Moonshot API</a> using the <a href=\"https://llm.datasette.io/en/stable/other-models.html#openai-endpoint\">llm openai endpoint</a> command I added to <a href=\"https://llm.datasette.io/en/stable/changelog.html#v0-32\">LLM 0.32</a> back in August:</p>\n<pre><code>llm openai endpoint \\\n https://api.moonshot.ai/v1 \\\n --key kimi \\\n -m kimi-k3.1-pro \\\n \"Generate an SVG of a pelican riding a bicycle\" \\\n --responses \\\n -o reasoning_effort low \\\n > kimi-k3.1-pro-pelican-low.stdout.txt \\\n 2> kimi-k3.1-pro-pelican-low.stderr.txt\n</code></pre>\n<p><code>llm openai endpoint</code> can run prompts against any OpenAI-compatible endpoint but doesn't log the results, hence the extra options to save stdout and stderr (the reasoning trace).</p>\n<p>Here <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9b7181492209387da1d4f53002f26663\">are the pelicans</a> I got for Kimi K3.1 Pro on the three reasoning levels it supports - low, medium, and max. This is max:</p>\n<p><img alt=\"It's pretty solid - feet are on the pedals, bicycle frame is good, nice beak. Both legs are on the same side of the Fram though.\" src=\"https://static.simonwillison.net/static/2026-10-23/image-2.png\" /></p>\n<p>For comparison, I ran fresh <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Feba9a4283c9e94cbbb5325902a3921a8\">pelicans against Kimi K3</a> on those three reasoning levels.\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50212065\">Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/llm\">llm</a>, <a href=\"https://simonwillison.net/tags/llm-pricing\">llm-pricing</a>, <a href=\"https://simonwillison.net/tags/pelican-riding-a-bicycle\">pelican-riding-a-bicycle</a>, <a href=\"https://simonwillison.net/tags/llm-release\">llm-release</a>, <a href=\"https://simonwillison.net/tags/ai-in-china\">ai-in-china</a>, <a href=\"https://simonwillison.net/tags/moonshot\">moonshot</a>, <a href=\"https://simonwillison.net/tags/kimi\">kimi</a></p>",
"url": "https://simonwillison.net/2026/Oct/23/kimi-k31-pro/",
"published": "2026-10-23T19:40:54.000Z",
"updated": "2026-10-23T19:40:54.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "llm",
"term": "llm",
"url": null
},
{
"label": "llm-pricing",
"term": "llm-pricing",
"url": null
},
{
"label": "pelican-riding-a-bicycle",
"term": "pelican-riding-a-bicycle",
"url": null
},
{
"label": "llm-release",
"term": "llm-release",
"url": null
},
{
"label": "ai-in-china",
"term": "ai-in-china",
"url": null
},
{
"label": "moonshot",
"term": "moonshot",
"url": null
},
{
"label": "kimi",
"term": "kimi",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/22/de-staat-freedom/",
"title": "DE STAAT - FREEDOM (Official Music Video)",
"description": "<p><strong><a href=\"https://www.youtube.com/watch?v=hKO4pQtIXow\">DE STAAT - FREEDOM (Official Music Video)</a></strong></p>\nOK well this is a first for me... at <a href=\"https://www.youtube.com/watch?v=hKO4pQtIXow&t=44s\">00:44</a> in this new music video by Dutch alternative rock band <a href=\"https://en.wikipedia.org/wiki/De_Staat\">De Staat</a>:</p>\n<p><video\n src=\"https://static.simonwillison.net/static/2026/freedom-pelican.mp4\"\n poster=\"https://static.simonwillison.net/static/2026/freedom-pelican-poster.jpg\"\n preload=\"none\"\n loop=\"1\" controls=\"1\"\n playsinline=\"1\" muted=\"1\"\n width=\"1280\"\n height=\"720\"\n style=\"display: block; width: 100%; height: auto;\"\n> </video>\n</p>\n<p>The visual effects are credited to Matties Grooten of <a href=\"https://fakeitorleaveit.com\">Fake it or Leave it</a>.\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50186129#50193407\">flir on Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/music\">music</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/pelican-riding-a-bicycle\">pelican-riding-a-bicycle</a></p>",
"url": "https://simonwillison.net/2026/Oct/22/de-staat-freedom/",
"published": "2026-10-22T19:42:26.000Z",
"updated": "2026-10-22T19:42:26.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "music",
"term": "music",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "pelican-riding-a-bicycle",
"term": "pelican-riding-a-bicycle",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/22/donating-agent-skills/",
"title": "Donating Agent Skills to the Agentic AI Foundation",
"description": "<p><strong><a href=\"https://www.anthropic.com/news/donating-agent-skills-to-the-agentic-ai-foundation\">Donating Agent Skills to the Agentic AI Foundation</a></strong></p>\nNews today from Anthropic:</p>\n<blockquote>\n<p>We’re committed to keeping Agent Skills open, community-driven, and vendor-neutral. Today, we are donating the standard to the Agentic AI Foundation (AAIF) under the Linux Foundation, <a href=\"https://www.anthropic.com/news/donating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation\">which we co-founded</a> with Block and OpenAI last year, and to which we donated the Model Context Protocol (MCP).</p>\n</blockquote>\n<p>I'm pleased to note I called this one <a href=\"https://simonwillison.net/2025/Dec/19/agent-skills/\">last December</a>, when Anthropic first declared skills to be an \"open standard\":</p>\n<blockquote>\n<p>I wouldn't be surprised to see this end up <a href=\"https://simonwillison.net/2025/Dec/9/agentic-ai-foundation/\">in the AAIF</a>, recently the new home of the MCP specification.</p>\n</blockquote>\n<p>Fun side note: since my blog content is available to Claude via the <a href=\"https://github.com/datasette/datasette-mcp\">datasette-mcp</a>\nplugin I found that post by <a href=\"https://claude.ai/share/80b341de-590b-4834-bca9-0d9c9a3a0298\">prompting Claude</a> to \"<code>Use simonwillison.net MCP to find if I ever talked about how I want skills to be donated to a standards body</code>\".\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/standards\">standards</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/anthropic\">anthropic</a>, <a href=\"https://simonwillison.net/tags/model-context-protocol\">model-context-protocol</a>, <a href=\"https://simonwillison.net/tags/skills\">skills</a></p>",
"url": "https://simonwillison.net/2026/Oct/22/donating-agent-skills/",
"published": "2026-10-22T18:09:56.000Z",
"updated": "2026-10-22T18:09:56.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "standards",
"term": "standards",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "anthropic",
"term": "anthropic",
"url": null
},
{
"label": "model-context-protocol",
"term": "model-context-protocol",
"url": null
},
{
"label": "skills",
"term": "skills",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/22/armin-ronacher/",
"title": "Quoting Armin Ronacher",
"description": "<blockquote cite=\"https://twitter.com/mitsuhiko/status/2113207589978636646\"><p>As fun as AI is, we built so much bad software over the last 30 years, and now the universe is punishing us for our sins.</p></blockquote>\n<p class=\"cite\">— <a href=\"https://twitter.com/mitsuhiko/status/2113207589978636646\">Armin Ronacher</a></p>\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/security\">security</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/armin-ronacher\">armin-ronacher</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/ai-security-research\">ai-security-research</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a></p>",
"url": "https://simonwillison.net/2026/Oct/22/armin-ronacher/",
"published": "2026-10-22T15:34:13.000Z",
"updated": "2026-10-22T15:34:13.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "security",
"term": "security",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "armin-ronacher",
"term": "armin-ronacher",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "ai-security-research",
"term": "ai-security-research",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/21/php-security-release/",
"title": "Today's PHP Security Release, and How We're Strengthening PHP Security",
"description": "<p><strong><a href=\"https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/\">Today's PHP Security Release, and How We're Strengthening PHP Security</a></strong></p>\nIf you're running anything on PHP it's vital you upgrade - today's updates (across the entire PHP 8.x line) address two remote code execution holes, and there have been exploits circulating since last night, thanks to a leak in the coordinated disclosure process.</p>\n<p>This post from the PHP Foundation explain what went so wrong:</p>\n<blockquote>\n<p>On Tuesday, October 20th, at around 15:00 UTC, the two CVE IDs began circulating on online forums and social media. They came with a wrong release time and a wrong CVSS score of 10.0 (the actual score is 9.2). No technical details leaked. In response, the PHP project brought its pre-announcement forward and <a href=\"https://www.php.net/archive/2026.php#2026-10-20-1\">published it at 19:30 UTC</a>. It also moved the release from October 22nd, 14:00 UTC, to October 21st, 14:00 UTC [...]</p>\n<p>As a result of the leak and pre-announcement around 20:00 UTC, Calif, one of the security firms that had reported the issues mistakenly published a video. It showed their proof of concept working against a number of targets and revealed a few additional, though limited, details about the vulnerabilities. Copies of the deleted video started circulating on social media soon after. The video contributed to accelerated development of various PoCs (exploitation proof of concepts), which then increased circulation on October 21st.</p>\n</blockquote>\n<p><a href=\"https://www.wiz.io/blog/php2shell-php-rce\">This article</a> from the team that discovered the original vulnerability includes a more detailed timeline of the original intended responsible disclosure:</p>\n<blockquote>\n<ul>\n<li><strong>August 19, 2026:</strong> Wiz Research discovers the first PHP vulnerability using Wiz Atlas, Gemini 4 Argon, and GPT-5.6 Sol.</li>\n<li><strong>August 20, 2026:</strong> Unauthenticated RCE is confirmed against Drupal.</li>\n<li><strong>August 21, 2026:</strong> Unauthenticated RCE is confirmed against WordPress.</li>\n<li><strong>August 24, 2026:</strong> Wiz Research reports the vulnerabilities to the PHP security team.</li>\n<li><strong>September 21, 2026:</strong> PHP acknowledges the reports and begins developing a coordinated fix.</li>\n<li><strong>October 21, 2026:</strong> Patched PHP releases become available.</li>\n<li><strong>October 21, 2026:</strong> Public disclosure.</li>\n</ul>\n</blockquote>\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50182987\">Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/open-source\">open-source</a>, <a href=\"https://simonwillison.net/tags/php\">php</a>, <a href=\"https://simonwillison.net/tags/security\">security</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/ai-security-research\">ai-security-research</a></p>",
"url": "https://simonwillison.net/2026/Oct/21/php-security-release/",
"published": "2026-10-21T18:41:53.000Z",
"updated": "2026-10-21T18:41:53.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "open-source",
"term": "open-source",
"url": null
},
{
"label": "php",
"term": "php",
"url": null
},
{
"label": "security",
"term": "security",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "ai-security-research",
"term": "ai-security-research",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/21/panache/",
"title": "Panache — RTS Belle Époque pour mobile",
"description": "<p><strong><a href=\"https://github.com/menufactory43/panache/\">Panache — RTS Belle Époque pour mobile</a></strong></p>\nWell this is delightful: I <a href=\"https://simonwillison.net/2026/Oct/20/battledrones/\">released Battle Drones</a> yesterday under an Apache 2.0 License and there's already a French language fork which reskins the game to take place in steampunk 1900s France and adds an animated intro!</p>\n<blockquote>\n<p><strong>Panache</strong> est un jeu de stratégie en temps réel pour mobile et navigateur, dans la France de la Belle Époque (vers 1900) : dirigeables, Fardiers à vapeur, Creusot cuirassés, automates en képi, Gargantua la forteresse marchante — et beaucoup de panache.</p>\n</blockquote>\n<p>You can <a href=\"https://menufactory43.github.io/panache/\">play Panache here</a> - it's worth clicking that link just to experience the new intro video.</p>\n<p>So far it's mostly just aesthetic updates as opposed to gameplay changes. The music has had a French twist added to it as well.</p>\n<p>The new steampunk models are so cool!</p>\n<p><img alt=\"The new buildings are gold and red, there are dirigibles and biplanes, and the Goliath stomping mech has had a total makeover.\" src=\"https://static.simonwillison.net/static/2026/battledrones-french.jpg\" /></p>\n<p>Here's a page with <a href=\"https://simonw.github.io/battledrones/models.html\">the original Battle Drones models</a> and that same page <a href=\"https://menufactory43.github.io/panache/models.html\">with the new Panache alternatives</a>.</p>\n<p>This is a comparison of the original and the new design for the Goliath:</p>\n<p><img alt=\"On the left: blue stomping mech robot, missile launcher shoulders, classic sci-fi robot look. On the right: gold, steampunk, much more 1900s French look.\" src=\"https://static.simonwillison.net/static/2026/battledrones-goliath-diff.jpg\" />\n\n <p><small></small>Via <a href=\"https://twitter.com/Meffysto69/status/2112908755654365220\">@Meffysto69</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/open-source\">open-source</a></p>",
"url": "https://simonwillison.net/2026/Oct/21/panache/",
"published": "2026-10-21T16:25:16.000Z",
"updated": "2026-10-21T16:25:16.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "open-source",
"term": "open-source",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/20/emudhra-certificates/",
"title": "eMudhra Intermediate CA Compromise",
"description": "<p><strong><a href=\"https://emudhra.we-have-a-problem.com\">eMudhra Intermediate CA Compromise</a></strong></p>\nThis is very, very bad news:</p>\n<blockquote>\n<p>The private keys of eight eMudhra intermediate CA certificates have been compromised. They chain to roots trusted by the Mozilla, Microsoft, Apple and Chrome root programs and by many downstream trust stores.</p>\n</blockquote>\n<p>Any software that bundles a list of trusted certificates needs to be updated. This site is tracking software updates <a href=\"https://github.com/galadran/we-have-a-problem.com\">via this GitHub repository</a> - Linux distros need to update their <code>ca-certificates</code> packages.</p>\n<p>In Python world <a href=\"https://github.com/astral-sh/uv/releases/tag/0.13.4\">uv 0.13.4</a> and <a href=\"https://github.com/pypa/pip/releases/tag/26.2.2\">pip 26.2.2</a> and <a href=\"https://github.com/certifi/python-certifi/releases/tag/2026.10.19\">certifi 2026.10.19</a> have been released with upgraded certificate lists.</p>\n<p>There's a <a href=\"https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576\">very informative thread</a> about this on the official Python forum.\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/encryption\">encryption</a>, <a href=\"https://simonwillison.net/tags/https\">https</a>, <a href=\"https://simonwillison.net/tags/pip\">pip</a>, <a href=\"https://simonwillison.net/tags/python\">python</a>, <a href=\"https://simonwillison.net/tags/security\">security</a>, <a href=\"https://simonwillison.net/tags/uv\">uv</a></p>",
"url": "https://simonwillison.net/2026/Oct/20/emudhra-certificates/",
"published": "2026-10-20T23:50:25.000Z",
"updated": "2026-10-20T23:50:25.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "encryption",
"term": "encryption",
"url": null
},
{
"label": "https",
"term": "https",
"url": null
},
{
"label": "pip",
"term": "pip",
"url": null
},
{
"label": "python",
"term": "python",
"url": null
},
{
"label": "security",
"term": "security",
"url": null
},
{
"label": "uv",
"term": "uv",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/20/battledrones/",
"title": "Battle Drones - a vibe coded RTS with audio-based multiplayer",
"description": "<p>My latest vibe coded game experiment is a Command & Conquer style RTS (Real Time Strategy) game called <a href=\"https://github.com/simonw/battledrones#readme\">Battle Drones</a> (<a href=\"https://simonw.github.io/battledrones/\">play it here</a>). Unlike <a href=\"https://simonwillison.net/2026/Aug/5/raccoon-heist/\">my previous experiments</a>, this one is <em>actually fun to play</em>. I'm somewhat embarrassed to admit that I got there by telling Claude to \"Make it a LOT more fun\". It also supports multiplayer between nearby devices using audio to synchronize game state! Here's what I've built so far, and some of the things I learned along the way.</p>\n\n<ul>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#battle-drones\">Battle Drones</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#how-i-built-this\">How I built this</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v1-the-initial-prototype\">v1: the initial prototype</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v2-full-sprites\">v2: full sprites</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v3-varied-terrain\">v3: varied terrain</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v4-the-fun-update\">v4: the fun update</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v5-battle-drones-goes-3d\">v5: Battle Drones goes 3D</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v8-archipelago\">v8: Archipelago</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v10-goliath-and-agent-battles\">v10: Goliath, and agent battles</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#agent-battles\">Agent battles</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v11-random-maps\">v11: Random Maps</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#v12-multiplayer-via-sound\">v12: Multiplayer via sound</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#some-thoughts\">Some thoughts</a></li>\n <li><a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support\">Update: Online multiplayer support</a></li>\n</ul>\n\n<h4 id=\"battle-drones\">Battle Drones</h4>\n<p>My initial goal was to build an RTS game I could play on my phone, in the style of <a href=\"https://en.wikipedia.org/wiki/Command_&_Conquer_(1995_video_game)\">Command & Conquer</a>. I have fond memories of the 1995 original (I liked Red Alert too) and wanted to recapture a little bit of the magic.</p>\n<p>After 12 major iterations (and <a href=\"https://github.com/simonw/battledrones/commits/main/\">321 commits</a> by coding agents, mainly Claude Code) I now have a browser-based game that works on mobile and desktop, has multiple play modes, several maps (including a random map generator) and even supports multiplayer for two devices within microphone range of each other. (<strong>Update</strong>: also <a href=\"https://simonwillison.net/2026/Oct/20/battledrones/#update-online-multiplayer-support\">online multiplayer</a>; the audio multiplayer induced headaches!)</p>\n<p>Here's a video demo of Battle Drones running in a desktop browser:</p>\n\n<video\n src=\"https://static.simonwillison.net/static/2026/archipelago_720p_h264.mp4\"\n poster=\"https://static.simonwillison.net/static/2026/archipelago_poster.jpg\"\n preload=\"none\"\n loop=\"1\" controls=\"1\"\n playsinline=\"1\" muted=\"1\"\n width=\"1280\"\n height=\"706\"\n style=\"display: block; width: 100%; height: auto;\"\n> </video>\n\n<p style=\"margin-top: 1em\">Features so far include:</p>\n<ul>\n<li>9 buildings, 7 ground vehicles, 6 aerial vehicles, 3 infantry units - all 3D models, which you can <a href=\"https://simonw.github.io/battledrones/models.html\">browse here</a>\n</li>\n<li>Fog of war</li>\n<li>Different weapons are needed to target aerial or ground vehicles</li>\n<li>\n<strong>Six maps</strong>, across five biomes - temperate, desert, arctic, volcanic, tropical</li>\n<li>A random map generator</li>\n<li>\n<strong>Skirmish mode</strong> - red vs. blue on a rotationally symmetrical map</li>\n<li>\n<strong>Last Stand mode</strong> - one player holds out against as many waves of enemies as possible</li>\n<li>Area effect weapons: Barrage, EMP, Drop Pod, Sky Hammer</li>\n<li>\n<strong>Crate drops</strong> with bonus resources</li>\n<li>In-game music that responds to events - it gets more intense as fighting breaks out</li>\n<li>Different in-game <strong>AI personalities</strong> (Balanced, Rush, Air Swarm, Boom, Skyforce, Ironclad)</li>\n<li>\n<strong>AI vs. AI</strong> mode, to watch those personalities play each other</li>\n<li>The <strong>Goliath</strong> - a giant stomping mech with laser eyes and arm cannons and the ability to establish a new base</li>\n<li>\n<strong>Mutators</strong> that add extra rules or twists</li>\n<li>A \"Daily Op\" challenge</li>\n<li>Ranks and achievements (<strong>Medals</strong>)</li>\n<li>\n<strong>Agent vs. Agent</strong> mode where two LLMs can play Battle Drones against each other</li>\n<li>A <strong>multiplayer mode</strong> based on two nearby phones communicating via audio messages, an extension of my earlier experiment with <a href=\"https://simonwillison.net/2026/Oct/15/chirp-pong/\">Chirp Pong</a>\n</li>\n</ul>\n<h4 id=\"how-i-built-this\">How I built this</h4>\n<p>Battle Drones is heavily vibe coded - I've reviewed almost none of the code, and it's built in a language (TypeScript) that I've hardly used myself. I've playtested it quite a bit though, and it's been through a large number of iterations since I started the project.</p>\n<p>Here's a rough history of the project so far, including key prompts and links to transcripts.</p>\n<h4 id=\"v1-the-initial-prototype\">v1: the initial prototype</h4>\n<p>I started out with Claude Fable 5 back in July:</p>\n<blockquote>\n<p><code>We are going to build a mobile friendly RTS game - command and conquer style - called Battle Drones, in which two armies of drones (both flying and ground-based) battle for territory and resources</code></p>\n<p><code>Let's start with a MVP design, ask me some questions</code></p>\n</blockquote>\n<p>Here's a <a href=\"https://claude.ai/code/session_015RYeKm4ji4N16oqthyX1b1\">shared transcript</a>. I'd given Claude Code for Web an environment variable with an OpenAI API key and told it to use the OpenAI <a href=\"https://developers.openai.com/api/docs/guides/image-generation\">Image Generation API</a> for assets, which got me some basic sprites.</p>\n<p>You can <a href=\"https://simonw.github.io/battledrones/v1/\">try v1 here</a> - it looked like this:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v1.webp\" alt=\"Game screen. Down the right are text icons to build Fab, Airpad, Turret, Harv, Sting, Flak, Scout, Wasp, Raptor. There is a blocky fog of war on a 2D battlefield. There are some gems, an HQ building being attacked by badly rendered tanks, and some blue vehicles dotted around. It's not very visually impressive but it does look like a basic RTS.\" style=\"max-width: 100%;\" /></p>\n<p>It's recognizable as an RTS, has building mechanics and the ability to select and direct units, and a basic AI to play against.</p>\n\n<p>This first version was barely a proof of concept, and it wasn't any fun to play.</p>\n<p>Claude used the <a href=\"https://github.com/phaserjs/phaser\">Phaser</a> 2D game framework for these early versions. I didn't even realize this until several iterations later!</p>\n<h4 id=\"v2-full-sprites\">v2: full sprites</h4>\n<p>The second version (<a href=\"https://simonw.github.io/battledrones/v2/\">try v2 here</a>) added sprites for all of the vehicles and the \"AI vs. AI\" mode, so I could watch the game playing without having to directly control it myself.</p>\n<p>Claude proved reasonably competent at prompting OpenAI's image models to generate sprites. You can browse the v2 sprites in the <a href=\"https://github.com/simonw/battledrones/tree/v2/public/assets/sprites\">public/assets/sprites</a> folder.</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v2.webp\" alt=\"Four flying units, three turrets, a harvester and an airpad all have proper sprites now. The scrap field has a new design which doesn't look great but is at least using a graphic.\" style=\"max-width: 100%;\" /></p>\n<h4 id=\"v3-varied-terrain\">v3: varied terrain</h4>\n<p>It still wasn't much fun, and the graphics were boring. It was now October, and I had upgraded to Claude Opus 5.5. I told it:</p>\n<blockquote>\n<p><code>Massively improve this game. Make the graphics and gameplay better (keep it mobile friendly). Render new graphics using the latest OpenAI GPT image API (lookup details) with the API key in the environment variable. Add new unit types and balance the gameplay better. Also add new buildings and better, more varied terrain.</code></p>\n</blockquote>\n<p>This resulted in five new maps with generated background tiles in a variety of styles, <a href=\"https://github.com/simonw/battledrones/commit/aa22f08a34347d7d9f94b33f44a73b4deb046aa1\">visible here</a>. Opus also regenerated the sprites, making them much more visually appealing. You can <a href=\"https://simonw.github.io/battledrones/v3/\">try v3 here</a> - it looks like this:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v3.jpg\" alt=\"The map is now an ice map with snow and ice and broken ice - it looks really good. The vehicles and buildings have all had a cosmetic upgrade too. This is starting to look like a real game.\" style=\"max-width: 100%;\" /></p>\n<p>This is starting to feel like a real game! It still wasn't very fun to play though - I found myself getting bored pretty quickly.</p>\n<h4 id=\"v4-the-fun-update\">v4: the fun update</h4>\n<p>So far my Battle Drones experiment was confirming my <a href=\"https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp\">previous belief</a> that coding agents can build a thing that looks like a game but can't actually make something that's genuinely compelling to play.</p>\n<p>I shared this theory with someone over dinner, and then thought to myself that I should give the models a proper chance to prove me wrong. I prompted Opus 5.5 on my phone:</p>\n<blockquote>\n<p><code>This game isn't fun enough yet. Make it a LOT more fun.</code></p>\n</blockquote>\n<p>This time I was running in <a href=\"https://code.claude.com/docs/en/workflows\">Ultracode mode</a>, where Claude Code (in this case Claude Code for Web) runs \"dynamic workflows\", described in their docs as:</p>\n<blockquote>\n<p>A dynamic workflow is a JavaScript script that orchestrates many <a href=\"https://code.claude.com/docs/en/sub-agents\">subagents</a> at once.</p>\n</blockquote>\n<p>This kicked off <em>many hours</em> of work. I started it in the evening and didn't get a playable result back until late into the next morning. But the results were spectacular.</p>\n<p>You can <a href=\"https://simonw.github.io/battledrones/v4/\">try v4 here</a> - it looks like this:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v4.jpg\" alt=\"The lava map. Uplink satellites are being taken, crystals look better, Elite text is shown above a unit, there is an arrow marked Fight to jump to a fight, the AI vs AI mode has a speed controller - plenty of new features here.\" style=\"max-width: 100%;\" /></p>\n<p>I had Claude <a href=\"https://github.com/simonw/battledrones/blob/main/Battle%20Drones%20The%20Fun%20Update%20%E2%80%94%20Release%20Notes.md\">write its own release notes</a> - here are the highlights:</p>\n<blockquote>\n<p>Every skirmish and Daily Op now opens with a choice, gives the side that's losing a way back, and pulls the armies into the middle of the map. There are also two new ways to play.</p>\n<ul>\n<li>\n<strong>Openers</strong>: pick Blitz, Industry or Air Wing before the clock starts.</li>\n<li>\n<strong>Call-down powers</strong>: Barrage, EMP, Drop Pod and the Sky Hammer orbital strike.</li>\n<li>\n<strong>Objectives and salvage</strong>: Uplink relays, supply drops and wrecks worth scrap.</li>\n<li>\n<strong>Feel</strong>: combat juice, adaptive music, unit voices and an announcer.</li>\n<li>\n<strong>Command</strong>: battle alerts, game speed, saved squads and touch placement.</li>\n<li>\n<strong>New modes</strong>: Last Stand survival waves and an 8-mission Ops campaign.</li>\n<li>\n<strong>Progression</strong>: heroes, an after-action report with awards, a career, 7 mutators and a Daily Op.</li>\n</ul>\n<p>Fights run longer and swing more. In 1,200 AI-vs-AI test matches on Normal, games still undecided after 25 minutes fell from 14% to 0.9%. The share of wins by a side that had been 800+ scrap behind rose from 24% to 46%.</p>\n</blockquote>\n<p>Part of the reason Claude took so long was that it ran over a thousand simulated playtest sessions, and used the results to rebalance the existing units, add new ones, and introduce new features.</p>\n<h4 id=\"v5-battle-drones-goes-3d\">v5: Battle Drones goes 3D</h4>\n<p>After the success of Ultracode at \"Make it a LOT more fun\", I decided to be more ambitious:</p>\n<blockquote>\n<p><code>Port this game to three.js with 3D models for all of the buildings and vehicles and landscapes</code></p>\n</blockquote>\n<p>That was another overnight run. I woke up to <a href=\"https://simonw.github.io/battledrones/v5/\">this v5 version</a>:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v5.jpg\" alt=\"Now it is in 3D - the battlefield is at a slight angle, the buildings and vehicles are all 3D models, the rocks and trees look a bit 3D as well.\" style=\"max-width: 100%;\" /></p>\n<p>The new 3D models were entirely constructed by Claude in TypeScript code.</p>\n<p>v6 (<a href=\"https://simonw.github.io/battledrones/v6/\">play v6 here</a>) added some more visual polish. v7 (<a href=\"https://simonw.github.io/battledrones/v7/\">play v7</a>) added robot infantry (troopers, rocket squads, snipers) and a \"Condor\" troop carrying aircraft.</p>\n<h4 id=\"v8-archipelago\">v8: Archipelago</h4>\n<p>I was beginning to feel guilty at how little actual design input I had into the game - it really had been a case of me saying \"make it more fun\" and \"add visual polish\" for the past few releases.</p>\n<p>I'd noticed that the AI didn't use the new infantry and troop carrying aircraft from v7 very often - there wasn't a great strategic reason to use them.</p>\n<p>It would be neat if we had a new map with a new game mechanic that actively encouraged players to load up Condors with infantry robots and send them out into the map.</p>\n<p>This resulted in my longest prompt yet:</p>\n<blockquote>\n<p><code>Design a new map. Goal is to make different strategic incentives that encourage use of Infantry and Condors and aerial vehicles.</code></p>\n<p><code>To do this the map will have limited harvester resources but several more uplinks - but uplinks will be on islands that are inaccessible by land vehicles or infantry. These uplinks can also not be claimed using air vehicles. The ONLY way to get them is to fly infantry there in a Condor.</code></p>\n<p><code>Armies always start with a Condor and a single squad. If an army has no Condor a new one will be provided for free, flying in from the edge closest to their HQ and landing there. That free condor will come with a single free squad on board.</code></p>\n<p><code>The two HQs should be entirely separated by water, but still accessible by vehicles thanks to two bridges across the map in different places</code></p>\n<p><code>I want to encourage a battle over uplinks.</code></p>\n<p><code>The map should be the times the size of other maps - still square</code></p>\n<p><code>First research and then critique this design. Only build after we have agreed on any modifications</code></p>\n<p><code>You get to design a new biome for this</code></p>\n</blockquote>\n<p>The result was the tropical <strong>Archipelago</strong> map, with seven island uplinks that players can only capture by flying out infantry in a Condor. It's definitely the most fun map to play, once you've got the hang of the basic game mechanics from the simpler maps. The <a href=\"https://simonw.github.io/battledrones/v9/\">v9 edition</a> made that map a little more interesting - it now looks like this:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/battledrones-v8.jpg\" alt=\"Three islands, each with an uplink satellite. Blue holds one, red holds another, A blue condor is flying towards the red island, which is guarded by a red plane. There is a bridge nearby. The theme is tropical islands and looks very pleasant.\" style=\"max-width: 100%;\" /></p>\n<h4 id=\"v10-goliath-and-agent-battles\">v10: Goliath, and agent battles</h4>\n<p>I decided to add giant robot mechs to the game - think Jaegers from <a href=\"https://en.wikipedia.org/wiki/Pacific_Rim_(film)#Plot\">Pacific Rim</a>, or Titans from Warhammer 40,000.</p>\n<p>Here are some of the prompts I used to brainstorm with Claude:</p>\n<blockquote>\n<p><code>Help me brainstorm ideas for adding giant robots to this game - think dreadnoughts or titans from W20K - how could we do this in a way that enhanced gameplay, kept things balanced, added unique twist? Don't overthink this yet</code></p>\n</blockquote>\n<blockquote>\n<p><code>Let's keep brainstorming. I like the idea that it's a mobile base - that can accept harvested scrap and can have buildings built near it (even if it later moves on) and can produce infantry units too. An interaction with condor would be neat but I don't know what that could be.</code></p>\n</blockquote>\n<blockquote>\n<p><code>Idea: as it gets damage it loses the ability to fire some weapons - by default it has eye laser (like lancers) and arm canons (like titan) and two shoulder mounted mortars, plus machine guns similar to a squad of troops</code></p>\n</blockquote>\n<blockquote>\n<p><code>Damage knocks out mortars and then laser - it always has guns. You can't build next to a building that was only put there because of the mech, you need the mech there for off-base building and only within three squares of it</code></p>\n</blockquote>\n<blockquote>\n<p><code>[...] Lets do two condors can carry the mech</code></p>\n</blockquote>\n<p>The end result is <em>really cool</em>.</p>\n\n<video\n width=\"1644\"\n height=\"1080\"\n preload=\"none\"\n loop=\"1\" controls=\"1\"\n playsinline=\"1\" muted=\"1\"\n style=\"display: block; width: 100%; height: auto;\"\n poster=\"https://static.simonwillison.net/static/2026/goliath-poster.jpg\"\n>\n <source src=\"https://static.simonwillison.net/static/2026/goliath.mp4\" type=\"video/mp4\" />\n Your browser does not support HTML video.\n</video>\n\n<p style=\"margin-top: 1em\">Goliaths can be constructed using a Gantry - a building that can only be created after first building a Fab, Bay, Airpad, and Tech Lab. You can see the Goliath under construction, and it then walks out from the Gantry and can march around the map.</p>\n<p>Goliaths can \"anchor\", which digs them into the ground. In their anchored state they can act as a new HQ, constructing infantry units and additional buildings in a new area.</p>\n<p>Two Condor aircraft can hook onto a Goliath, at which point it can be flown around the map!</p>\n<p>The game now ends when you destroy the enemy's HQ building <em>and</em> any Goliaths they might have built.</p>\n<p>There are also a couple of mutators relating to Goliaths:</p>\n<ul>\n<li>\n<strong>Goliath Armada</strong> starts each side with four airborne Goliaths (each with a pair of Condors) and no other units.</li>\n<li>\n<strong>Robot Love</strong> adds a special rule: if enemy Goliaths get close to each other on the battlefield they fall in love and the game ends in a draw. (Thank Natalie for that one).</li>\n</ul>\n<h4 id=\"agent-battles\">Agent battles</h4>\n<p>The other v10 feature is <strong>agent battles</strong>. In musing about how multiplayer could work I had an idea: what if different LLMs could fight it out in the game?</p>\n<blockquote>\n<p><code>Fun extra challenge: think about how we might make multiplayer available to coding agents. It would be neat if we could set up a battle between eg GPT-6 Sol and Claude Opus 5.5 where each model has access to a tool which gives them information about the game (presumably non-visual, but only the information they could see through fog of war etc) and lets them control their units etc [...]</code></p>\n<p><code>Consult ~/dev/llm/docs and include notes in that file about how LLM could be used here via a new tools plugin</code></p>\n</blockquote>\n<p>Opus 5.5 went to work on this, producing <a href=\"https://github.com/simonw/battledrones/blob/7001ed186c8b8aef4acb27f680ecf4c09b607e54/AGENT-BATTLES.md\">this AGENT-BATTLES.md proposal</a> and then implementing and testing it. The feature also includes the ability to record and replay these battles - here's <a href=\"https://simonw.github.io/battledrones/v11/?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json\">a replay of Claude Haiku 5.5 vs. GPT-6 Luna</a>, and here's that same battle <a href=\"https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1\">in a separate debug tool</a> that shows the underlying prompt responses.</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/agent-v-agent.jpg\" alt=\"Screenshot of a replay of a real-time strategy game between two AI models, shown from a top-down view of a snowy map with a dark frozen lake of cracked ice floes on the left and pine forests at the top and lower right. Top bar: pause button, \"6:27\", \"1×\", \"anthropic/claude-haiku-5-5 · industry\" in blue, \"gpt-6-luna · industry\" in red, a blue-and-red strength bar labeled \"B\" and \"R\", and \"0:03\". Left notification: \"Blue: Pushing turrets at the enemy's south-east edge.\" Replay panel: \"Blue anthropic/claude-haiku-5-5 · industry vs Red gpt-6-luna · industry · frostbite seed 42\", a timeline slider at \"6:27 / 7:48\", and buttons \"−30s\", \"+30s\", \"All\", \"Blue's eyes\", \"Red's eyes\", \"Notes\". In the scene, a group of blue tanks and a large blue Goliath mech trailing smoke advance near the ice edge at lower center, while a column of red turrets (one burning) lines the ice to their north, red tanks and trucks sit by a rocky ridge to the east, and red base buildings occupy the top right. A minimap is in the top right corner and zoom in, zoom out and lightning-bolt buttons are on the lower left.\" style=\"max-width: 100%;\" /></p>\n<p>The prompt that drives agent battles <a href=\"https://github.com/simonw/battledrones/blob/d584e351d9d28c4ba058b78ddcca9b93cd9bcd33/llm-tools-battledrones/llm_tools_battledrones.py#L106-L117\">can be seen here</a>.</p>\n<p>There are a few more replays like this <a href=\"https://github.com/simonw/battledrones/blob/main/README.md#watch-ai-models-play-it\">linked in the README</a>. I hope to turn this into a full league table at some point in the future.</p>\n<h4 id=\"v11-random-maps\">v11: Random Maps</h4>\n<p>This version exists purely because I glanced at my <a href=\"https://claude.ai/new#settings/usage\">Claude Usage</a> page one day and saw that I'd only used 75% of my weekly allowance and it was resetting in 45 minutes. I decided to see if I could get an extra Battle Drones feature from my remaining tokens, and picked \"random map\" as the target:</p>\n<blockquote>\n<p><code>Design and implement a mechanism for generating a random map using any of the available biomes - it should be the size of the largest map and rivers and bridges and rocks and forest and scrap and crystals are all in play. Make them rotationally symmetric and use a seed to allow them to be selected or reused later. You have 45 minutes to build this! Be creative.</code></p>\n</blockquote>\n<p>Here's <a href=\"https://claude.ai/code/session_01CfwMwDaK1kLKnRV6di8VMT\">the transcript</a>, and an image Claude generated to show me its work:</p>\n<p><img src=\"https://static.simonwillison.net/static/2026/random-map-contact-sheet.jpg\" alt=\"Grid of ten top-down game maps, two per biome (temperate, desert, arctic, volcanic, tropical), each with a river or lava flow, bridges and roads. Title: \"Battle Drones: generated maps (108x108, point-symmetric), 2 per biome, runtime ground painter\". Each map is captioned with a name and layout type plus a seed and crossing counts, e.g. \"Hawthorn Delta · fork\" \"random-temperate-1x8a6r2 · 6 bridges, 4 fords\"; layout types are fork, badlands, crossing and lake.\" style=\"max-width: 100%;\" /></p>\n<h4 id=\"v12-multiplayer-via-sound\">v12: Multiplayer via sound</h4>\n<p>I only <em>just</em> got this working, so I've not had much time to actively test it yet. The latest Battle Drones now supports multiplayer via two devices sat within microphone distance of each other!</p>\n<p>This feature started out as my <a href=\"https://simonwillison.net/2026/Oct/15/chirp-pong/\">Chirp Pong</a> experiment from last week. I pointed Claude Code at that working proof of concept:</p>\n<blockquote>\n<p><code>Clone Simonw/tools from GitHub and look at recent branches for the example pong game that uses web microphone to implement multiplayer between two phones via audio signals</code></p>\n<p><code>Build a version of that for battledrones</code></p>\n</blockquote>\n<p>Opus built <a href=\"https://simonw.github.io/battledrones/radio-probe.html\">this Radio Probe tool</a> to measure how much bandwidth we could get between two devices and, based on positive results from that, implemented a full audio modem system. I've tried it between laptops, iPhones and iPads so far and it seems to work really well!</p>\n<p>Why use sound for this? Because I <a href=\"https://simonwillison.net/2025/Dec/10/html-tools/#the-anatomy-of-an-html-tool\">love static HTML</a> that costs nothing to run, and I don't want to spin up a server somewhere and then stay responsible for keeping it operating for as long as anyone might want to play the game.</p>\n<h4 id=\"some-thoughts\">Some thoughts</h4>\n<p>I know almost <em>nothing</em> about game development. This makes it a great opportunity to try out coding agents in a field where my existing software engineering experience has less impact on the results.</p>\n<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>\n<p>This morning (<a href=\"https://news.ycombinator.com/item?id=50168190\">via Hacker News</a>) I found <a href=\"https://www.ign.com/articles/steam-fans-are-begging-for-a-no-ai-filter-as-steam-next-fest-is-filled-with-slop\">Steam Fans Are Begging for a No-AI Filter as Steam Next Fest Is Filled With Slop</a>. I wouldn't personally dream of submitting Battle Drones to an event like this - it's still way too low effort to warrant consideration as a legitimate indie gaming project.</p>\n<p>... but I can now see a path to vibe coded games like this being taken seriously. Battle Drones is fun, it looks good, it has innovative features (the multiplayer-over-audio thing is a first for an RTS as far as I can tell).</p>\n<p>I'd love to see what someone with better taste than me and a driving passion to produce something truly exceptional could build!</p>\n<p>A few other observations from this project:</p>\n<ul>\n<li>Static HTML and JavaScript is a fantastic medium for games development. WebGL works great, and <a href=\"https://github.com/mrdoob/three.js/\">Three.js</a> (and <a href=\"https://github.com/phaserjs/phaser\">Phaser</a> before it) are excellent platforms to build on that the current models know inside out.</li>\n<li>This also lets them run as <a href=\"https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps\">Progressive Web Apps</a> - I didn't ask for it, but Battle Drones works offline. I was able to play it on a plane despite never having directly installed it - my phone had it cached.</li>\n<li>Giving Claude an OpenAI API key and telling it to generate images using OpenAI's models works really well. It can view the images it has generated and iterate on the prompts.</li>\n<li>Opus 5.5 is spectacular at 3D modeling using Three.js (and Blender, and no doubt other 3D applications as well). The <a href=\"https://til.simonwillison.net/llms/blender-coding-agents-macos\">same is true</a> of GPT-6 Astra. They are absolutely capable of building models for 3D game projects.</li>\n<li>For features like replay and multiplayer it's useful to have a deterministic simulation engine. At one point Claude had to replace calls to <code>Math.sin()</code> and <code>Math.cos()</code> and friends with <a href=\"https://github.com/simonw/battledrones/blob/v12/src/sim/fmath.ts\">custom versions</a> because different browsers (Chrome vs. Safari, for example) returned very slightly different numbers, desynchronizing the replay.</li>\n<li>Opus 5.5 can write music! There are no audio files in this project - the soundtrack is entirely generated through code, varies across different maps, and even gets more intense as the battle heats up. See <a href=\"https://simonwillison.net/2026/Oct/6/scrimshaw-jukebox/\">Scrimshaw Jukebox</a> for a previous experiment with Claude for music composition.</li>\n<li>I still can't get over how well the prompt \"Make it a LOT more fun\" worked.</li>\n<li>Tools are effectively free. I prompted up the <a href=\"https://simonw.github.io/battledrones/radio-probe.html\">Radio Probe</a>, the <a href=\"https://simonw.github.io/battledrones/models.html\">Model browser</a>, the <a href=\"https://simonw.github.io/battledrones/record-viewer.html?replay=battles/showcase/2026-10-14-frostbite-42-claude-haiku-5.5-vs-gpt-6-luna.json#r1\">Agent vs. Agent debug tool</a>, and Claude Code <a href=\"https://github.com/simonw/battledrones/tree/main/tools\">built a bunch of tools</a> for itself that I haven't even explored myself.</li>\n<li>Audio-based multiplayer between static HTML games works! I hope to see a whole lot more games use this same pattern - in digging around today I've not found much prior art beyond <a href=\"https://github.com/AlonHor/siner\">Siner</a> by Alon Horesh and <a href=\"https://github.com/ggerganov/ggwave\">ggwave</a> by Georgi Gerganov (also of <code>llama.cpp</code> fame).</li>\n<li>Claude Code \"Ultracode\" burns tokens like there's no tomorrow, but it can also solve complex problems (like adding audio-based multiplayer) from a single prompt.</li>\n<li>I'm still not quite over the <em>guilt</em> of building software in this way. I don't feel like I've earned the right to create something this good, in a field in which I have so little prior experience! At this point I've shown it to enough people in private that it felt wrong not to publish it for everyone else to see and learn from.</li>\n</ul>\n\n<h4 id=\"update-online-multiplayer-support\">Update: Online multiplayer support</h4>\n<p>Earlier in this article I said:</p>\n<blockquote>\n<p>Games are also super low stakes. The worst that can happen is one of my silly game experiments suffers a bug.</p>\n</blockquote>\n<p>Then I tried playing the multiplayer version with Natalie... and the high pitched modem sounds gave her a nasty headache!</p>\n<p>That's a pretty bad bug. I <a href=\"https://github.com/simonw/battledrones/pull/36\">added a warning</a> and was then inspired to build proper network multiplayer. I tried <a href=\"https://github.com/simonw/battledrones/pull/37\">getting WebRTC to work</a> but couldn't get a connection going between two of my own devices even on my own WiFi network, so <a href=\"https://github.com/simonw/battledrones/pull/38\">I had Claude build</a> a simple, stateless WebSockets relay server instead:</p>\n<blockquote>\n<p><code>If I wanted to support multiplayer between two devices at a very low cost without storing any state on the server could I do that with a tiny asyncio web server running on the cheapest Fly instance?</code></p>\n</blockquote>\n<blockquote>\n<p><code>Build the server and the fly.toml for deploying it, use Fly application name battledrones-relay - put that in a folder in the repo, include deploy instructions in the README in that folder</code></p>\n</blockquote>\n<p>Here's <a href=\"https://github.com/simonw/battledrones/tree/v13/relay\">the resulting server</a>. Since this scales to zero and runs on a single <a href=\"https://fly.io/\">Fly.io</a> <code>shared-cpu-1x</code> instance it should cost me no more than $2.19/month - and that's if it stays hot and serving connections the whole time.</p>\n<p>Battle Drones now supports online multiplayer. Click \"Duel a friend online\", then either share the resulting room URL via your messaging app of choice or have them snap a picture of the displayed QR Code.</p>\n<p>I also added a feature where you can copy JSON of the match once it has ended and then feed that into the replay feature to rewatch your game.</p>\n<p>I didn't expect to introduce online multiplayer this soon, but the headache bug felt like it warranted an urgent alternative.</p>\n \n <p>Tags: <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/projects\">projects</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/claude\">claude</a>, <a href=\"https://simonwillison.net/tags/vibe-coding\">vibe-coding</a>, <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a>, <a href=\"https://simonwillison.net/tags/claude-code\">claude-code</a></p>",
"url": "https://simonwillison.net/2026/Oct/20/battledrones/",
"published": "2026-10-20T19:34:19.000Z",
"updated": "2026-10-20T19:34:19.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "projects",
"term": "projects",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "claude",
"term": "claude",
"url": null
},
{
"label": "vibe-coding",
"term": "vibe-coding",
"url": null
},
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
},
{
"label": "claude-code",
"term": "claude-code",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/",
"title": "My obituary for programming",
"description": "<p><strong><a href=\"https://dumbmatter.com/2026/10/programming-obituary/\">My obituary for programming</a></strong></p>\nJeremy Scheff poignantly captures the key loss caused by coding agents for career programmers who enjoyed the <em>puzzle</em> of developing code:</p>\n<blockquote>\n<p>Programming turned into one of the greatest jobs you could imagine. You got paid to work on tricky little logic puzzles. The trickier the puzzle, the more you got paid. But even pretty simple puzzles were worth a lot of money because regular people just couldn't do it! No, they needed us. They would give us a problem and we would solve it the way we wanted. We set the strategy, we made the timeline, we defined what was and was not possible.</p>\n</blockquote>\n<p>If you're a programmer who thrives on building working systems and doesn't care too deeply about the problems solved along the way, LLMs are the gift that keeps on giving.</p>\n<p>If directly solving those problems was a big part of your enjoyment, the loss is very real.\n\n <p><small></small>Via <a href=\"https://lobste.rs/s/wtobpt/my_obituary_for_programming\">lobste.rs</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/programming\">programming</a>, <a href=\"https://simonwillison.net/tags/careers\">careers</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a>, <a href=\"https://simonwillison.net/tags/deep-blue\">deep-blue</a></p>",
"url": "https://simonwillison.net/2026/Oct/19/my-obituary-for-programming/",
"published": "2026-10-19T23:58:25.000Z",
"updated": "2026-10-19T23:58:25.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "programming",
"term": "programming",
"url": null
},
{
"label": "careers",
"term": "careers",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
},
{
"label": "deep-blue",
"term": "deep-blue",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/18/llm-tools-datasette/",
"title": "llm-tools-datasette 0.1.1",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/llm-tools-datasette/releases/tag/0.1.1\">llm-tools-datasette 0.1.1</a></p>\n <p>When I switched LLM over to <a href=\"https://github.com/pydantic/httpx2\">httpx2</a> in <a href=\"https://llm.datasette.io/en/stable/changelog.html#v0-33\">LLM 0.33</a> I forget that this would break any plugins which used <code>httpx</code> without directly depending on it. <code>llm-tools-datasette</code> was one of those plugins, now fixed.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/datasette\">datasette</a>, <a href=\"https://simonwillison.net/tags/llm\">llm</a></p>",
"url": "https://simonwillison.net/2026/Oct/18/llm-tools-datasette/",
"published": "2026-10-18T23:43:09.000Z",
"updated": "2026-10-18T23:43:09.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "datasette",
"term": "datasette",
"url": null
},
{
"label": "llm",
"term": "llm",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/18/llm-echo/",
"title": "llm-echo 0.5",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/llm-echo/releases/tag/0.5\">llm-echo 0.5</a></p>\n <p>I'm working towards a new <a href=\"https://llm.datasette.io/\">LLM</a> release, and testing PRs caused me to revisit the <code>llm-echo</code> debug plugin. This plugin provides a \"model\" which doesn't involve an LLM at all - it just repeats back the prompts that have been fed to it. The new release now updates the simulated token usage counts to take tool calls, system prompts, and reasoning tokens into account.</p>\n<p>Example usage:</p>\n<pre><code>uvx --with llm-echo llm -m echo 'hi there' -o thinking 1 --usage\n</code></pre>\n<p>Outputs:</p>\n<pre><code>First I consider the prompt, then I decide what to say.\n{\n \"prompt\": \"hi there\",\n \"system\": \"\",\n \"attachments\": [],\n \"stream\": true,\n \"previous\": []\n}\nToken usage: 2 input, 24 output\n</code></pre>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/llm\">llm</a></p>",
"url": "https://simonwillison.net/2026/Oct/18/llm-echo/",
"published": "2026-10-18T23:16:16.000Z",
"updated": "2026-10-18T23:16:16.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "llm",
"term": "llm",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/17/document-currentscript/",
"title": "Inline rendering with document.currentScript",
"description": "<p><strong><a href=\"https://leanrada.com/notes/inline-rendering-currentscript/\">Inline rendering with document.currentScript</a></strong></p>\nLean Rada describes a neat trick that takes advantage of the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript\">document.currentScript</a> property. You can use that to drop in a tiny inline <code><script></code> element that replaces itself when the page loads:</p>\n<pre><code>The year is <script>\ndocument.currentScript.replaceWith(\n new Date().getFullYear())</script>\n</code></pre>\n<p>If you define a shortcut function like this:</p>\n<pre><code>$=(...n)=>document.currentScript.replaceWith(...n)\n</code></pre>\n<p>You get a tiny template language:</p>\n<pre><code>The year is <script>$(new Date().getFullYear())</script>\n</code></pre>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/javascript\">javascript</a></p>",
"url": "https://simonwillison.net/2026/Oct/17/document-currentscript/",
"published": "2026-10-17T21:11:12.000Z",
"updated": "2026-10-17T21:11:12.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "javascript",
"term": "javascript",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/17/web-edit/",
"title": "web-edit 0.1a2",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/web-edit/releases/tag/0.1a2\">web-edit 0.1a2</a></p>\n <p>web-edit (<a href=\"https://simonwillison.net/2026/Oct/12/web-edit/\">previously</a>) is my tiny web app for browsing and editing files in a folder. I mainly built it for editing files on different machines via Tailscale.</p>\n<p>I added a \"copy to clipboard\" option for both text and image data. I needed this because I was running pelican prompts on a laptop from my phone (here's <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fb1cec9726b6aa62d4de47100f90f0c1a\">DeepSeek 4.1 Flash 1017</a>) and I wanted an easy way to copy the resulting logs into a Gist.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/projects\">projects</a>, <a href=\"https://simonwillison.net/tags/pelican-riding-a-bicycle\">pelican-riding-a-bicycle</a>, <a href=\"https://simonwillison.net/tags/deepseek\">deepseek</a></p>",
"url": "https://simonwillison.net/2026/Oct/17/web-edit/",
"published": "2026-10-17T13:16:49.000Z",
"updated": "2026-10-17T13:16:49.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "projects",
"term": "projects",
"url": null
},
{
"label": "pelican-riding-a-bicycle",
"term": "pelican-riding-a-bicycle",
"url": null
},
{
"label": "deepseek",
"term": "deepseek",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/16/code-review/",
"title": "Quoting Addy Osmani, Morgan Westlee Lunt, and Qing Wang",
"description": "<blockquote cite=\"https://claude.dev/blog/solving-code-review-at-anthropic/\"><p>We think \"did a human read the code?\" is an imprecise proxy for \"what could go wrong with this change, and which check—automated or human—is the right one to catch it?\"</p>\n<p>Asking that question also changed <em>when</em> review happens. Before, review was a gate at the end of the road: write the code, open a PR, wait for your colleague.</p>\n<p>Now, review runs continuously, more like spellcheck while you write. Most changes have been reviewed and fixed by Claude at least once before a human is asked to look. This catches most routine mistakes, and saves team attention for higher-level questions and scrutiny.</p></blockquote>\n<p class=\"cite\">— <a href=\"https://claude.dev/blog/solving-code-review-at-anthropic/\">Addy Osmani, Morgan Westlee Lunt, and Qing Wang</a>, How the Claude Code team does code review</p>\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/anthropic\">anthropic</a>, <a href=\"https://simonwillison.net/tags/claude\">claude</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/claude-code\">claude-code</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/addy-osmani\">addy-osmani</a>, <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/agentic-engineering\">agentic-engineering</a>, <a href=\"https://simonwillison.net/tags/code-review\">code-review</a></p>",
"url": "https://simonwillison.net/2026/Oct/16/code-review/",
"published": "2026-10-16T22:06:37.000Z",
"updated": "2026-10-16T22:06:37.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "anthropic",
"term": "anthropic",
"url": null
},
{
"label": "claude",
"term": "claude",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "claude-code",
"term": "claude-code",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "addy-osmani",
"term": "addy-osmani",
"url": null
},
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "agentic-engineering",
"term": "agentic-engineering",
"url": null
},
{
"label": "code-review",
"term": "code-review",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/",
"title": "sparqlite: SPARQL 1.1 inside SQLite, written in Rust",
"description": "<p><strong>Research:</strong> <a href=\"https://github.com/simonw/research/tree/main/sqlite-sparql-rust#readme\">sparqlite: SPARQL 1.1 inside SQLite, written in Rust</a></p>\n <p>This research task is really an experiment in running Claude Code for web in \"Ultracode\" mode, as described in <a href=\"https://code.claude.com/docs/en/workflows\">Orchestrate subagents at scale with dynamic workflows</a> in the Claude Code documentation.</p>\n<p>With Ultracode turned on, Claude Code makes aggressive use of dynamic workflows - it generates JavaScript that defines and coordinates a network of subagents to take on complex problems.</p>\n<p>My initial prompt was this - I meant \"hit the rows directly\", the word \"delete\" was an accidental typo on my phone:</p>\n<blockquote>\n<p><code>Write a SQLite extension in Rust that implants SPARQL and runs really fast because it can hit the delete rows directly</code></p>\n</blockquote>\n<p>This caused Claude Code for web to churn for over 12 hours. I checked in on its progress the next day and sent a single follow-up prompt when I noticed how many Rust crates it had built:</p>\n<blockquote>\n<p><code>Every folder in the crates/ directory needs a README</code></p>\n<p><code>Include a tutorial.md teaching users how to install the extension and how to run it in the SQLite CLI and then teaching them SPARQL in addition to how to use the SQLite extension</code></p>\n<p><code>Include a script with the tutorial for populating a SQLite database with useful and realistic example data for that tutorial</code></p>\n</blockquote>\n<p>This project feels like next-level vibe coding - it's not remotely feasible to review the code that was produced here, and even following the documentation is a significant investment in work. I'm not entirely sure what to do with this - I appear to have a full SPARQL implementation in Rust inside SQLite now, but how valuable is that if I created it on a whim and can't (or won't) invest the necessary time to understand what it can do?</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/rdf\">rdf</a>, <a href=\"https://simonwillison.net/tags/semantic-web\">semantic-web</a>, <a href=\"https://simonwillison.net/tags/sqlite\">sqlite</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/rust\">rust</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a>, <a href=\"https://simonwillison.net/tags/claude-code\">claude-code</a></p>",
"url": "https://simonwillison.net/2026/Oct/16/sqlite-sparql-rust/",
"published": "2026-10-16T01:58:00.000Z",
"updated": "2026-10-16T01:58:00.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "rdf",
"term": "rdf",
"url": null
},
{
"label": "semantic-web",
"term": "semantic-web",
"url": null
},
{
"label": "sqlite",
"term": "sqlite",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "rust",
"term": "rust",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
},
{
"label": "claude-code",
"term": "claude-code",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/15/chirp-pong/",
"title": "Chirp Pong",
"description": "<p><strong>Tool:</strong> <a href=\"https://tools.simonwillison.net/chirp-pong\">Chirp Pong</a></p>\n <p>Another game experiment - I wanted to see if it was feasible to have a two player game on two separate phones running in static HTML where the networking code uses chirps sent via the microphone. It seems to work!</p>\n<blockquote>\n<p><code>Build a two player competitive pong like game where two players use their phones close to each other and the game state is sent via audio noises which the web microphone API can interpret - but add graphical and gameplay twists to make it a lot more fun and intertwine than pong</code></p>\n</blockquote>\n<p>Claude Opus 5.5 Extra <a href=\"https://claude.ai/code/session_019awUnNB7NoYd7noBNAsNdd\">in Claude Code</a>.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/claude-code\">claude-code</a></p>",
"url": "https://simonwillison.net/2026/Oct/15/chirp-pong/",
"published": "2026-10-15T19:47:52.000Z",
"updated": "2026-10-15T19:47:52.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "claude-code",
"term": "claude-code",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/",
"title": "Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO",
"description": "<p><strong><a href=\"https://www.ft.com/content/11632d03-358c-454b-af95-d06d4072932b?syn-25a6b1a6=1\">Anthropic tells investors quarterly revenue up nearly 50% to $16.8bn ahead of IPO</a></strong></p>\nThe phrase \"told investors\" appears four times in this FT article, which reports on Anthropic's day of hosting investors on Wednesday. Lots of details in here from \"<a href=\"https://simonwillison.net/2023/Nov/22/deciphering-clues/#hints-to-look-out-for\">people with knowledge of the matter</a>\".</p>\n<p>Key things I learned from the article:</p>\n<ul>\n<li>Q1 revenue (Jan/Feb/Mar) was \"about $4.8bn\"</li>\n<li>Q2 (Apr/May/Jun) was $11.5bn</li>\n<li>Q3 (Jul/Aug/Sep) was $16.8bn</li>\n<li>In Q3: $1.70 in revenue for every $1 spent on \"computing power\"</li>\n<li>Adjusted operating margins (excluding stock-based compensation) were 11%</li>\n</ul>\n<p>This point about distillation is worth quoting in full (highlight mine):</p>\n<blockquote>\n<p>The start-up has also clamped down on “distillation” — a controversial practice whereby rival AI labs train their models on the outputs of more advanced ones.</p>\n<p>When rival companies “distil” their models from Anthropic’s models, that involves heavy usage and spending.</p>\n<p>Anthropic told investors on Wednesday <strong>distillation accounted for 5 per cent to 7 per cent of revenue</strong> and that they had cut it back “materially” in the third quarter of the year, said four people with direct knowledge of the matter.</p>\n</blockquote>\n<p>Napkin maths says that if distillation was 5% of their Q2 revenue (before they cut it back in Q3) then unnamed \"other labs\" spent over half a billion dollars distilling Anthropic's models in that quarter!</p>\n<p>Also notable: Anthropic appear to no longer be leaning on \"annualized run-rate revenue\" (<a href=\"https://simonwillison.net/2026/May/29/anthropic/\">previously</a>) in these communications to their investors.\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/anthropic\">anthropic</a></p>",
"url": "https://simonwillison.net/2026/Oct/15/anthropic-tells-investors/",
"published": "2026-10-15T13:04:03.000Z",
"updated": "2026-10-15T13:04:03.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "anthropic",
"term": "anthropic",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/15/latex/",
"title": "LaTeX renderer",
"description": "<p><strong>Tool:</strong> <a href=\"https://tools.simonwillison.net/latex\">LaTeX renderer</a></p>\n <p>Inspired by Paul Ford and Aboard Foundary's new web app <a href=\"https://tinylittleoffice.com/\">Tiny Little Office</a>, which provides a suite of web app content editors (a Word Processor, Outliner, Presentation Builder, Spreadsheet, Calculator, Drawing Tool, Diagram Maker, Animator, Calendar, and Trip Planner).</p>\n<p>Tiny Little Office's signature trick is to store all of the document data in the <code>#fragment</code> section of the URL, so every document created using it becomes a bookmarkable and shareable link.</p>\n<p>It also has <a href=\"https://tinylittleoffice.com/llms.txt\">an llms.txt file</a> telling agents how to construct URLs that will render as documents. Claude <a href=\"https://claude.ai/share/239301ff-edde-420e-b433-b9c16fe40a6c\">used that file</a> to generate <a href=\"https://tinylittleoffice.com/#/v1/deck/zXVVdb9tGEHznr1hED2kBSbZcO4UFtIHTuCgQtylstwH6Uq7Io3gRdcfeHS1T_fjtnV1Ssp038r52d2Z2djabZcmmxizpJ78jpnvrerqxCUv0sapsYaixbkM7HzYxS7XZ4ujWls6u65SlwC7aZL1bUmxsabIZHpxMaCmXlnRfG9rVHm~Vvui2xiWykfDK8Ojfc439b5bN6BdP0YQHE6bkPJWceMXR6A8Xhe9cwqFr7Peptm5NXCUT9Kl8klNM3EeyjnrfBVoFv8Nj2TGbaDgU9ZKuHCe_7clXKFVSkMh5Qs2Nluy14nnhtyeTk4fFSWmKzUn_7e~f5_N5LkcfFvlSg1Y~bDkR8omoXrbkLDZ3tS1q4rYl3xqHnCTvvB~vbX2J2k1C7rI8vjzsHSCaEuK3wcRoSmJXknEFrpVZ9r0CWgVeK5QDBBOB1BlkAgCxmry~dgAz~hePj0i1wT5wMnIY_Ohl0FQ~cTN_Aq~yIo~7ZFpaoL5gcc8iOg6bx5QdaHlB8f3Nxykg_pnDpvQ7Rw8cLCuFdyKTSLEF4uQd5QiTS0gTsftDzSHFKZWBd2A5av3sLLAGzPgNqB94AJlV44uN3LmvEVDQl8C88l2iBX14JyS3DUMTY5pjOS0XG14fKjqDcP_qjNlLTVLLLe_o_fWPN1f319MBSN4a4mbtUXi9lbL3ttW81vgQFvcgcIg0XjwwPv7SDjeBhnBqEpW2kGI49HIu4Bw0fqAcGwRdcdMc6O6fXdAKAcBurA9dWSrYR_AjddGIuH1ayqNbvHft1o2N9RTqc5IIUi~5J4fCAHVEXC5jbZBa1TkNheUjdbF3iR_ndGtaw3i_9RYcr1jwdtAPaLQuJrwhGa2MNGdsTdOAI3DxTEii4hH2b2AivFEd_XZ7M4tcGQH_XZ~gjZVB4oak_9~cd6FZ0htaWQkNmRZQCBdj_1zN_iCe7el0dpkLWZDTf7kWmP~p_Yq_YMBNYQZpd7HjBprLp8OpmViHbRpSDKiCDNWLBo9xxpQatQCyM21DLD8rSNQ6uBwKtgU71eGUVj1Fu0dJeZ4rsnplPL7ioL93CTKkf4aiMyFRhIqFi_PLs~y9qRp0aDmIp8fy4vzsIrsR32y5bzzwxtrl6UKCiFgu5hejLNSKozTg2EdjGz11EioV2kYXpM6VgPZsenp6~gSwaKP2IcF_fLeuxfKgoJjkRBKHi8~43Zh~SZ_qXgyYAMTrpJAKwQDD9ErvJ5Qi7amGdBT1lGpuKl1cKf~DwhDDDTxoj3N6HeFVvfSR9pp1ChBVbJs4oPSqtLA3uAN8zWMjqExfaZshma~~zqVmbWqYGN7j1s4_q3l4MSXG7BunwnFwpCQ~tKTrRwy7KI4l940rdXS8BUK7fLR6HlxI29ylIfH8bZkfJ4HYrSRyGBfztk2PJzIBSFpNOI2jtaLLYbs4~KsWK~MGpgAz10G8pHyYTRP0_Xc5EOm~0CmE89L2ihrnoVUxkfRi8sJzHYTonVE_Ua0cR3Shm1H9CXPLNP2XjovGNI3M0_1smG4C4P8\">this link to a deck</a> that explains how the URL format works:</p>\n<p><img alt=\"Screenshot of a slide deck editor in a web app with a dark-themed presentation open. The document title field reads \"How a Tiny Little Office link works\", with a progress ring, share icon and menu icon at top right. Below is a formatting toolbar with an \"Insert\" dropdown followed by icon buttons for play, bold, italic, underline, strikethrough, highlight, code, link, superscript, emoji, outdent, indent, layout and color palette. The main canvas shows slide 1 with a blue chain-link icon and the text: \"The whole document is the link\" \"No server, no database, no account\" \"Everything after the # stays in your browser\" and a slide counter \"1 / 9\". Below the canvas is a \"SPEAKER NOTES\" heading. A sidebar on the right shows slide thumbnails. Slide 1 (selected): \"The whole document is the link\" \"No server, no database, no account\" \"Everything after the # stays in your browser\". Slide 2: \"Anatomy of a link\" with bullets \"tinylittleoffice.com/#/v1/deck/y7Vj...\" \"v1: the format version\" \"deck: which app opens it\" \"y: the mode letter\" \"7Vj...: the document, compressed and encoded\". Slide 3: \"Step 1: write it as text\" with bullets \"Every document is TLO, a Markdown variant\" \"Slides split on --- lines\" \"Charts, drawings and animations are fenced blocks\" \"This deck is about 1 KB of plain text\". Slide 4: \"Step 2: squeeze it\" with bullets \"Raw DEFLATE, the same algorithm as zip and gzip\" \"z: plain DEFLATE\" \"y: DEFLATE with a preset dictionary\" \"r: no compression at all\".\" src=\"https://static.simonwillison.net/static/2026/tiny-little-office.webp\" /></p>\n<p>Tiny Little Office inspired me <a href=\"https://claude.ai/code/session_017KJrPqqWVHLqr4E7TLPnpt\">to have Claude Code</a> (Opus 5.5 Extra) build a similar tool that works with LaTeX. Here's the sequence of prompts I used:</p>\n<blockquote>\n<p><code>I want a tool where you can link to it with a fragment hash #code-here and it treats that code as LaTeX and renders it really effectively. It should also support a prefix which means the latex is compressed with a custom compression dictionary optimized for latex. Use the best available latex render library from a CDN (consider WebAssembly too). If loaded without a fragment hash show an editor you can paste latex into and then toggle to a \"rendered\" view. That rendered view should be bookmarkable. The #fragment view should let you switch to edit source too.</code></p>\n</blockquote>\n<p>Since it was working in <a href=\"https://github.com/simonw/tools\">my tools repo</a> I told it to take inspiration from the <code><iframe sandbox=\"...\"></code> mechanism used by my existing <a href=\"https://tools.simonwillison.net/markdown-svg-renderer\">SVG in Markdown tool</a> as protection against XSS risks:</p>\n<blockquote>\n<p><code>Safe from XSS? We could run in an iframe sandbox like we do on the SVG markdown render project</code></p>\n</blockquote>\n<p>I had it copy the Gist/URL loading feature from that tool as well:</p>\n<blockquote>\n<p><code>We should have an option to load latex from a URL (or gist) similar to the markdown SVG tool</code></p>\n</blockquote>\n<p>Here's <a href=\"https://tools.simonwillison.net/latex#~1jZq9DoIwEIB3nuKGbigJJS5svoAOMJuQ4EBEJWJjGHh3765A_8DIQtJfIMdR-n0uCV9l4DOs_p8ua3ZZKK2anOsaTqya9AZnHhMo3qqewKWPMh2SOQOFkhSJtmruY1QungBJFk-cQLsspAF8qgFPWKQ6FmdYdCB7oseX5HVNfgE-HGmM2OPATDfAlCssyLcLGI4BONwZ7E8pby5KWoilFBK0n5T4lMeHgQaMMsYjS6hrG61G4Micmcj2EN48tyVgHpzNKMBEHuxEbV0dZhsJwZB7_Lux0mR4YDc9HTd1bnGaki0V1nr6kGHSI8NAwCWaVjeAPyYUNAYxUZt8k2aKlODPRQq7JIYMS-VKaQwHrMmoxqWeLlT6Ag\">an example link</a>. The tool uses <a href=\"https://github.com/nodeca/pako\">Pako 2.1.0</a>, <a href=\"https://github.com/mathjax/MathJax\">MathJax 4.1.3</a>, <a href=\"https://github.com/arena-ai/faster-latex\">faster-latex 0.3.1</a>, and <a href=\"https://github.com/cure53/DOMPurify\">DOMPurify 3.4.16</a>.</p>\n<p><img alt=\"Screenshot of a web app titled \"LaTeX renderer\" with a split-pane layout. The top bar has an Edit/Rendered toggle, a blue Copy link button, and a Share button. The left pane, labeled LaTeX source with a \"Document · faster-latex (WASM)\" badge, has a URL/GitHub Gist input with a Load button, a code editor containing a LaTeX document, and rows of example buttons (Quadratic formula, Gaussian integral, Maxwell, Attention, Matrix, Chemistry, Prose, TikZ, Document). The right pane shows the typeset output: a paper titled \"Sums of Odd Numbers\" by A. Student, with a section stating a theorem that the first n odd numbers sum to n squared, a Proof section with numbered equations, and a bulleted list of small cases.\" src=\"https://static.simonwillison.net/static/2026/latex-tool.webp\" /></p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/latex\">latex</a>, <a href=\"https://simonwillison.net/tags/paul-ford\">paul-ford</a>, <a href=\"https://simonwillison.net/tags/tools\">tools</a>, <a href=\"https://simonwillison.net/tags/urls\">urls</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a></p>",
"url": "https://simonwillison.net/2026/Oct/15/latex/",
"published": "2026-10-15T02:07:28.000Z",
"updated": "2026-10-15T02:07:28.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "latex",
"term": "latex",
"url": null
},
{
"label": "paul-ford",
"term": "paul-ford",
"url": null
},
{
"label": "tools",
"term": "tools",
"url": null
},
{
"label": "urls",
"term": "urls",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/14/tree-appreciator/",
"title": "Tree Appreciator",
"description": "<p><strong>Tool:</strong> <a href=\"https://tools.simonwillison.net/tree-appreciator\">Tree Appreciator</a></p>\n <p>Another game experiment with Claude. This one used the default Claude iPhone app (chat mode, not Claude Code mode), where I prompted Claude Opus 5.5 Max with:</p>\n<blockquote>\n<p><code>Build a three js game called \"Tree appreciator\" - it shows you two algorithmically generated trees and the game mechanics is about appreciating the differences between them. Think hard about how to make sure it is both fun and beautiful.</code></p>\n</blockquote>\n<p>Somewhat embarrassingly given <a href=\"https://simonwillison.net/2026/Sep/27/2026-in-llms-so-far/#simon-willison-2026-in-llms.059.webp\">my recent talk</a>, I've found that telling Opus 5.5 \"make sure it is fun\" works uncomfortably well. In this case Claude <a href=\"https://claude.ai/share/ee7de555-f85c-4ff0-96cb-d51ed5e479e9\">crunched for 3 hours and 7 minutes</a> before retuning a cosy little spot-the-difference game with music and animation and achievements that's quite compelling to play.</p>\n<p><img alt=\"Screenshot of a mobile spot-the-difference puzzle game with a dark interface. Header reads \"No. 003 Acer autumnalis ‘Hid…\" with subtitle \"Autumn maple · A country lane in late a…\" and icons for sound, a book, and help. Two nearly identical 3D-rendered scenes are stacked vertically, labeled \"Fig. i\" and \"Fig. ii\", each showing a dark-trunked maple tree with red, orange and pale peach leaves, leaves falling through the air, a golden grassy field with a few small rocks, and hazy hills with pine silhouettes under a pale sky. Two differences are circled in blue in both images: circle \"a\" at the base of the trunk, where Fig. i has a small red mushroom that is missing in Fig. ii, and circle \"b\" in the right side of the canopy, where Fig. i has a patch of green leaves that are red in Fig. ii. The bottom bar shows \"2 of 4\", a reset button, a \"Hint\" button with three filled and two empty dots, and a score of \"1,803\".\" src=\"https://static.simonwillison.net/static/2026-10-14/image_crop_1320x2195_w1320_q0.7.webp\" /></p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/javascript\">javascript</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/claude\">claude</a>, <a href=\"https://simonwillison.net/tags/vibe-coding\">vibe-coding</a>, <a href=\"https://simonwillison.net/tags/three-js\">three-js</a></p>",
"url": "https://simonwillison.net/2026/Oct/14/tree-appreciator/",
"published": "2026-10-14T21:23:01.000Z",
"updated": "2026-10-14T21:23:01.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "javascript",
"term": "javascript",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "claude",
"term": "claude",
"url": null
},
{
"label": "vibe-coding",
"term": "vibe-coding",
"url": null
},
{
"label": "three-js",
"term": "three-js",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/",
"title": "AI is mass decompiling games. That's both awesome and scary.",
"description": "<p><strong><a href=\"https://popcar.bearblog.dev/ai-is-mass-decompiling-games-thats-both-awesome-and-scary/\">AI is mass decompiling games. That's both awesome and scary.</a></strong></p>\nIndie game developer Popcar talks about the recent wave of AI-powered decompilation of existing games, enabling weird mashups between existing games, and producing a boom in game preservation projects to get old games working on new hardware (often in a browser using WebAssembly).</p>\n<p>I like how this piece captures both the positives and the negatives of this new development:</p>\n<blockquote>\n<p>Most people already realized the scary part by now. If AI can decompile games and software, then the entire tech industry is about to explode. Anybody can decompile other software and use it any way they'd like, and nobody can stop them. Companies can steal from competitors. Your paid game or app can be open-sourced against your will. This isn't exclusive to old video games, we can apply this to <em>any</em> software. [...]</p>\n<p>This is also a big win for preservation. Old games can be ported, modified, enhanced, and made much more easily accessible than before. [...[</p>\n<p>With console makers going all in on digital and games becoming entirely unplayable due to servers shutting down, this is <em>fantastic</em> news. We could own software we bought regardless of what the company thinks.</p>\n</blockquote>\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50088534\">Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/computer-history\">computer-history</a>, <a href=\"https://simonwillison.net/tags/game-design\">game-design</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/webassembly\">webassembly</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/ai-ethics\">ai-ethics</a>, <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a></p>",
"url": "https://simonwillison.net/2026/Oct/14/ai-is-mass-decompiling-games/",
"published": "2026-10-14T16:26:53.000Z",
"updated": "2026-10-14T16:26:53.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "computer-history",
"term": "computer-history",
"url": null
},
{
"label": "game-design",
"term": "game-design",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "webassembly",
"term": "webassembly",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "ai-ethics",
"term": "ai-ethics",
"url": null
},
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/",
"title": "Redesigning source control at Anthropic",
"description": "<p><strong><a href=\"https://www.anthropic.com/engineering/redesigning-source-control\">Redesigning source control at Anthropic</a></strong></p>\nInteresting piece from Anthropic describing why and how they built their own custom alternative to Git, based on the dramatic increase in rate of changes to their code after the past six months.</p>\n<blockquote>\n<p>In May 2026, Anthropic averaged around 2,500 code changes merged per day; as of September, we merged over 30,000 per day.</p>\n</blockquote>\n<p>They included a chart showing those changes. I <a href=\"https://claude.ai/share/aefcdd4a-9364-40c1-927a-29bf445894fc\">had Claude modify their chart</a> (<a href=\"https://gist.github.com/simonw/4a16dff066fd9763faf8642f797905be\">code here</a>) to add markers for the public releases of each of their models in 2026:</p>\n<p><img alt=\"Stacked bar chart titled “Changes merged per day”, for the Anthropic monorepo, January–September 2026. Each day’s bar is split into pull requests (blue) and antique change requests (orange), with a black line for the 7-day average. Weekdays start at around 1,000 merges in January and climb slowly to about 3,000 by late May. Antique change requests appear in late May, overtake pull requests in mid-June and have almost fully replaced them by mid-July, when weekdays reach 6,000–8,000. A labelled “Quiet week” at the end of July dips below 1,000 a day. After that, growth turns steep: over 10,000 a day by mid-August, about 17,000 in early September, and a peak of 30,401 on Sep 9. Dotted lines mark Claude model releases: Opus 4.6 (Feb 5), Sonnet 4.6 (Feb 17), Mythos Preview (Apr 7), Opus 4.7 (Apr 16), Opus 4.8 (May 28), Fable 5 and Mythos 5 (Jun 9), Sonnet 5 (Jun 30), Opus 5 (Jul 24, just before the quiet week), and Fable 5.1 and Mythos 5.1 (Sep 1).\" src=\"https://static.simonwillison.net/static/2026/anthropic-merges-per-day.webp\" /></p>\n<p>This shows public release dates, not the date when models became available for Anthropic's internal use. My guess is that the introduction of Fable/Mythos class models is a key factor in the increased coding velocity.</p>\n<p>\"Antique\" is their new code review system. The source control system is called Scion, and sounds to me like a reinvention of centralized source control along the lines of Subversion.</p>\n<p>(<strong>Update</strong>: Anthropic credit Google's <a href=\"https://en.wikipedia.org/wiki/Piper_(source_control_system)\">Piper</a> and Meta's <a href=\"https://sapling-scm.com/\">Sapling</a> as \"prior art\" - it looks like the core concept of \"derived data\" <a href=\"https://sunshowers.io/posts/anthropic-mononoke/\">was heavily inspired by Mononoke</a>, the server component of Sapling.)</p>\n<p>They had some pretty extreme requirements:</p>\n<blockquote>\n<p>The history of our main branch alone is almost 100 GB, and a <em>compressed</em> working copy is over 25 GB. We perform on the order of 25 million code checkouts per day for CI, before counting developer environments, agent sandboxes, and research jobs. Fetched naively, that would be over 600 PB of git traffic per day.</p>\n</blockquote>\n<p>The new system was built by a team of seven people, and the migration from Git was completed in five months.</p>\n<p>When asked on Hacker News about the lack of offline support, Scion engineer Nick G <a href=\"https://news.ycombinator.com/item?id=50073633#50079495\">replied</a>:</p>\n<blockquote>\n<p>Since Claude is by far the heaviest user of Scion and is necessarily online, this just wasn't important to do.</p>\n</blockquote>\n<p>As an aside, I've been trying adversarial review in my own projects recently, where you have a model try and find flaws (I often play Claude and GPT off against each other). This note from the article reflected my own experience with that:</p>\n<blockquote>\n<p>Anthropic also makes extensive use of adversarial review, and, while this is incredibly effective in many ways, it can also be myopic, so skilled engineers needed to steer Claude away from over-engineering parts of the system in response to hypothetical concerns.</p>\n</blockquote>\n\n <p><small></small>Via <a href=\"https://news.ycombinator.com/item?id=50073633\">Hacker News</a></small></p>\n\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/git\">git</a>, <a href=\"https://simonwillison.net/tags/migrations\">migrations</a>, <a href=\"https://simonwillison.net/tags/version-control\">version-control</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/anthropic\">anthropic</a>, <a href=\"https://simonwillison.net/tags/agentic-engineering\">agentic-engineering</a></p>",
"url": "https://simonwillison.net/2026/Oct/13/redesigning-source-control-at-anthropic/",
"published": "2026-10-13T23:00:06.000Z",
"updated": "2026-10-13T23:00:06.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "git",
"term": "git",
"url": null
},
{
"label": "migrations",
"term": "migrations",
"url": null
},
{
"label": "version-control",
"term": "version-control",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "anthropic",
"term": "anthropic",
"url": null
},
{
"label": "agentic-engineering",
"term": "agentic-engineering",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/13/llm-gemini/",
"title": "llm-gemini 0.35",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/llm-gemini/releases/tag/0.35\">llm-gemini 0.35</a></p>\n <p>I added support to <a href=\"https://github.com/simonw/llm-gemini\">llm-gemini</a> for the <a href=\"https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/\">new Gemini 4 Argon</a> model, made available today via the Gemini API and for customers of their $100/month subscription plan.</p>\n<p>Here are <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2Fd741e4420dea14c460f0108ac22dbc26\">the low, medium and high pelicans</a>. As expected, they are all excellent: Gemini has a track record of producing great SVGs, and are the only lab where I know their <a href=\"https://twitter.com/sunjiao123sun_/status/2024555516551372920\">staff have invested in SVG specifically</a> (and who have <a href=\"https://simonwillison.net/2026/Feb/19/gemini-31-pro/#jeff-dean\">boasted about their pelicans</a> before.)</p>\n<p>Here's the \"high\" illustration, which cost me 17.166 cents:</p>\n<p><img alt=\"Stylish, accurate bicycle frame. Fish in the basket. Snazzy scarf. Feet on either side of the frame touching the pedals. Spokes, a little hat, a good beak and pouch, a somewhat fierce expression.\" src=\"https://static.simonwillison.net/static/2026/gemini-4-argon-high.webp\" /></p>\n<p>The pricing is interesting. At launch, Argon is $2/million input and $10/million output - the same price as GPT-6 Sol, half the price of Claude Opus 5.5 and 1/5th the price of Claude Fable 5.1 and GPT-6 Astra.</p>\n<p>But on December 1st Argon is set to double in price - so it will be the same price as Opus 5.5.</p>\n<p>Prices like this aren't really comparable these days since what really matters is how many tokens a model takes to achieve a goal within an agentic harness.</p>\n<p>One useful clue for that comes from Artificial Analysis, who publish <a href=\"https://artificialanalysis.ai/#total-cost-tabs\">the total cost to run their benchmark</a> using each model. Argon is looking very good there - costing $2,407 to run the benchmark, putting it close to GLM-5.3 and significantly cheaper than OpenAI, Anthropic, and Meta's latest models.</p>\n<p>When the price doubles it will still be a little cheaper than GPT-6 Astra.</p>\n<p><img alt=\"Screenshot of a stacked bar chart from Artificial Analysis comparing dollar costs for 14 AI models, sorted from lowest to highest, with bars colored by provider, the provider's logo beneath each bar and angled model names along the bottom. Logo at top right: Artificial Analysis. A hover tooltip pointing at the Gemini 4 Argon bar reads: Gemini 4 Argon (High), $2,407, Output $313, Reasoning $815, Cache Write $897, Cache Read $264, Non-Cache Input $118, Click for more info. Bars from left to right, with the total above each bar and some segment values printed inside: Qwen3.8 27B (xhigh), $1,336, Alibaba logo; Mistral Large 4 Preview, $1,607, Mistral logo; Gemini 3.8 Flash (high), $1,623, Google logo; Muse Spark 1.3 (max), $2,000, segment $769, Meta logo; Gemini 4 Argon (high), $2,407, segments $815 and $897, Google logo; GLM-5.3 (max), $2,503, segment $790, Z.ai logo; Kimi K3 (max), $3,658, Kimi logo; Qwen3.8 Max (0902), $4,935, segments $893 and $1,441, Alibaba logo; Grok 4.7 (xhigh), $4,967, segments $1,861 and $1,618, xAI logo; GPT-6 Astra (max), $5,324, segments $778 and $978, OpenAI logo; Muse Wonder (max), $5,733, segment $1,748, Meta logo; Claude Sonnet 5.5 (max with fallback), $7,260, segments $1,216 and $1,815, Anthropic logo; Claude Opus 5.5 (max with fallback), $8,708, segment $921, Anthropic logo; Claude Fable 5.1 (max with fallback), $13,129, segment $7,219, Anthropic logo.\" src=\"https://static.simonwillison.net/static/2026/gemini-4-argon-artificial-analysis.webp\" /></p>\n<p><small>(I <a href=\"https://chatgpt.com/share/6acebe13-5378-83e8-bf2f-9f4d05b206f4\">used ChatGPT to edit that chart</a>! The data is all correct, I checked - I needed to get that Gemini 4 Argon info box to display without overlapping the other numbers.)</small></p>\n<p>Some bonus examples using Gemini 4 Argon: here's <a href=\"https://tools.simonwillison.net/markdown-svg-renderer?url=https%3A%2F%2Fgist.github.com%2Fsimonw%2F9589ff9e0c977bbf3b012b7a11f5bd71\">Generate an SVG of an armadillo in fishnet tights jaywalking on Mars</a>, here's <a href=\"https://tools.simonwillison.net/blender-viewer?url=https%3A%2F%2Fstatic.simonwillison.net%2Fstatic%2Fcors-allow%2F2026%2Fgemini-4-astra-egg.blend\">a Fabergé egg</a> it created for me using Blender, and DeepMind staffer @fofrAI shared <a href=\"https://twitter.com/fofrai/status/2110043023954284889\">a video of a pelican riding a bike, using fourier epicycles</a>. That's a fun new twist!</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/google\">google</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a>, <a href=\"https://simonwillison.net/tags/llm\">llm</a>, <a href=\"https://simonwillison.net/tags/gemini\">gemini</a>, <a href=\"https://simonwillison.net/tags/llm-pricing\">llm-pricing</a>, <a href=\"https://simonwillison.net/tags/pelican-riding-a-bicycle\">pelican-riding-a-bicycle</a>, <a href=\"https://simonwillison.net/tags/llm-release\">llm-release</a></p>",
"url": "https://simonwillison.net/2026/Oct/13/llm-gemini/",
"published": "2026-10-13T22:28:54.000Z",
"updated": "2026-10-13T22:28:54.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "google",
"term": "google",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
},
{
"label": "llm",
"term": "llm",
"url": null
},
{
"label": "gemini",
"term": "gemini",
"url": null
},
{
"label": "llm-pricing",
"term": "llm-pricing",
"url": null
},
{
"label": "pelican-riding-a-bicycle",
"term": "pelican-riding-a-bicycle",
"url": null
},
{
"label": "llm-release",
"term": "llm-release",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/13/geoffrey-huntley/",
"title": "Quoting Geoffrey Huntley",
"description": "<blockquote cite=\"https://ghuntley.com/agency/\"><p>If the agent isn't using my diagnostics library, I could introspect and update AGENTS.md, but there's still a delta, and it'll drift. Instead, I write a pre-commit hook that checks the git diff for direct calls to observability modules that bypass my diagnostics module. Boom: fail the commit, inject a prompt telling the agent to use the diagnostics library. All of a sudden it's ten out of ten.</p></blockquote>\n<p class=\"cite\">— <a href=\"https://ghuntley.com/agency/\">Geoffrey Huntley</a>, nobody should type code by hand anymore. here's what's left.</p>\n\n <p>Tags: <a href=\"https://simonwillison.net/tags/coding-agents\">coding-agents</a>, <a href=\"https://simonwillison.net/tags/generative-ai\">generative-ai</a>, <a href=\"https://simonwillison.net/tags/git\">git</a>, <a href=\"https://simonwillison.net/tags/agentic-engineering\">agentic-engineering</a>, <a href=\"https://simonwillison.net/tags/ai\">ai</a>, <a href=\"https://simonwillison.net/tags/geoffrey-huntley\">geoffrey-huntley</a>, <a href=\"https://simonwillison.net/tags/llms\">llms</a></p>",
"url": "https://simonwillison.net/2026/Oct/13/geoffrey-huntley/",
"published": "2026-10-13T13:32:00.000Z",
"updated": "2026-10-13T13:32:00.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "coding-agents",
"term": "coding-agents",
"url": null
},
{
"label": "generative-ai",
"term": "generative-ai",
"url": null
},
{
"label": "git",
"term": "git",
"url": null
},
{
"label": "agentic-engineering",
"term": "agentic-engineering",
"url": null
},
{
"label": "ai",
"term": "ai",
"url": null
},
{
"label": "geoffrey-huntley",
"term": "geoffrey-huntley",
"url": null
},
{
"label": "llms",
"term": "llms",
"url": null
}
]
},
{
"id": "https://simonwillison.net/2026/Oct/13/web-edit/",
"title": "web-edit 0.1a1",
"description": "<p><strong>Release:</strong> <a href=\"https://github.com/simonw/web-edit/releases/tag/0.1a1\">web-edit 0.1a1</a></p>\n <p>Includes <a href=\"https://github.com/simonw/web-edit/pull/1\">performance optimizations</a> written <a href=\"https://claude.ai/code/session_01LE2R4P74P9GGUbE6yQ5YBt\">by Claude Opus 5.5</a> after I fed it <a href=\"https://simonwillison.net/2026/Oct/12/python-3-15-web-edit-profiling/\">this Python 3.15 profiling report</a> generated by GPT-6 Astra.</p>\n \n \n <p>Tags: <a href=\"https://simonwillison.net/tags/profiling\">profiling</a>, <a href=\"https://simonwillison.net/tags/projects\">projects</a></p>",
"url": "https://simonwillison.net/2026/Oct/13/web-edit/",
"published": "2026-10-13T01:40:05.000Z",
"updated": "2026-10-13T01:40:05.000Z",
"content": null,
"image": null,
"media": [],
"authors": [
{
"name": "Simon Willison",
"email": null,
"url": null
}
],
"categories": [
{
"label": "profiling",
"term": "profiling",
"url": null
},
{
"label": "projects",
"term": "projects",
"url": null
}
]
}
]
}