Skip to content

Create sprite-loading infrastructure with placeholder assets for catwalk #223

Description

@williamthorsen

Description

The catwalk visualization currently renders agents as Excalibur geometric primitives: Circle + Text for station agents, Rectangle + Text for the orchestrator. This ticket builds the sprite loading infrastructure and placeholder assets needed to transition to pixel art sprites, as designed in the parent epic #222.

The placeholder assets (simple colored-rectangle SVGs with frame-number labels) serve as a build-bridge — all code is fully functional and testable before AI-generated pixel art arrives. Swapping in real art later is a single file replacement per sprite sheet.

Current state

  • StationAgentActor renders a Circle (radius 14px) with role color + text label overlay
  • OrchestratorActor renders a Rectangle (~35×25px) in gold with "ORCH" text
  • Background is #111111 (near-black)
  • No sprite loading infrastructure exists in the catwalk visualization
  • The FactoryScene (separate visualization, being discarded) has a working sprite system in packages/factory/src/client/game/sprites/ that proves the pattern

Proposed solution

2 new sprite sheets loaded via Vite static imports:

Sheet File Visual Purpose
Subagent catwalk/sprites/assets/subagent.svg Neutral metallic (placeholder: steel gray #888899 rectangles) Shared across all non-orchestrator roles
Orchestrator catwalk/sprites/assets/orchestrator.svg Distinct silhouette (placeholder: gold-tinted #CCAA44 rectangles) Unique mobile agent

Both sheets follow the existing sprite-definitions.ts frame layout (already used by FactoryScene):

  • Grid: 4 columns × 3 rows, 32×32px per frame (128×96 total)
  • Frame layout: Row 0 = idle (0-1), walking (2), resting-1 (3); Row 1 = working (0-2), resting-2 (3); Row 2 = celebrating (0-1), concerned (2), resting-3 (3)
  • Transparent backgrounds

Role differentiation: A colored Rectangle accent bar (4px tall) beneath each subagent sprite, using the existing ROLE_TYPE_COLORS palette per role type.

New modules:

  • catwalk/sprites/sprite-sheet-urls.ts — maps CatwalkSpriteType ('subagent' | 'orchestrator') → Vite static asset URL
  • catwalk/sprites/catwalk-sprite-loader.ts — loads sprite sheets, creates cached Excalibur Animation objects per animation state. Exports loadAllCatwalkSprites() (async init) and getAnimation(spriteType, state) (cached lookup)

Modified actors:

  • StationAgentActor — replaces Circle + Text with Animation + accent bar GraphicsGroup. updateConfig() switches animation state + opacity.
  • OrchestratorActor — replaces Rectangle + Text with Animation. working: true → working animation, false → idle.
  • CatwalkScene — calls loadAllCatwalkSprites() in onInitialize(), background changes from #111111 to midnight blue #1a1a2e

Reused unchanged:

  • sprite-definitions.ts (frame coordinates, animation durations/strategies — shared contract between code and art)
  • catwalk-differ.ts, run-to-catwalk.ts, layout logic
  • ArtifactActor, ChuteActor, GateActor (remain geometric primitives)

Key files to reference

File Relevance
packages/factory/src/client/game/sprites/sprite-definitions.ts Frame coordinates and animation config — reused as-is
packages/factory/src/client/game/sprites/agent-sprite-loader.ts Reference implementation for the loader pattern (FactoryScene version)
packages/factory/src/client/visualizations/catwalk/actors/StationAgentActor.ts Currently 69 lines — replace Circle+Text with sprite
packages/factory/src/client/visualizations/catwalk/actors/OrchestratorActor.ts Currently 50 lines — replace Rectangle+Text with sprite
packages/factory/src/client/visualizations/catwalk/scene/CatwalkScene.ts Scene init + background color
packages/factory/src/client/visualizations/catwalk/constants/dimensions.ts AGENT_RADIUS=14 needs to become 16 for 32×32 sprites
packages/factory/src/client/visualizations/catwalk/actors/__tests__/actors.test.ts Existing actor tests — mock pattern with vi.mock('excalibur')
packages/factory/src/client/visualizations/catwalk/scene/__tests__/CatwalkScene.test.ts Scene tests — mocks actors module

Quality gates

Run from repo root:

  • pnpm typecheck
  • pnpm lint
  • pnpm test
  • Visual smoke test: cd packages/factory && pnpm dev → open catwalk visualization

Acceptance criteria

Must have

  • 2 placeholder sprite sheets in catwalk/sprites/assets/ (128×96 SVGs, 4×3 grid of 32×32 frames, transparent backgrounds)
  • sprite-sheet-urls.ts maps sprite types to Vite static asset URLs
  • catwalk-sprite-loader.ts loads sheets, creates cached Animation objects per state, exports loadAllCatwalkSprites() and getAnimation()
  • StationAgentActor renders sprite animation + colored accent bar (not Circle + Text)
  • OrchestratorActor renders sprite animation (not Rectangle + Text)
  • CatwalkScene background is #1a1a2e (midnight blue) and calls sprite loader on init
  • AGENT_RADIUS and ORCH_RADIUS updated to 16 (half of 32×32 sprite)
  • All existing tests pass (pnpm typecheck && pnpm lint && pnpm test)

Should have

  • Accent bar uses ROLE_TYPE_COLORS[roleType] per agent
  • Loader is idempotent (second loadAllCatwalkSprites() call is a no-op)
  • getAnimation() throws if called before loading

Nice to have

  • One-shot generator script (packages/factory/scripts/generate-placeholder-pngs.ts) for regenerating placeholders

Parent epic

#222 — Pixel art upgrade for catwalk visualization

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:factory

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions