Screenshot of actualplaydb.com

What I learned from building actualplaydb.com

This entry is part 23 of 23 in the series Artificial Intelligence

I spent the weekend chasing a rabbit down a hole. I built an IMDB for actual playsmostly from my phone.

The thought process went something like this: Aabriya Iyengar has been in a bunch of live TTRPG actual plays, both the mainstream kind (Dimension 20, Critical Role, The Adventure Zone, Dungeons & Dragons official) and weird little indie things like this Monsterhearts campaign I stumbled onto on an indie channel that I’d never heard of in which she was a guest player for a couple episodes before her name actually changed to Iyengar and she’s not actually credited anywhere on the show’s pages but I’m 100% sure I did not hallucinate her and her character.

I wondered what other stuff has she been in that I don’t know about? Not necessarily because I’m particularly interested in her as a player or GM (I mean, I kinda am, but that wasn’t the main thought process) but more in the sense of, what other games are out there that I have no way of knowing about that might overlap with stuff I’m actively interested in (because there are actors/players that I’ve seen before and like to watch performing)? Surely there’s a database for this somewhere, right? And, also, there was a period of like a year during which it seemed like she was everywhere — it was right as she was making her jump into the official D&D stuff and CR and it seemed like she would be a good case study for precisely the type of thing I was looking for.

It turns out no, actually. ActualPlay.world is that for shows and APs but, crucially, not for performers in those APs. There’s no IMDB for actual plays (although, some of the top tier APs do actually show up in IMDB (like CelebriD&D and Critical Role), but it’s spotty and inconsistent). And that’s what I wanted: a way to cross reference what shows people appeared on and give a credits list like IMDB would.

Of course, I fed this concept to Claude Code to see if I could possibly build this thing in a way that would make community contributions somewhat easy to submit.

The catch? About 90% of the build was from my phone talking to Claude Code working on my laptop.

This wasn’t really an intentional choice, more of a way to keep the build happening and check up on running processes while I wasn’t at my machine. But over time, it was so convenient to work through the normal, boring Claude interactions to keep it on task and review its logic that not actually seeing what it was building wasn’t really a blocker as long as I felt like I had a good idea of what it was doing.

This is the first time I’ve really spent time building something from my phone. I have used my phone via Dispatch or regular Chat to communicate with Claude in other ongoing conversations. When doing Claude Code operations, specifically, you kinda have to just trust that the LLM is doing what’s best for the project because, unlike if you’re using it in a CLI and you’ve got a browser you can pop open, or even if you’re using Claude Desktop and can use the internal browser to preview the local build, there’s nothing like that when you’re talking to Claude Code on your phone to see the result of the work.

When people talk about how LLMs make natural language the programming language and the LLM itself the compiler, this is what they’re talking about.

Obviously (or maybe not so obviously?), I couldn’t do 100% of this from my phone. At some point I needed to actually see what it built and give feedback on the product. But surprisingly, I was able to get most of the way there and fill it with data that was mostly valid before I ever saw what it looked like. In fact, it was a fully functional prototype before I opened it on my computer to check it and before a GitHub repository ever existed. It’s actually kind of wild how this build came together without really even using my computer.

When people talk about how LLMs make natural language the programming language and the LLM itself the compiler, this is what they’re talking about. I was concerned about the architecture of the project, but I didn’t have opinions about implementation. I knew I wanted this to be community-contributable, which meant using a language that was easily parseable by humans. My first thought was using JSON files for the data layer, but Claude suggested YAML which I decided was a better solution because YAML allows for inline comments while JSON does not, and it’s a little easier to read. After that, it was just a matter of telling Claude to build the thing.

To start, I used Claude to do the initial research about whether the thing I was looking for existed before I came to the conclusion that this was essentially greenfield, there’s nothing in the space. When it became clear that I wanted something that didn’t exist and wanted to build that thing, I asked Claude to take everything we discussed about the intent and write up a prompt that I could copy over to Claude Code to build the thing, with a few points in there about where the hosting might land, giving it a choice of GitHub Pages for the platform or Next.js on Pantheon and letting it suggest which would fit the build more appropriately (ultimately, I settled on GitHub Pages).

I used Opus 5 for the entirety. This may have been a mistake. I’ve been using Opus at work but I’ve really not ever noticed a difference between Opus and Sonnet…maybe a minor improvement. In this case, Claude was churning through tokens and grinding its wheels on things I didn’t ask it for, hyper-optimizing discovery scripts rather than doing web searches to manually validate data.

Claude built a bunch of adapters for importing data from various sources, which was helpful for standardizing that data import. But really, once the data is imported, those adapters are kind of pointless.

The biggest point of frustration was wanting it to just run to completion but it kept stopping to check in…even as it said “Continuing”. Which was wild because it was like “uh…no, you actually aren’t…”. I haven’t played a lot with the different modes of Claude, but I’ve started using Auto mode when I don’t want to have to approve every tool request or action. Given a lot of the work I’ve been doing lately is around workflows to keep Claude on the rails (see my Claude Code review and the talk I’ll be giving at WCUS in a couple weeks), the challenge I need to set for myself (and Claude) is to integrate those systems and put the optimization there, so I don’t have to babysit the LLM. It seemed like part of its programming is that it needs to stop and check in, even when you have it set to Auto mode, which was annoying when I wanted to be more hands-off while I was doing stuff throughout the day on my weekend and when there was a very clear task list I just wanted it to go through. More than once, when I asked it to validate information it had collected, it decided to build an adapter with complex regex rather than just doing a web search. Again, I don’t know if this is a product of the model or the mode (Claude Code specifically), but either way, the token consumption and usage for Opus is higher than Sonnet, so those tasks would have potentially been significantly cheaper had I not been using the “better” model.

Besides building an online database via a chat window on my phone, the thing I’m most impressed by in the result is the speed. I knew using flat files for data and a speedy JavaScript framework was a good combination — I used precisely that model for a DevRel Dashboard I built as an internal tool. But this site rips. It’s so fast. And it really makes a strong case for dropping everything and only making websites with flat files that serve data from now on. (I won’t…but I’m thinking about it.)

Contribution can be made by either opening an issue (clicking “Suggest a Correction” on any page, or using the Submit link) and using the appropriate GitHub issue template, or else clicking the “Edit this…” button on any page and opening a PR on the raw YAML file for whatever entity type you’re editing. I encourage you to check out the site and submit suggestions or corrections to any messy data you might see (and add new stuff that I’m missing, which I’m sure will be a lot!).

In the end: Claude Code from your phone and using natural language to build apps is really a wow feature to try, static sites are the way to go whenever possible (this is not news, I know…), but using the most expensive model is maybe not the thing you should do, especially when, as of this writing Sonnet 5 is supposed to be close to what Opus 4 was — the model you’re using today will always be the worst model there’s ever been because the changes are coming so rapidly that improvements are constantly being made (it’s also the best it’s ever been), and it’s good to keep that in mind when considering which to use. (I still haven’t really tried Fable and kind of don’t want to for precisely this reason.)

Artificial Intelligence

The CMS is dead. Long live the CMS.

Published on

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.