Play free

How Bootleg City was built

Behind the scenes · November 2026

Bootleg City is a multiplayer game with sign-in, saved progress, live chat and its own website. It runs without a game server, a database server or any infrastructure of our own. It's one HTML file and a handful of Tessryx workflows. It was built over a few days by Claude, Anthropic's AI, working inside a Tessryx workspace through the Tessryx connector, with a person describing what they wanted and playtesting along the way.

The whole game is one file

The game is a single page of about 100 KB, or 35 KB compressed. It has no game engine, no libraries and no image or sound files. The city, the cars, the people and the speech bubbles are drawn in code on an HTML canvas. The engine noise, the gunshots, the Ah-ooga horn and the jazz on the radio are synthesized live with the Web Audio API. That's why it loads in a blink on a phone.

The page is stored inside a Tessryx workflow and served from an endpoint at /play, cached at the edge like any static page.

Multiplayer without a game server

Online games usually need a server that holds a connection open to every player. Bootleg City uses something much simpler:

  1. About once a second, your game sends a small snapshot of you: where you are, which way you're facing, your car, your health, shots you've fired.
  2. A workflow saves that snapshot as a datafile and sends back everyone else seen in the last 20 seconds.
  3. Your game smooths the other players between updates, so they glide rather than jump.

Hits work the same way: a shooter's snapshot includes who they hit, and the victim's game applies the damage. Players who leave are cleaned up automatically after 10 minutes. When you're alone in the city, the game checks in every four seconds instead of every second.

Sign-in without handling a single password

The game's API endpoints are gated by Tessryx sign-in, so the game never sees passwords or email addresses. Each endpoint passes the workflow an anonymous player ID that Tessryx has already verified:

"input_transform": "{ \"vid\": auth.viewer_id, \"s\": body.s }",
"auth": { "required": true, "on_unauthenticated": { "mode": "refuse" } }

Because the server always knows who's calling, nobody can pretend to be someone else. Your name and stats come from your saved profile, not from what your browser claims. Names are claimed by creating a datafile named after the name itself. Creating one that already exists fails, so two players can never end up with the same name, even if they press the button at the same moment.

Keeping it clean

Every new gangster name and every chat message is checked by TypeSafe's Jev model before anyone else sees it. Jev looks for hate, vulgarity, threats, impersonation, and phone numbers or social handles. Chat is rate-limited before it reaches Jev: one message every two seconds, five a minute, and a daily cap. That way a spammer can't run up the bill. If the screening service can't be reached, the message isn't sent. It never slips through unchecked.

The API key for TypeSafe is stored as a Tessryx secret. Workflows can use it, but nobody can read it back out, including Claude, which built them.

The website is workflows too

The page you're reading, the home page, the privacy policy, the terms, the sitemap and robots.txt are all rendered by one more workflow, with search-engine markup built in. The social share card was drawn as vector art and turned into an image by another workflow. The domain is a Tessryx custom domain: two DNS records, and it was live.

By the numbers

Game page1 file · ~100 KB · no dependencies
Workflows7: game page, sync, profile, name check, chat, website, share card
Endpoints11, all served on bootlegcity.app
Servers we run0
Time to buildA few days, including playtesting fixes for traffic jams and police cars that pinned you against walls

Want to build something like this? Tessryx gives you pages, APIs, data, sign-in and custom domains in one workspace, and works with AI assistants like Claude.

Build your own on Tessryxor play Bootleg City first →