Since joining the Recurse Center (RC), I’ve been posting about the process, my projects, and what I’m learning. See all the weekly installments or filter for posts with the Recurse tag.


This was not only my most productive week so far, but also my most socially-engaged one.

I had three excellent and energising coffee chats (thanks Evan, Alexa, and Krishna), presented to the whole of Recurse, and had a number of superb group meetups.

Jam-packed: A “claustrophobic” game jam

The theme for the Fall 1 ‘24 Game Jam was “claustrophobia.” I had two ideas percolate up:

  1. A reverse Turing Test game where you’re in some environment with several LLM-driven NPCs that are trying to figure out who’s not an AI. Your job is to try go undetected as they “close in” on you. I’ve been wanting to experiment with this for ages, since I started doing experiments on LLMs interacting (as bots in a Discord server) as part of some Bountyful prototypes. I also saw this video a few months back and was curious if this could make for fun gameplay.
  2. A 2D fluid simulation sailing game where you have to hit just the right angles with your boat and sails in order to navigate the claustrophobic riverways without crashing into the banks or being caught by other boats.

I ended up building the first one early in the week, and polishing it off to present to Recurse for Thursday presentations.

Game 1: AImong Us, a reverse Turing Test where the AI detect YOU!

I whipped up a quick prototype, but gameplay was far from fun. LLMs can be exhaustingly dull and generic by default.

After sharing screenshots of the early version, I got some ideas and suggestions from Krishna about coalitions of AI vs human players that have to try and win some kind of majority without giving themselves up. That prompted me to think more about the game theory and competitive dynamics of the game.

I started with a simplified Werewolf mechanic and having the agents all vote to kill one agent every N messages, after which it’s revealed if the agent was human or machine. That way, there’s a claustrophobic constraint as they close in on the player. This instantly made the game both more fun and more difficult.

I also used the opportunity to try out uv and rich, which have both been great so far! But it’s quite weird going back to Python (my “native language”) after so many weeks of focussing on Rust. I think I miss the compiler.

Screenshot of AImong Us game in the terminal

Game 2: Fluid-Sim Sailor (WIP)

I also made a significant amount of headway on the second game idea when the prompt for Wednesday’s creative coding session was an excerpt from Italo Calvino’s Invisible Cities that contained the following section:

…the white and red wind-socks flapping, the chimneys belching smoke, he thinks of a ship; he knows it is a city, but he thinks of it as a vessel that will take him away from the desert, a windjammer about to cast off, with the breeze already swelling the sails, not yet unfurled…

I based it on this example and the broad strokes of their implementation. I believe that makes it some variant of the Lattice-Boltzmann approach, but I ended up just hacking away at it in ways that probably make it less of a good simulation, but more fun to build and play with.

It’s still not interactive, but it’s fun to watch. The canvas is automatically sized based on the browser window, so it’s interesting how different window sizes or mobile layouts affect the stability of the fluid system.

Yanked back into the AI world

As our study group for Neural Networks: Zero to Hero has progressed, I’ve found myself being lured back into the world of deep learning. Moreover, I’ve been working with a lot of LLM code this past week with AImong Us and some open source code.

But the real vortex opened up when OpenAI finally released “strawberry” just as I was about to sign off on Thursday night. It reminded me of back when I was in the trenches of building Bountyful in 2023, when it felt like there was some seismic shift in the industry every couple of weeks that shook everything to pieces.

I ended up writing so much about this that I spun it out to it’s own essay.

Contributing to open-source

For most of this year, I’ve been using llm as my primary way to interact with LLMs. I pretty much live on the terminal and I find the ability to pipe standard input / output to and from llm just like any other *nix CLI tool to be a force multiplier in my whole workflow.

My only gripe has been the lack of rich text formatting in the terminal. But I recently used rich for a AImong Us and found it excellent, so I was excited to add this to llm.

I found an old PR relating to this that had gone dormant, so I decided to nudge things along with my own contribution that:

  1. fixes a mysterious bug that was failing some tests and
  2. resolves merge conflicts caused by changes since the older PR was proposed.

This week I learned

(Copy-pasted from my #TIL-tagged notes in Obsidian from the past week.)

  • Found a nice solution anyone who wants the simplest and quickest way to have a live reload server:npx live-server . in the directory worked out of the box for me. It’s running live-server but without installing and setting up a project each time by using npx, which should already be installed if you have npm.
  • :set paste puts vim into a mode that prepares it for pasting of content, disabling things that might break formatting such as auto-indenting.
  • Gdiffsplit (which is from git-fugitive?) - #TIL allows for a nice side-by-side git diff in neovim. ]c and [c to move to/from hunks.
  • Rust has todo!() macro and also unimplemented. Also << and >> bit shift operators! Handy!