Pixel Layer v1 — Member Sprite

Goal: show the member as an 8×8 pixel character somewhere useful in the Guild portal. That’s it. Not a full CRPG character screen — just the sprite.

Narrower scope than earlier drafts on purpose. A small pixel sprite leaves room for imagination. Over-defined hero art closes the loop; under-defined sprites let the member project onto the character. This is the right move for v1.

Stack per game-engine-choice: PixiJS v8 + @pixi/react v8 + TypeScript, embedded in the existing Guild Next.js app.

Asset commitment

Total: $8.25. Single attribution line on portal footer satisfies CC-BY 4.0 across both packs.

Why Mini Medieval (captured from decision thread 2026-04-15):

  • Fruitpunch24 palette is warm, whimsical, nostalgic — not dark or menacing. Demonic Dungeon was flagged by Carrie as too hell-like for a cozy indie bookshop.
  • 8×8 register hits the NES / Game Boy / RuneScape Classic nostalgia layer harder than 16×16 SNES polish would. Closer to the MUD-adjacent era in the mud-lineage narrative.
  • Polyphrog’s Fruitpunch24 is a widely-used indie-pixel palette with community tooling. Recognizable provenance.
  • Active growing universe — main pack + UI + planned expansions (dungeons, caves, VFX, additional enemy races). All in one palette.
  • 8×8’s “not enough pixels to over-define” property is a feature, not a bug, for member-projectable identity.

MVP shippable

Render the member’s class as an 8×8 Mini Medieval hero sprite on the existing Guild dashboard. Replace whatever currently represents the member’s class/avatar. No layout redesign. No new page.

Sequence

  1. Install + scaffold (today)

    • pnpm add pixi.js @pixi/react
    • One client-only wrapper component that mounts a PixiJS canvas
    • Verify nearest-neighbor rendering (image-rendering: pixelated + PixiJS scale mode NEAREST)
    • Verify no SSR hydration issues (use next/dynamic with ssr: false)
    • Commit: scaffold only, no sprite yet
  2. First sprite render (today, if pipeline goes smoothly)

    • Pick one Mini Medieval hero sprite as the test case (e.g. the base warrior)
    • Render at chosen upscale factor — start with 8× (64×64 on-screen) and adjust if too small/large
    • Commit: single static sprite on one page
  3. Class → sprite mapping (tomorrow)

    • Read the existing class taxonomy in Guild (need to check — probably in src/collections/ or similar)
    • Map each class to a specific Mini Medieval hero variation
    • Render the member’s actual class sprite based on their data
  4. Idle animation (tomorrow)

    • 2-frame breathing/bob animation
    • Respect prefers-reduced-motion
  5. Checkpoint

    • Ship to prod. Look at member reactions in Discord. Don’t scope further pixel work until signal arrives.

What’s explicitly out of scope

  • Equipment slots, inventory grid, paper doll composition — deferred. May never happen if v1 signal is good enough alone.
  • New /character route — not needed for v1; the sprite lives in existing pages.
  • Stats panel redesign — existing stats UI stays as-is.
  • Level-up animation — defer until sprite itself is shipped and working.
  • Ambient pixel layer across the app — defer until member reaction on the sprite validates the direction.
  • Shop interior scene — bigger bet, after member sprite proves the pipeline and the aesthetic feel.

Technical guardrails

Set up during step 1, not retrofitted.

  • Dev-only perf overlay — FPS + frame time, visible on any page rendering Pixi content
  • prefers-reduced-motion — shared hook consumed by animated components
  • Nearest-neighbor renderingimage-rendering: pixelated + PixiJS TextureStyle.DEFAULTS.scaleMode = 'nearest' or equivalent
  • SSR handling — Pixi components render client-only via next/dynamic({ ssr: false })
  • @pixi/react v8 extend conventions — document which Pixi components are registered where
  • Sprite asset path — store Mini Medieval sprites under public/pixel/mini-medieval/ initially. Organize by type (heroes/, items/, ui/).

PixiJS vs. React DOM (unchanged from earlier draft)

Principle: Pixi for pixels, DOM for structure and text.

Rendered by PixiJS / @pixi/react:

  • Member class sprite (one small canvas per instance)

Regular React DOM + CSS:

  • Everything else — page layout, stats text, navigation, tooltips, responsive behavior, accessibility

@pixi/react makes this cheap — Pixi canvases sit anywhere in the React tree alongside normal DOM. No bridge layer; same React state.

Design rules (PR review checklist)

From guild-1bit-aesthetic and rpg-loyalty-system-creative-direction:

  • Every animation serves feedback, continuity, or identity. No decoration-only sprites.
  • Fantasy voice on smilable surfaces; plain language on trust-critical surfaces.
  • Genuinely magical, not ironic. The sprite IS the member, not a joke about RPGs.
  • Nearest-neighbor everywhere. No anti-aliasing on pixel art.
  • Respect the 8×8 constraint. Don’t try to add detail the grid can’t hold. Let silhouette and motion do the work.

Open decisions

  • Upscale factor: 8× (64×64) or 12× (96×96)? Test both in-browser on the actual dashboard surface before committing
  • Where exactly the sprite lives: dashboard hero area, nav avatar, profile card — check the existing UI and pick the spot that reads as “this is me”
  • Class → hero mapping: need to look at Mini Medieval’s actual hero sprites and map to roles-classes-jobs taxonomy. Some classes may not have a natural fit; pick the nearest or create our own by swapping colors later.
  • Font pairing: bitmap text via CSS (cheapest) or MRMOTEXT 8×8 sprites for numbers. v1 probably CSS pixel font.