Skip to main content

Furniture

Furniture items populate the office — desks, chairs, computers, plants, shelving, and decorations. Each item is defined by a manifest.json and one or more PNG sprites in its own folder under assets/furniture/.

Available Items

Desks

ItemDimensionsFootprintRotation
Desk48×32 px3×2 tiles2-way (front/side)
Small Table32×32 px2×2 tiles2-way (front/side)
Table48×64 px3×4 tilesNone
Coffee Table32×32 px2×2 tilesNone

All desks have isDesk: true, meaning other items with canPlaceOnSurfaces can be placed on top of them.

Chairs

ItemDimensionsFootprintRotation
Cushioned Chair16×16 px1×1 tiles3-way mirror
Wooden Chair16×32 px1×2 tiles3-way mirror
Sofa32×16 px2×1 tiles3-way mirror
Cushioned Bench16×16 px1×1 tilesNone
Wooden Bench16×16 px1×1 tilesNone

Chairs generate seat positions used by agents. Each non-background tile in a chair's footprint becomes a seat, with the facing direction determined by the chair's orientation or an adjacent desk.

Electronics

ItemDimensionsFootprintFeatures
PC16×32 px1×2 tiles3-way mirror, on/off state, 3-frame animation

The PC is the most complex asset — it combines rotation, state toggling (on/off), and animation. When an agent sits at a desk facing a PC, it automatically switches to the "on" state.

Decor & Plants

ItemDimensionsFootprintNotes
Plant16×32 px1×2 tiles1 background tile
Plant 216×32 px1×2 tiles1 background tile
Large Plant32×48 px2×3 tiles2 background tiles
Cactus16×32 px1×2 tiles1 background tile
Pot16×16 px1×1 tiles
Coffee16×16 px1×1 tilesCan place on surfaces

Wall Items

ItemDimensionsFootprintNotes
Bookshelf32×16 px2×1 tiles
Double Bookshelf32×32 px2×2 tiles
Whiteboard32×32 px2×2 tiles
Large Painting32×32 px2×2 tiles
Small Painting16×32 px1×2 tiles
Small Painting 216×32 px1×2 tiles
Clock16×32 px1×2 tiles
Hanging Plant16×32 px1×2 tilesCan place on walls and surfaces

Misc

ItemDimensionsFootprint
Bin16×16 px1×1 tiles

Manifest Format

Each furniture item has a manifest.json in its folder. There are two main types:

Simple Asset

{
"id": "BIN",
"name": "Bin",
"category": "misc",
"type": "asset",
"file": "BIN.png",
"width": 16,
"height": 16,
"footprintW": 1,
"footprintH": 1,
"canPlaceOnWalls": false,
"canPlaceOnSurfaces": false,
"backgroundTiles": 0
}

Grouped Asset (Rotation + State + Animation)

Groups nest to compose complex behaviors:

{
"id": "PC",
"name": "PC",
"category": "electronics",
"type": "group",
"groupType": "rotation",
"rotationScheme": "3-way-mirror",
"canPlaceOnSurfaces": true,
"backgroundTiles": 1,
"members": [
{
"type": "group",
"groupType": "state",
"orientation": "front",
"members": [
{
"type": "group",
"groupType": "animation",
"state": "on",
"members": [
{ "type": "asset", "id": "PC_FRONT_ON_1", "file": "PC_FRONT_ON_1.png", "frame": 0, ... },
{ "type": "asset", "id": "PC_FRONT_ON_2", "file": "PC_FRONT_ON_2.png", "frame": 1, ... },
{ "type": "asset", "id": "PC_FRONT_ON_3", "file": "PC_FRONT_ON_3.png", "frame": 2, ... }
]
},
{ "type": "asset", "id": "PC_FRONT_OFF", "file": "PC_FRONT_OFF.png", "state": "off", ... }
]
}
]
}

Manifest Properties

Core Properties

PropertyTypeDescription
idstringUnique asset identifier
namestringDisplay name
categorystringOne of: desks, chairs, storage, electronics, decor, wall, misc
typestring"asset" for a leaf sprite, "group" for a container
filestringPNG filename (leaf assets only)
width / heightnumberSprite dimensions in pixels
footprintW / footprintHnumberGrid footprint in tiles

Placement Properties

PropertyTypeDefaultDescription
canPlaceOnWallsbooleanfalseCan be placed on wall tiles
canPlaceOnSurfacesbooleanfalseCan sit on top of desks/tables
backgroundTilesnumber0Rows from the top that don't block walking

Group Properties

PropertyTypeDescription
groupTypestring"rotation", "state", or "animation"
rotationSchemestring"2-way", "3-way-mirror", or 4-way (default)
orientationstring"front", "back", "left", "right", "side"
statestring"on" or "off"
framenumberAnimation frame index (0-based)
mirrorSidebooleanIf true, the side orientation generates a virtual left variant by flipping

Rotation Schemes

SchemeOrientationsUse Case
2-wayFront + sideSymmetric furniture (desks, tables)
3-way-mirrorFront + back + side (side mirrors to left)Chairs, PCs, sofas
4-way (default)Front + back + left + right

Background Tiles

The backgroundTiles property controls how many rows from the top of the sprite allow characters to walk through. This creates the illusion of depth — for example, a tall plant's canopy extends above the character while the pot blocks the tile.

backgroundTiles: 2 → top 2 rows are walkable
bottom rows block movement

Z-Sorting

Furniture depth is determined by the zY coordinate (bottom edge Y position):

  • Default: zY = y + spriteHeight
  • Chairs: Special handling so seated characters overlap correctly
  • Surface items: Rendered slightly in front of the desk they sit on (zY = deskZ + 0.5)

Furniture Catalog

At runtime, manifests are flattened into a catalog that manages rotation groups, state toggles, and animation sequences. The catalog exposes:

getCatalogEntry(type) // Full entry with all variants
getCatalogByCategory(category) // Filter by category
getRotatedType(type, direction) // Next rotation variant (CW/CCW)
getToggledType(type) // On ↔ off state
getAnimationFrames(type) // Ordered frame IDs

The editor palette shows only the "default" variant of each item (front orientation, off state, first animation frame).

Adding Custom Furniture

  1. Create a folder in webview-ui/public/assets/furniture/ with your PNG sprite(s)
  2. Add a manifest.json describing the item (see format above)
  3. Rebuild the extension

The asset manager (scripts/asset-manager.html) provides a visual editor for creating and editing manifests.

Key Files

FilePurpose
src/assetLoader.tsExtension-side asset loading and PNG decoding
shared/assets/manifestUtils.tsManifest flattening (nested groups → flat array)
shared/assets/pngDecoder.tsPNG → SpriteData conversion
webview-ui/src/office/layout/furnitureCatalog.tsRuntime catalog with rotation/state/animation
webview-ui/src/office/layout/layoutSerializer.tsGrid placement → renderable instances
webview-ui/src/office/types.tsPlacedFurniture, FurnitureInstance types