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
Should have
Nice to have
Parent epic
#222 — Pixel art upgrade for catwalk visualization
Description
The catwalk visualization currently renders agents as Excalibur geometric primitives:
Circle+Textfor station agents,Rectangle+Textfor 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
StationAgentActorrenders aCircle(radius 14px) with role color + text label overlayOrchestratorActorrenders aRectangle(~35×25px) in gold with "ORCH" text#111111(near-black)packages/factory/src/client/game/sprites/that proves the patternProposed solution
2 new sprite sheets loaded via Vite static imports:
catwalk/sprites/assets/subagent.svg#888899rectangles)catwalk/sprites/assets/orchestrator.svg#CCAA44rectangles)Both sheets follow the existing
sprite-definitions.tsframe layout (already used by FactoryScene):Role differentiation: A colored
Rectangleaccent bar (4px tall) beneath each subagent sprite, using the existingROLE_TYPE_COLORSpalette per role type.New modules:
catwalk/sprites/sprite-sheet-urls.ts— mapsCatwalkSpriteType('subagent'|'orchestrator') → Vite static asset URLcatwalk/sprites/catwalk-sprite-loader.ts— loads sprite sheets, creates cached ExcaliburAnimationobjects per animation state. ExportsloadAllCatwalkSprites()(async init) andgetAnimation(spriteType, state)(cached lookup)Modified actors:
StationAgentActor— replacesCircle+TextwithAnimation+ accent barGraphicsGroup.updateConfig()switches animation state + opacity.OrchestratorActor— replacesRectangle+TextwithAnimation.working: true→ working animation,false→ idle.CatwalkScene— callsloadAllCatwalkSprites()inonInitialize(), background changes from#111111to midnight blue#1a1a2eReused unchanged:
sprite-definitions.ts(frame coordinates, animation durations/strategies — shared contract between code and art)catwalk-differ.ts,run-to-catwalk.ts, layout logicArtifactActor,ChuteActor,GateActor(remain geometric primitives)Key files to reference
packages/factory/src/client/game/sprites/sprite-definitions.tspackages/factory/src/client/game/sprites/agent-sprite-loader.tspackages/factory/src/client/visualizations/catwalk/actors/StationAgentActor.tspackages/factory/src/client/visualizations/catwalk/actors/OrchestratorActor.tspackages/factory/src/client/visualizations/catwalk/scene/CatwalkScene.tspackages/factory/src/client/visualizations/catwalk/constants/dimensions.tsAGENT_RADIUS=14needs to become 16 for 32×32 spritespackages/factory/src/client/visualizations/catwalk/actors/__tests__/actors.test.tsvi.mock('excalibur')packages/factory/src/client/visualizations/catwalk/scene/__tests__/CatwalkScene.test.tsQuality gates
Run from repo root:
pnpm typecheckpnpm lintpnpm testcd packages/factory && pnpm dev→ open catwalk visualizationAcceptance criteria
Must have
catwalk/sprites/assets/(128×96 SVGs, 4×3 grid of 32×32 frames, transparent backgrounds)sprite-sheet-urls.tsmaps sprite types to Vite static asset URLscatwalk-sprite-loader.tsloads sheets, creates cachedAnimationobjects per state, exportsloadAllCatwalkSprites()andgetAnimation()StationAgentActorrenders sprite animation + colored accent bar (notCircle+Text)OrchestratorActorrenders sprite animation (notRectangle+Text)CatwalkScenebackground is#1a1a2e(midnight blue) and calls sprite loader on initAGENT_RADIUSandORCH_RADIUSupdated to 16 (half of 32×32 sprite)pnpm typecheck && pnpm lint && pnpm test)Should have
ROLE_TYPE_COLORS[roleType]per agentloadAllCatwalkSprites()call is a no-op)getAnimation()throws if called before loadingNice to have
packages/factory/scripts/generate-placeholder-pngs.ts) for regenerating placeholdersParent epic
#222 — Pixel art upgrade for catwalk visualization