# Design My Floor Plan - JSON format for AI agents This document describes the design-file format used by [designmyfloorplan.com](https://designmyfloorplan.com). An AI agent can generate a file in this format from a plain-English description ("a 3-bedroom ranch with an open kitchen"), and the user imports it with **File -> Import** or **File -> Paste design JSON**. A working example lives in [`sample-design.json`](sample-design.json). --- ## The one rule that matters most **All coordinates and sizes are in PIXELS, where 1 foot = 24 pixels** (1 inch = 2 pixels). Only `canvasWidthFeet` / `canvasDepthFeet` are in feet. ``` feet -> pixels: px = feet * 24 inches -> pixels: px = inches * 2 ``` So a 12 ft x 10 ft room is `"w": 288, "h": 240`. Everything uses a top-left origin: `x` grows right, `y` grows down. --- ## File skeleton ```json { "version": 2, "app": "home-designer", "projectName": "My House", "canvasWidthFeet": 100, "canvasDepthFeet": 75, "style": "draft", "snapInches": 6, "defaultCeilingInches": 108, "showOverlapWarnings": true, "buildingSections": [], "rooms": [], "hallways": [], "outdoors": [], "walls": [], "doors": [], "windows": [], "furniture": [], "dimensions": [], "texts": [], "nextId": 1000 } ``` - `"app": "home-designer"` is **required** - the import is rejected without it. - Every object needs a unique `id` (any unique string, e.g. `"id-1"`, `"id-2"`). - `nextId` should be a number higher than any numeric id you used. - `style` is `"draft"` (clean lines) or `"rich"` (warm, textured). --- ## Object shapes ### buildingSections - the outer footprint Rectangles that merge into the overall building shape. Use several for L/T/U plans. ```json { "id": "id-1", "x": 240, "y": 240, "w": 1440, "h": 960 } ``` ### rooms ```json { "id": "id-10", "name": "Kitchen", "x": 264, "y": 264, "w": 288, "h": 240, "openSides": ["e"] } ``` - `openSides` is optional: any of `"n"`, `"s"`, `"e"`, `"w"`. Listed sides draw **no wall** - use it for open-plan connections and doorways without a door. ### hallways / outdoors Same rectangle shape. `outdoors` (patios, decks, yards) take a `name`. ```json { "id": "id-20", "x": 600, "y": 500, "w": 96, "h": 480 } { "id": "id-30", "name": "Back Patio", "x": 240, "y": 1200, "w": 480, "h": 144 } ``` **Outdoor areas go OUTSIDE the building footprint, flush against one edge - never overlapping it.** If the building is `x:240, y:240, w:1536, h:912`, a full-width front porch (10 ft deep) sits *below* it: ```json { "id": "id-31", "name": "Front Porch", "x": 240, "y": 1152, "w": 1536, "h": 240 } ``` That is: same `x` and `w` as the building, and `y` = building `y + h` (porch starts exactly where the building ends). A back porch uses `y = buildingY - porchDepth`. Overlapping the building makes the porch render on top of your rooms. ### walls - free-standing segments Thin rectangles. A typical wall is 8px (4in) thick. ```json { "id": "id-40", "x": 742, "y": 1076, "w": 8, "h": 72 } ``` ### doors `x,y` is the hinge-edge midpoint, **not** the center. `w` is the opening width. `rot` is degrees: `0` = opening faces down/south, `90` = faces left/west, etc. ```json { "id": "id-50", "kind": "interior", "x": 600, "y": 504, "w": 60, "rot": 0, "hinge": "left" } ``` - `kind`: `"interior"` | `"exterior"` | `"garage"` - `hinge`: `"left"` | `"right"` - Typical widths: interior 60 (30in), exterior 72, garage 192-216 ### windows ```json { "id": "id-60", "x": 571, "y": 1676, "w": 72, "rot": 0 } ``` Place along a wall; `rot` `0` for horizontal walls, `90` for vertical. ### furniture `x,y` is the **center** of the piece. `w`/`h` are optional (sensible defaults per kind are used if omitted). ```json { "id": "id-70", "kind": "kingbed", "x": 900, "y": 600, "rot": 0 } ``` Valid `kind` values: ``` sofa, loveseat, armchair, coffeetable, diningtable, table, chair, tv, bookshelf, fireplace, piano, bed, kingbed, twinbed, crib, dresser, nightstand, wardrobe, closet, walkincloset, desk, toilet, sink, vanity, bathtub, shower, tubshower, stove, fridge, dishwasher, microwave, kitchensink, island, countertop, stairs_straight, stairs_l, stairs_u, stairs_spiral, washer, dryer, waterheater, furnace, car, suv, truck, motorcycle, boat, bike, patiotable, grill, pool, hottub, plant, tree ``` Stairs also accept `"direction": "up"` or `"dn"`. ### texts ```json { "id": "id-80", "x": 500, "y": 400, "text": "Note", "size": 16, "rot": 0 } ``` Rooms and outdoor areas already render their own name and dimensions, so do **not** add a text label that repeats them - it just overlaps the built-in label. Use `texts` only for genuine extra notes. Most plans need none. ### dimensions ```json { "id": "id-90", "x1": 460, "y1": 1922, "x2": 900, "y2": 1922 } ``` --- ## Guidance for good output - **Keep everything inside the canvas.** Content must fit within `canvasWidthFeet x 24` and `canvasDepthFeet x 24` pixels or it's cut off in exports. Grow the canvas rather than letting the plan spill outside it. - **Tile the footprint completely.** Every part of the building interior should be covered by a room, hallway, or closet - no leftover gaps. Unfilled areas render as empty voids and look broken. - **Lay rooms out edge-to-edge.** Adjacent rooms sharing a wall share the same coordinate line: room A's `x + w` equals room B's `x`. Rooms must not overlap. ### A layout procedure that works Don't place rooms ad hoc - work it out as bands, then fill each band: 1. **Pick the footprint.** For ~2400 sq ft, e.g. 64 ft x 38 ft (`w: 1536, h: 912`). Put it at a round origin like `x: 240, y: 240`. 2. **Split into horizontal bands** that span the full width and sum exactly to the building height. E.g. a 912-tall building as 432 + 96 (hallway) + 384. **Every band must be a uniform full-width strip** - one `y` and one `h` for all rooms in it. Do not mix heights within a band or let a tall room span several bands; that's how rooms end up double-placed on top of each other. 3. **Split each band into rooms** whose widths sum exactly to the building width. Track a running `x` as you go so there are no gaps or overlaps. 4. **Verify the arithmetic** before emitting: for each band, sum of room widths == building width; sum of band heights == building height. Then check that **no two rooms overlap** - the total of all room areas must equal the building area exactly. If it's larger, something is stacked. 5. **Then** add doors on the shared walls, windows on exterior walls, and furniture centered in rooms. For open-concept, use ONE large room named e.g. "Living / Dining / Kitchen" rather than separate rooms, or use adjacent rooms with `openSides` facing each other so no wall is drawn between them. ### Circulation: making the plan actually livable A plan can tile perfectly and still be a house nobody could live in. These rules are as important as the geometry - check every one before you finish. **THE CORE MISTAKE TO AVOID:** laying out rooms first and adding doors after. A door can only exist where two rooms *share a wall*. If you place the rooms first and then look for somewhere to put doors, you will discover that the bedrooms don't touch the hallway at all, and you'll be forced to connect them to each other - producing a house where you walk through two bedrooms to reach an office. **Plan the hallway FIRST, then hang rooms off it.** **0. Lay out the circulation spine before any other room.** Reserve the hallway as an explicit band or column in step 2 of the layout procedure, running from the entry to the private wing. Then place bedrooms, bathrooms and offices *directly against it* so each one shares a wall with the hall. Concretely, for a bedroom wing along the bottom of the building: ``` band y=672 h=96 -> Hallway spanning the full width of the wing band y=768 h=384 -> Bedroom 1 | Bedroom 2 | Bath | Bedroom 3 ``` Every room in that second band touches the hallway above it, so every one can have its own door. **Before placing a single bedroom, ask: which wall of this room touches the hall?** If the answer is "none", the layout is wrong - fix the bands, not the doors. **1. Every private room needs its own door to circulation.** Every bedroom, every bathroom, and any office must open onto the hallway, the foyer, or the main living area - never onto each other. A 3-4 ft corridor is `w: 72` to `96` (or `h: 72` to `96` for a horizontal hall). **2. Never chain rooms together.** This is the most common mistake. If the only way to reach room C is `Living -> Bedroom A -> Bedroom B -> C`, the plan is broken. Specifically: - A bedroom must NEVER be a passageway to another room. - Two bedrooms must never share a door. - An office must not be entered through a bedroom. **3. Doors define circulation, not adjacency.** Two rooms touching does not connect them - only a door (or `openSides`) does. For every room, ask: "starting at the front door, what is the path here?" If that path crosses a private room, move the door or add a hallway. **4. Privacy rules.** - Bathrooms open onto a hallway or their own bedroom - never directly onto the living room, dining room, or kitchen. - A shared/guest bathroom goes off the hallway so guests never enter a bedroom. - The primary suite (bedroom + its bath + closet) is entered from the hallway, and its bath/closet are entered from inside the bedroom. **5. Utility spaces sit at the edge, as dead-ends.** Mud room, laundry, and utility rooms are destinations, not corridors. The mud room goes just inside a side or rear exterior door with the laundry beside it. Never route the path to a bedroom, office, or living area through them. **6. Give every exterior door somewhere sensible to land.** The front door opens into the living area or an entry - not into a bedroom. A side door opens into the mud room. Back doors open to the living/dining area or the patio. ### Required self-check before you output Run this explicitly. If any check fails, fix the LAYOUT (move the bands) - not just the doors. 1. **Hall contact.** For every bedroom, bathroom, and office, name the circulation space it shares a wall with. Any room that answers "none" is a bug - it cannot be given a door. 2. **One door each.** Every bedroom, bathroom and office has a door onto that circulation space. 3. **No private room is a corridor.** No door connects two bedrooms. No room's only access is through a bedroom, bathroom, closet, mud room, or laundry. 4. **Walk it.** Starting at the front door, write the path to each room, e.g. `Front door -> Foyer -> Hall -> Bedroom 2`. Every path must consist only of entry, hallway, and living/dining/kitchen spaces before its destination. A path like `Foyer -> Bedroom 3 -> Bedroom 2 -> Front Office` is broken. 5. **Areas add up.** Sum of all room areas == building area (no overlaps/gaps). State the results of checks 1 and 4 to yourself before emitting the JSON. ### Escaping note Room names and text values are JSON strings, so an inches mark must be escaped: write `"text": "60'-0\""`, never `"text": "60'-0""`. The second form is invalid JSON and the import will fail. Simplest fix: avoid `"` in text entirely and write `60 ft` or `60'-0 in`. - **Round to the snap grid.** With `snapInches: 6`, keep coordinates on multiples of 12 px. - **Never emit a zero or tiny dimension.** Minimum usable size is 72 px (3 ft) per side. A room or outdoor area with `w: 0` renders as a broken sliver - double-check every `w` and `h` is set and >= 72. - **Realistic sizes:** bedroom 10-14 ft, bathroom 5-9 ft, hallway 3-4 ft wide, ceiling 108 in (9 ft). - **Doors belong on walls** between rooms, and exterior doors on the building perimeter. --- ## Prompt to hand an AI agent > Generate a floor plan as JSON for designmyfloorplan.com, following the format > at https://designmyfloorplan.com/ai-format.md. Remember all coordinates are in > pixels at 24 px per foot. Here's what I want: ****. > Output only the JSON.