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
- Mini Medieval ($5, CC-BY 4.0, 8×8, Fruitpunch24) — https://v3x3d.itch.io/mini-medieval
- Mini Medieval — UI ($3.25, CC-BY 4.0, 8×8, Fruitpunch24) — https://v3x3d.itch.io/mini-medieval-user-interface
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
-
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/dynamicwithssr: false) - Commit: scaffold only, no sprite yet
-
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
-
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
- Read the existing class taxonomy in Guild (need to check — probably in
-
Idle animation (tomorrow)
- 2-frame breathing/bob animation
- Respect
prefers-reduced-motion
-
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
/characterroute — 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 rendering —
image-rendering: pixelated+ PixiJSTextureStyle.DEFAULTS.scaleMode = 'nearest'or equivalent - SSR handling — Pixi components render client-only via
next/dynamic({ ssr: false }) - @pixi/react v8
extendconventions — 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.
Related
- game-engine-choice — stack decision (PixiJS + @pixi/react)
- guild-1bit-aesthetic — visual direction (Mini Medieval / Fruitpunch24 locked in v1)
- rpg-loyalty-system-creative-direction — voice + fantasy-internet principles
- mud-lineage — why 8×8 register matches the MUD narrative
- roles-classes-jobs — class taxonomy for sprite mapping