Smallwood studio notes

Browser work and card-game programs

Vol. 1 · 2026
Public lab notebook

NB-15 · 9 Nov 2026 · Card game

Lab note

Representing card state in a browser game

Playing cards spread on a pale surface, face up.
Fig. 3. A spread of playing cards, used here as a reminder that rank and suit have to live in data, rather than solely on the picture of the card.

A playing card on screen is a picture and a button. A playing card in a program is a record with a rank, a suit, a location, and sometimes a face-up flag. This entry records the record I am using, and a mistake I made when I let the DOM become the only copy of that record.

Each card is a small object: rank as a number (6 to 14, with 11-13 as jack, queen, king and 14 as ace), suit as one of four short strings, id as a stable key such as h14 for the ace of hearts. Location is not stored on the card. The position object owns lists (stock, a hand, the table pairs). Moving a card means taking it out of one list and pushing it onto another. That makes it impossible for the same ace to sit in two hands unless a bug puts it there, in which case a uniqueness check on id after every move will say so.

The first prototype kept the face-up flag only as a CSS class on the node. After a re-render, every card came back face up. The fix was obvious after the fact: the picture is a view of the record. If the record does not say the card is face down, the view will not know. The same rule applies to selection and to "this card was just played." Those are states. They belong next to rank and suit, or in a short list of selected ids, not in the class attribute alone.

For a 36-card Durak deck this all fits in a few kilobytes. There is no reason to be more abstract than a list of records. When a later network mode arrives, the same record is what gets sent, not a bag of DOM nodes.