Skip to content

Replace geometric placeholders with tileset rendering #310

Description

@williamthorsen

Problem

The Excalibur OfficeScene renders agents as colored circles, artifacts as colored rectangles, and zones as tinted rectangles. The data pipeline is fully built (mapper, differ, transition planner, position resolver) but the rendering layer uses geometric placeholders. The static prototypes from #307 demonstrate that the LimeZu tilesets produce a warm, readable office visualization. This issue replaces placeholders with actual tileset sprites.

Relevant considerations

  • Asset source: LimeZu Modern Office Revamped v1.2 (furniture spritesheet, 16×53 tiles) and Modern Interiors (room builder sheets, character idle sprites). Licensed for distribution. Assets should be copied into the repo at office/sprites/assets/ (~300KB total).
  • Established pattern: The catwalk visualization demonstrates the sprite loading approach: Vite asset imports → ImageSourceSpriteSheetSprite, with a singleton cache in a dedicated loader module.
  • Existing pipeline: CanonicalRunStatusmapRunToLogicalScene()LogicalSceneStatemapLogicalToOffice()OfficeSceneConfigdiffOfficeConfigs()OfficeDiff. This pipeline stays unchanged — only the rendering calls change.
  • Furniture from spritesheet regions: The v8 prototype demonstrated that multi-tile composites (orchestrator desk 5×4, coder desk 2×2, rear-facing monitors 1×2) must be extracted as regions from the full spritesheet, not just the 64×96 singles.
  • Character directions: Direction 3 (up/facing wall) for desk workers at wall-mounted displays. Direction 0 (down/facing camera) for the orchestrator and reviewers who stand behind their desks.
  • Design skill: .agents/skills/office-visual-design/SKILL.md encodes palette, tile coordinates, wall construction, composition principles, and quality rubric.

Proposed solution

  1. Copy tileset assets into office/sprites/assets/ — room builder sheets (floors, walls, shadows), the full office furniture spritesheet, 12 furniture singles, and 7 character idle sprites.
  2. Create sprite loader (office-sprite-loader.ts) following the catwalk singleton cache pattern. Loads all sheets and singles via ImageSource with pixel filtering.
  3. Create sprite definitions (sprite-definitions.ts) with tile source coordinates, furniture manifest (position + spritesheet region for each item), and character-to-role mapping.
  4. Create OfficeCanvas.tsx React wrapper matching CatwalkCanvas.tsx — hosts the Excalibur engine and bridges React state to OfficeScene via updateStatus(status).
  5. Rewrite OfficeScene.ts rendering layer — draw tiled background (floors, walls, shadows, doorways) on a single Canvas actor, place furniture sprites from the manifest, render characters from idle sprite sheets. Keep the existing data pipeline unchanged.
  6. Register office in the visualization registry.

Acceptance criteria

  • Tiled floor, wall, and shadow rendering from LimeZu tile sheets (cream floors, gray transition strip, two-row north walls with doorway gaps, floor shadows)
  • Furniture sprites placed at workstation positions matching the v8 prototype layout — including multi-tile spritesheet regions (orchestrator desk, coder desk, rear-facing reviewer monitors)
  • Character idle sprites replace colored circles (Alex=architect, Amelia=planner, Dan=coder, Bob/Ash/Rob=reviewers, Adam=orchestrator)
  • OfficeCanvas.tsx registered in registry.ts, accessible via ?vis=office
  • Scene updates correctly when run state changes (agents appear/disappear at assigned slots)
  • Existing adapter pipeline tests continue to pass (pnpm --filter factory test)
  • No type errors (pnpm --filter factory typecheck)

Out of scope

Depends on

Guided by

.agents/skills/office-visual-design/SKILL.md

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