Files
2026-08-11 09:53:42 -04:00
..
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00
2026-08-11 09:53:42 -04:00

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 studies
  • art/courts/raw/ — locally generated court illustrations
  • exports/cards/ — finished standalone SVG cards and card back
  • exports/art/ — cleaned raster artwork embedded by the SVG exports
  • assets/fonts/ — Roboto Slab source font and its Apache-2.0 license
  • masters/ — 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.png closely, 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.ckpt SHA-256 b60a1430040108f8808ef20b47196b09526b1394f7438feeba5538bb89248354
  • 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.py adds 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.configuration is 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_height are 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_png handles this.