12 KiB
Side Cards
Original playing-card artwork for The Grind, generated locally with Draw Things and assembled into dependency-free game assets.
Current workflow
This project deliberately uses a simple hybrid format:
- J/Q/K illustrations are matching PNG artwork generated by Draw Things.
- A-10, indices and suit marks are deterministic SVG geometry.
- Each finished court card is a standalone SVG with its PNG illustration embedded inside it. It scales normally in the game without hand-tracing the figure.
Generate the nine non-Heart courts, then assemble the full deck:
./tools/.venv/bin/python tools/render_court.py --remaining
./tools/.venv/bin/python tools/build_deck.py
./tools/.venv/bin/python tools/audit_deck.py
Open gallery.html to inspect all 52 cards and the card back. The temporary game at
../index.html also uses these local exports; it no longer fetches Wikimedia
assets.
Folders
concepts/— calibration sheet and approved Hearts studiesart/courts/raw/— locally generated court illustrationsexports/cards/— finished standalone SVG cards and card backexports/art/— cleaned raster artwork embedded by the SVG exportsassets/fonts/— Roboto Slab source font and its Apache-2.0 licensemasters/— an archived vector-figure experiment; not the deck pipeline
Final deck files
The authoritative finished deck is the 53 standalone SVG files in
exports/cards/: 52 faces plus back.svg. Each file is self-contained; the
court and back raster artwork is embedded as a data URI. exports/manifest.json
is the machine-readable file list, and gallery.html is only the visual review
page. Files in exports/art/, concepts/, art/courts/raw/, and masters/
are sources or build intermediates, not files to ship as the deck.
Run tools/build_deck.py once after any design change. It deterministically
rebuilds all 53 final SVGs together, including removal of detached court-art
pixel islands. A printer-specific PDF or raster package still requires the
printer's requested size, bleed, colour profile, and resolution.
The generated court figures are final game artwork. Roboto Slab rank indices are converted to vector paths; suit marks, number-card layouts and assembly remain deterministic.
House style specification: masters/STYLE.md.
Third-party notices for the vendored protocol files and the model checkpoint:
tools/proto/LICENSE-NOTICE.md.
The provenance sidecars and license notice are quiet background records; they are not part of the day-to-day art workflow.
Calibration v1
concepts/calibration-v1.png
- SHA-256:
ff8a176c188c647532cd57df5c953f78af44e33c90ca2a536470b52dc02e780f - Generator: OpenAI built-in image generation
- Reference images supplied to generator: none
- Status: concept only, not a production asset
Prompt
Design a cohesive original Anglo-American-style playing card system with the clarity and familiarity of a premium traditional casino deck, but with entirely new court characters, poses, faces, garments, ornament, linework, suit symbols, and card back. Show the Jack, Queen, and King of Hearts; Ace and Ten of Spades; one Joker; and two alternate card backs. Use crisp flat vector-like illustration, precise black keylines, a restrained red, black, golden-yellow, and muted-blue palette, white card stock, mirrored court composition, and conventional corner indices. No trademarks, logos, brand names, recognizable branded artwork, photorealism, or watermarks.
Evaluation
- Court figures form a coherent family and remain legible at reduced size.
- Both back concepts are usable directions; the navy back has stronger contrast.
- The ten has the correct number of central pips.
- Several rotated indices are malformed. Production indices must therefore be vector typography, never baked into generated artwork.
- Court detail should be reduced slightly before final vector reconstruction.
DrawThings court study v1
concepts/dt-court-qh-v1.png
- SHA-256:
e53fd536a35f45f97c431a76e2a61af39262faf5bfecd56cc2ebf0aaab7cb073 - Generator: local Draw Things server,
qwen_image_2512_bf16_i8x.ckpt - Settings: 640x896, 30 steps, DPMPP2MTrailing, guidance 4.0, seed 7
- Reference images supplied to generator: none
- Status: concept only, not a production asset
Generated locally via tools/dt_client.py — no metered image API. This exists to
confirm the house style is reachable without OpenAI image generation.
Evaluation
- Palette, keyline weight, and flat vector-like rendering match the calibration sheet's direction closely enough to serve as the ongoing concept source.
- Mirrored two-way court composition resolved correctly.
- Carries no indices or text by design, which suits the production rule above: suit symbols and indices are vector work, never generated.
- Cost is wall-clock, not money: ~7 minutes per 640x896 card at 30 steps.
DrawThings court study v2 (img2img)
concepts/dt-court-qh-v2.png
- SHA-256:
455436aca85380a9f5e2a0c4fe5b1577249aa5d7835e1c01ea205825f680072e - Generator: local Draw Things server,
qwen_image_2512_bf16_i8x.ckpt - Settings: 640x896, 30 steps, DPMPP2MTrailing, guidance 4.0, seed 88, img2img strength 0.68
- Reference image: the Queen of Hearts crop from
calibration-v1.png, with the two corner index strips painted white before encoding - Model SHA-256:
b60a1430040108f8808ef20b47196b09526b1394f7438feeba5538bb89248354 - Draw Things:
1.20260716.0 - Status: concept only, not a production asset
v2 predates the provenance sidecars, so its prompts are recorded here in full.
Original playing card court figure illustration, a queen wearing an ornate golden crown, crisp flat vector-like illustration, precise black keylines, restrained palette of red, black, golden-yellow and muted blue on white card stock, mirrored two-way composition, ornate patterned robes, holding a stylized flower, thin black double-line border frame, completely empty plain white corners, plain white background
Negative prompt:
corner index, corner marking, letter Q, rank letter, suit index, heart symbol in corner, pip, text, letters, numbers, typography, watermark, signature, logo, photorealistic, photograph, 3d render, soft gradient shading, blurry, noisy, drop shadow, heavy solid black
How this was reached
Four rounds of text-only prompting locked the style but oscillated on layout: each composition fix over-corrected the previous one.
- Asking for a "premium traditional casino deck" reintroduced corner indices.
- "Generous white margin" shrank the figure until it floated in white.
- "Classic diamond lozenge silhouette" was drawn as a literal rhombus outline.
- "Robes flare to the card edges" pushed the robes outside the border frame.
Pinning the composition with img2img off the mockup solved this in one pass. Style, palette, and keyline weight were already matched by round 2.
Evaluation
- Composition, palette, and figure now track
calibration-v1.pngclosely, with cleaner and more consistent linework than the original sheet. - Strength 0.55-0.72 preserves composition; 0.85 drifts and garbles the index.
- Open issue: the model re-draws a corner suit pip even when the reference corners are blanked and pips are negative-prompted — it infers them from the card context. In this render the pip lands inside the border frame, so it cannot be removed by cropping to the panel. Removing it needs inpainting or a mask, or the vector stage must cover that region.
Court family test v3 (J/Q/K of Hearts)
concepts/dt-court-jh-v3.png, dt-court-qh-v3.png, dt-court-kh-v3.png
Each PNG has a JSON sidecar recording both prompts, the checkpoint SHA-256, the
Draw Things build, the reference hash, all sampler settings and the client
revision. Regenerate with tools/render_court.py JH QH KH.
- Model:
qwen_image_2512_bf16_i8x.ckptSHA-256b60a1430040108f8808ef20b47196b09526b1394f7438feeba5538bb89248354 - Draw Things:
1.20260716.0 - Settings: 640x896, 30 steps, DPMPP2MTrailing, guidance 4.0, seed 88, img2img strength 0.68, seed_mode ScaleAlike
- Reference: each card's cell from
calibration-v1.png(cells measured by background-gutter detection: all four are 329x460, ratio 0.715), resized to 640x896 with the two corner index strips painted white - Status: approved Heart court artwork used by
tools/build_deck.py
Evaluation
- The three cards read as a coherent family: consistent linework, palette, keyline weight and mirrored composition. The King's beard, crown and sword resolved without trouble.
- Rank letters are absent, as intended;
build_deck.pyadds them reliably. - The generated Heart marks are correct and align with the SVG suit overlay.
- Generated frame segments are locally inpainted out during assembly. One continuous SVG inner frame is then drawn behind the figure, giving the court the intentional traditional frame-break effect. The approved upper figure supplies both ends of the card by exact 180-degree rotation; a symmetric blended join avoids mismatched lower art.
- The temporary game has been verified at 110×154. No smallest production size has been chosen, so this does not constrain the master artwork.
The house style specification derived from this test lives in
masters/STYLE.md.
Archived vector experiment — Queen of Hearts
masters/queen-hearts.svg
This was an experiment in hand-authoring the generated figure as SVG. It is not
used by build_deck.py; the practical deck keeps court illustrations as raster
art inside standalone SVG cards.
Editable groups: frame, indices, veil, garments, ornament, props,
hair-back, face, hair-front, crown, keylines. All colour lives in one
stylesheet block at the top; the rank glyph is drawn geometrically so it needs
no font at render time.
Status: structurally correct, artistically unfinished. The mirror, clip, frame, indices, seam, palette and group organisation are all verified working. The figure drawing is a schematic — the face is doll-like, the hair reads as flat slabs, the robe silhouette is a lens rather than cloth, and the ornament is far sparser than the concepts. It is a sound skeleton to refine, not a finished master.
Size behaviour
tools/size_test.py ../masters/queen-hearts.svg at 110/220/440/1050:
| 110px | 220px | 440px | 1050px |
|---|---|---|---|
| 0.189 | 0.119 | 0.053 | 0.022 |
It reads cleanly at all four sizes, so a single universal master works — but only because the art is currently sparse. Re-run this once real detail is added, since that is when the small-size question actually bites.
Generation toolchain
tools/ holds a local Draw Things gRPC client. Run tools/setup.sh once, then
drive it through tools/dt_client.py.
Notes that are not obvious from the Draw Things docs and cost real time to work
out — see also the proto/ copies vendored from drawthingsai/draw-things-community:
- The app's API server speaks TLS on port 7859 and serves only a self-signed
leaf (
CN=localhost, issuer "Draw Things Root CA"). The client pins that leaf. ImageGenerationRequest.configurationis a FlatBuffers blob (proto/config.fbs), not protobuf. Fields are written by slot index in declaration order; deprecated fields still consume their slot.start_width/start_heightare in units of 64px, so 640x896 is 10x14.- Returned images are not PNG. They are s4nnc tensors: a 68-byte ccv header
(
CCV_16F, NHWC, dims) followed by an fpzip stream, with pixel values in [-1, 1].dt_client.decode_pnghandles this.