← Back to the blog

Fine Print Devlog: Making "Every Visitor Obeys Exactly" Your Fault, Not Random

· 5 min read · Fine Print

Fine Print is a game about writing the signs for a small, odd town. Every visitor obeys every sign exactly as written. Your job is to get them all home safe.

A run lasts 5 days. Each day you pick 1 of 3 rule cards and put it on 1 of 3 sign posts. You can have at most 3 signs up; a fourth replaces one. Then you open the town and watch. There is a Daily town and an Endless town.

It’s our seventh game. The first six were orbit timing, swipe-to-judge, claw steering, stroke-to-cut, push-or-bank and probe-and-decode. This one is new again: you write the rules, then you watch. The main risk is that players can’t read the rules. If they can’t, they can’t blame themselves, and the whole joke falls apart.

Title screen of Fine Print: a street sign with the game name, the line “You write the signs. Every visitor obeys them exactly. Get everyone home safe.” and buttons for Daily town, Endless town, How to play and Settings.

The title screen. The signs, the town and the sounds are all made in code: there are no image files.

Making it your fault, and funny

When a visitor does something dumb, the player should think “oh, I wrote that”, not “that’s random”. That needs the rules to be easy to read. We learned this on Crossed Wires, where a rule in room 4 was not readable on screen. So Fine Print has four things built in from the start:

  • One-line cards with a who-it-affects icon. There are 24 cards, and every one is 40 characters or fewer.
  • Intent arrows before you open the town. You see where each visitor is about to head, so you can change your mind.
  • The simulation pauses on an incident. A caption names the sign that caused it.
  • A QA “cold-rules” release gate. Before reading the design, QA writes down what each card does from the screen alone.

Planning screen on Day 1 in a park town. The card “Visitors in this area meet here for 3 s” is selected, dashed areas surround the three sign posts, and a hint reads “A sign only works inside its post’s dashed area.”

The planning screen. The dashed areas and the hint line came out of the cold read, which we get to below.

The pause is the part we like best. The sim stops on the incident, a ring marks who it happened to, the post that caused it lights up, and the caption spells out the chain.

The day paused on an incident: a red ring marks a dog on a bridge, post 1 is highlighted, and the caption reads “A kid followed the dog → ‘Kids follow the nearest dog’ → got soaked”.

An incident. The caption names the sign behind it, so the next move is yours to make.

Searching every Daily in full

The game has 3 places, 6 visitor types and those 24 cards. The simulation is pure integer ticks, which let us do something stronger than bot testing. levelcheck, our test script, searches every Daily in full: 3^10 = 59,049 paths per date, across 1157 dates.

What came out of it:

  • Every date has an all-home path.
  • Best play beats random play by about 1.2x (median 1.20 and 1.21 on the two seed sets).
  • No card shows up in more than 40% of the best runs, and every card shows up in at least one. The highest share we saw was 36.4% on one seed set and 39.6% on the other.

The card-share limit caught something. One of our original cards, a crossing-closed rule, turned up in 49-61% of the best runs. We replaced it with “No kids or dogs on bridges or gangways”, and the gates passed. A full levelcheck takes about 5 to 9 minutes on 15 workers. Along the way we lost one round of balance work when a scratch folder was deleted, and redid it.

What the cold read caught

Searching shows the numbers hold. It can’t show whether a person can read the cards. For that we added the cold-rules gate: before reading the design, our QA agent writes what each card does from the screen alone, and we compare.

On the first pass, 22 of 24 cards were read exactly right, and every bot had passed. Two problems were still there:

  • Card #17 read as town-wide. It said “Everyone meets at this post for 3 s”, and QA read that as everyone in town. It only affects visitors inside the post’s area.
  • The screen never said a sign only works inside its post’s dashed area. That left it unclear where the sign applies for 21 of 24 cards.

We reworded the card to “Visitors in this area meet here for 3 s” and added a hint line, “A sign only works inside its post’s dashed area.”, that shows when a card is selected. While we were there, we fixed some jam captions that named the wrong visitor, and made captions wrap so the smallest text is 12 px at 360x640. On the re-check, all 6 cards QA looked at were read correctly, with no console errors in 10 runs. One last strings-only fix followed, to make a Korean jam caption and an English “a kid was / kids were” caption read right.

What we haven’t checked

We tested in headless Chromium with mobile touch emulation at 360x640 and 540x960, not on a real phone and not on iOS. Nobody has listened to the audio; the synth sounds were checked in code only. Balance and fairness were judged with bots and exhaustive search. The cold read was done by our QA agent, not by first-time human players, so we don’t yet know what a real newcomer will misread. We also never saw the emoji in the share line rendered, because our test sandbox has no emoji font.

If a card reads wrong to you, tell us.

Play Fine Print and see how well you write a sign.