← Project Management · Visual Information

Case Study

One File That Travels

A 20 Below character is a single file. It moves between the Character Creator, the Battle Tracker and the character sheet in Owlbear Rodeo, and it gets passed around the table. When characters needed pictures, the picture had to travel the same way: inside that one file, shown the same way in every tool, and safe to open whoever made it. It was asked for, built, tested and released in one morning. The study is also honest about the part it didn’t reach.

Role
Producer: the request, the decision and the release ruling.
Team
Claude (AI assistant).
Timeline
One morning, 28 September 2026: asked at 08:11, released at 10:35.
Result
A character’s picture travels inside its file, to the Creator, the Battle Tracker and the Owlbear sheet, released in four tools at once.

The Problem

I was setting up an Owlbear Rodeo room for a portfolio video shoot. The Battle Tracker’s button for putting a character on the map placed nothing, even after a reload. The tokens had to be drawn, uploaded and linked by hand. That bug was logged as its own task instead of being fixed mid-shoot, but it raised a better question. Why doesn’t a character already carry its own picture?

The tracker could already pair an image with a character file when both were picked together, Wolf.json beside Wolf.png. But that means two files picked at once, every time, and the picture reached only the tracker. Nothing in the Creator or the Owlbear sheet knew what a character looked like.

Analysis: Who It’s For

A player

Wants their character to look like someone, wherever it appears.

The GM running a fight

Needs to tell combatants apart at a glance in the tracker.

Anyone sharing files

Wants one file to pass across the table, not a file and a picture that can get separated.

Anyone opening someone else’s file

Needs to trust that a shared file can’t carry anything harmful.

My question at 08:11 was simple: “Is it possible to bundle icons with the JSONs and have the extension load them? … Automatically?” Four options were weighed. Five minutes later, the decision was one sentence: “Build the Portrait field.”

Five ways to put a picture on a character. Pair by name, kept: reaches the Battle Tracker only, and needs two files picked every time. Rebuild a shared file with icons, not taken: only for files the tracker exported. A Portrait field in the character file, chosen: reaches the Creator, the Battle Tracker and the Owlbear sheet, released by 10:35. Host a fixed token set, not taken: map tokens, but only stock art. Found later: offer the portrait to Owlbear's assets through its own import dialog, the better route for map tokens and now the plan for the token fix.
Four options weighed that morning, and a fifth found later, while this study was being written.

Design Decisions

One file carries the character

The portrait lives inside the character file, set once in the Creator on the Name & Concept step or beside the sheet’s heading. Wherever the file goes, the picture goes with it. The Battle Tracker shows it in its Catalog and its encounters from the file alone. Saved encounters and exports carry it too. The Owlbear sheet shows it beside the name. Nobody has to pick a second file.

A test character file carrying its portrait, arriving in three tools: beside the Creator's sheet heading with Change and Remove, in the Battle Tracker's encounter row, and in the Owlbear Character Sheet's header. A dashed card marks Owlbear map tokens as not yet: a token needs its picture as an Owlbear asset, and Owlbear's extension API can offer one through its own import dialog, which is the next step. Until then, upload the portrait once as a Character and use Link.
One file, three places. Map tokens are marked “not yet”, with the route that will get there.

Any picture in, the same portrait out

A player can pick any picture, of any shape. Every place a portrait appears is a circle or a small square, so the Creator keeps the centred square and re-encodes it at 256 by 256 pixels. That’s more than twice the largest size any tool shows it at, so it stays sharp on a high-density screen. One source picture serves every size, from 96 pixels on the Creator’s first step down to 34 in a tracker row. With no portrait, each tool falls back to the character’s initials.

A 900 by 600 test picture with its centred 600 by 600 square outlined. A red band on its left edge falls outside the square. The saved result is a 256 by 256 WebP. The same portrait is shown at each tool's actual size: 96 pixels on the Creator's Name and Concept step, 64 beside the sheet, 44 in the Owlbear sheet header, and 34 in a Battle Tracker row.
A test picture through the Creator’s own crop, shown at each tool’s real size.

A file from the table is untrusted

Character files are made by players and passed around, and each tool puts the portrait straight onto the screen. So one shared check decides what counts as a portrait. It accepts PNG, JPEG, WebP or GIF image data, up to 400 kB. It refuses:

  • SVG, which can carry more than a picture;
  • a link to a picture on someone else’s server;
  • text that only claims to be an image;
  • anything too large.

Anything refused counts as no portrait, and the file still opens. A picture picked in the Creator is re-encoded even when it’s already small, so what the Creator writes is always a plain image and nothing else.

Accepted: PNG, JPEG, WebP or GIF image data, up to 400 kB. Refused and treated as no portrait: SVG as data or plain text, a link to another server, text that isn't image data, anything over 400 kB, and anything that isn't text at all. What happens instead: the Battle Tracker shows generated initials, shown with a real test file whose portrait was an SVG; the Owlbear sheet shows the name without a picture; the Creator shows an empty circle, and picking a file that isn't a picture says: Pick a PNG, JPEG, WebP or GIF picture.
Every accepted and refused row here is a tested result.

What was chosen on purpose still wins

The old pairing wasn’t removed. If a GM picks a picture alongside a character file, that picture is used, because someone chose it deliberately. The portrait inside the file fills in only when nothing else was given.

Say where it stops

Two things were left out, on purpose, and said out loud.

  • Map tokens. A token on Owlbear’s map needs its picture as an Owlbear asset, not an image tucked inside a file. That morning’s answer was that an extension couldn’t get it there. While writing this study, a check of Owlbear’s own extension API showed that it can, through an import dialog the player confirms. That route is now the plan for the token fix. Until it’s built, a portrait becomes a token by uploading it once and linking it in the tracker.
  • The printed character sheet. Its artwork is a designed page, so a portrait on it would need a design change. That wasn’t made without a design ruling.

How the Work Ran

  • About ten minutes from decision to tested. One shared check, the Creator’s crop, and the portrait in all three tools. Then browser tests of the crop, a non-image file, a portrait from the file alone, and a hostile file refused everywhere.
  • Held for review. Screenshots of all three tools went to me first, and nothing was committed until I’d seen them.
  • A bug logged, not chased. The broken token button that started this became its own task instead of widening the feature.
  • Released everywhere at once. The Character Creator v0.12.34, the Battle Tracker v0.3.4 and both Owlbear extensions went out by 10:35, the same morning as the retirement of the Novice tier. That shared release is where two parallel workstreams overlapped, told in The Rung That Made Players Worse.
  • A wrong answer corrected in the open. The claim that map tokens were out of reach was checked against Owlbear’s extension API while this study was being written, and it was wrong. The correction changed the token fix’s plan.
A timeline of 28 September. 07:53: the token button places nothing, and the bug is logged as its own task at 07:57. 08:11: the question, can icons travel with the files and load automatically. 08:16: the decision, build the Portrait field. 08:17: built in three tools. 08:21: tested in the browser. 08:25: held for review. 10:05: go-ahead, commit it, release both and sync them. 10:06: committed and pushed. 10:35: released everywhere, with extensions synced at 10:31. Later: a route for map tokens found while writing this study.
From a broken button to a released feature.

Outcome

A character now carries its own picture. It’s set once in the Creator, framed the same way everywhere, and shown in the Creator, the Battle Tracker and the Owlbear sheet with no second file. A file from the table can’t slip anything but a plain picture onto the screen. The part that isn’t done, map tokens, has a named route and a task behind it.

What this doesn’t show yet is players using it. The next sessions will show whether portraits get set, and whether the GM’s tracker reads faster for them.

Credits

The request, the decision and the release rulingMe, as producer
Options, Package Deliverables, tests and figuresClaude (AI assistant), checked by me