tgame/docs/07-item-cards.md
Parley Hatch 2abfe4abd1 Initial commit: design docs
Working title 'tgame' is provisional. Top-level samples/ and
docs/samples/ are gitignored; visual/art pipeline lives outside
this repo.
2026-05-17 11:16:07 -06:00

8.6 KiB
Raw Permalink Blame History

Item Cards & Visual Composition

Items aren't authored as finished PNGs. They're composed at runtime from a stack of layered sprites driven by the item's actual components, materials, quality, and effects. The player's crafting choices show up visually.

This is the trick that lets the game have functionally infinite visual variety from a finite asset library.

Layer model

Most items render as a card with these layers, bottom to top:

1. Card frame           — quality band (Crude / Common / Fine / Masterwork / Legendary)
2. Background           — effect or material flavor (forge ember, poison mist,
                          holy rays, cursed shadow)
3. Base silhouette      — the item type (longsword, dagger, vial, ring, helmet)
4. Material tint        — primary material (moonsilver sheen, obsidian gleam, bronze)
5. Component overlays   — per-slot: pommel gem, hilt wrap, stopper, label,
                          engraving — driven by the actual components used
6. Effect aura          — enchantment (poison wisp, fire flicker, curse,
                          holy radiance)
7. Quality flourish     — Masterwork particle, Legendary frame glow
8. Stamps / marks       — maker's mark (engineer who crafted it), faction sigil

Each base item sprite defines anchor points for component overlays — pommel anchor, blade anchor, stopper anchor, etc. Components are authored to land on those anchors, so the gem inhabits the pommel rather than floating beside it.

Examples

Lapis-infused Moonsilver Falchion (Fine)

  • Frame: Fine (silver border)
  • Background: faint blue arcane glow
  • Base: falchion silhouette
  • Material tint: moonsilver pale-blue sheen
  • Component overlay: lapis lazuli at pommel anchor
  • Engraving overlay: frost rune
  • Aura: cold mist
  • Stamp: Theodric's maker's mark

Cursed Ruby-binding Black Draught (Masterwork)

  • Frame: Masterwork (gold)
  • Background: deep crimson swirl
  • Base: rounded apothecary vial
  • Material tint: liquid opaque black with red glints
  • Component overlay: bone stopper, red wax seal, ruby fragment in liquid
  • Aura: dark heat-shimmer
  • Flourish: drifting particles
  • Stamp: Theora's apothecary mark

The player sees both items and immediately knows which components went into each. Crafting decisions are visible.

Why this is the right call

  • Asset count collapses. ~30 base silhouettes × ~20 material tints × ~30 component overlays × ~15 effect auras × 5 frames = combinatorial variety from a small authored library.
  • Crafting becomes visually expressive. Every craft choice has visible consequence — the strongest feedback loop possible.
  • Functionally infinite uniques. Even when a recipe is shared, your specific instance has your specific components, engineer stamp, and quality. No one else's is identical.
  • Future bazaar gets richer. Listings show full composed cards, browsing becomes part of the fun.
  • Names compose too. [quality adjective] [material] [base] of [effect noun] gives Diablo-style procgen names from the layer stack itself.

Tradeoffs

  • Consistency burden. Components must be authored to compose cleanly — same perspective, same lighting direction, same scale, same color discipline. Strict style guides + a composition test step before any new component ships.
  • Color clashes. Lapis blue + ruby red on one sword can look muddy. Either gameplay-prevent it via recipe constraints, or lean into it as visual feedback that the craft is unstable.
  • Reserve bespoke art for Legendary or named items. When the player discovers a truly unique recipe — Crucible-Forged Sun-Sword of Aelis — that one gets full hand-finished treatment. Composition for 99%, bespoke for 1%.

Rendering: alpha layers + shader passes

Composition isn't flat sticker-stacking. Every layer carries an alpha channel and lower layers bleed through where higher ones are transparent. Atmosphere layers (swirling shadows, drifting mist, dust motes) sit between solid layers and add depth without hiding the base art.

After the layer stack composes into a single card texture, post-process shaders run on the composed result. Many effects need no PNG asset at all — they're pure fragment shaders.

Pass model

Pass 1 — Layer composite (alpha-aware)
   frame → background gradient → atmosphere overlay (alpha) →
   base silhouette → material tint → component overlays →
   aura layer → flourish particles → stamps
   = composed card RGBA texture

Pass 2 — Effect shaders
   apply post-process shader stack to the composed texture
   (glow / holo / foil / corruption / first-reveal / ...)
   = final card pixels

Pass 3 — UI compositing
   place card in inventory frame, drop shadow, hover state

Pixel art note: the visual style is pixel art with palette-locked dithering (09-art-style.md). Effect shaders on the composed card should pixelate-quantize to the pixel grid when they're large or visible (holo, foil, corruption); subtle glow/bloom can stay smooth because the eye reads it as atmosphere rather than as art.

Effects that need zero assets

Effect Implementation Use case
Outer glow radial blur on alpha mask, colored Magical items
Holographic foil animated UV shimmer, hue rotation over time Rare quality bands
Foil shimmer specular angle-based highlight Legendary frames
Heat haze UV displacement by animated noise Fire / forge effects
Frost crackle overlay noise, hue toward white-blue Frost enchantments
Cursed corruption chromatic aberration + vignette darkening Cursed items
Holy radiance god-rays + bloom Blessed items
First-reveal sweep animated alpha mask wipe on card open "New Discovery!" moment
Faded / locked desaturation + alpha reduction Items beyond your tier

This collapses asset counts even further — atmospheric / textural effects don't need a PNG, they need a shader.

Quality bands become partly shader-driven

  • Crude: no shader pass.
  • Common: no shader pass.
  • Fine: subtle outer glow, colored by primary effect.
  • Masterwork: animated foil shimmer + drifting particles.
  • Legendary: holographic shader + animated frame glow + drifting particles + bespoke art.

Quality is felt instantly through visual treatment, not just stat numbers.

Performance

  • Active card view (focused, large): all shaders + animation enabled.
  • Inventory list (200 thumbnails): drop the shader pass, render Pass 1 only, cache the result. Or render at reduced resolution.
  • Transition: cross-fade from cached static thumbnail → live shader version on tap-to-focus.
  • Animation gating: shaders pause when offscreen — save battery.
  • Mobile GPUs handle this trivially at 12 simultaneous focused cards. Don't try to run the shader stack across 50 cards in a grid.

Engine implications (input, not decision)

Pushes mildly toward an engine with strong custom-shader support.

  • Unity: Shader Graph + URP, well-trodden mobile path.
  • Godot: visual shader editor is solid and free, mobile improving.
  • Flutter: possible via FragmentShader + CustomPainter, rougher for shader-heavy UI.

Data model implication

Every item instance stores a composition recipe, not a baked image:

ItemInstance {
  id: UUID
  base_id: "falchion"
  material_ids: ["moonsilver"]
  component_ids: ["pommel_gem:lapis_lazuli", "hilt_wrap:silver_thread"]
  effect_ids: ["frost_aura"]
  quality: Fine
  maker_id: minion_uuid
}

The renderer reconstructs the card on demand. Save data is tiny. Serialization for future bazaar is trivial — transmit the composition recipe, receiving client reconstructs the card.

UI implications

  • Card view is a first-class UI object, not just an icon.
  • Card flip on craft completion is a key game moment — the reveal is where the dopamine lives. Choreography per quality band designed in 13-reveal-choreography.md.
  • Inventory, market, share screenshots, patron orders all reuse the same card renderer.
  • Tooltips can be lighter because the card itself communicates so much already (gem, material, aura, quality).

Open questions

  • Do non-card uses (inventory icons, list views) use a low-detail composition or a baked thumbnail cache?
  • Where does the composition test step live in the asset pipeline — automated screenshot diffing? Curator review?
  • Do we expose composition recipes to players (they see the layer breakdown), or stay opaque?
  • Shader budget for mid-tier mobile devices — what's the realistic ceiling for simultaneous focused cards?
  • Do atmosphere layers ever animate (scrolling UV swirls), or are they static PNGs and animation only happens via shader passes?