# A compact two-storey house — one drawing per storey, from `level` blocks. # # Settings and the plan-global `let`s live OUTSIDE the levels and apply to every one of # them: one building is issued on one sheet at one scale. Each level's body is an ordinary # plan body, and ids are unique WITHIN a level — so the `stair` below exists on both floors # at the same coordinates, and that shared id is what declares one shaft: `describe --json` # reports it under `vertical.connections`, and it is why the first floor needs no front # door of its own to lint clean. # # THE HEIGHTS DRAW NOTHING, AND THAT IS THE POINT. A plan is a horizontal cut, so the # `height` below moves no byte of either drawing — `examples/two-storey.svg` is the same # file it was before these clauses existed. What the datum feeds is `describe --json # --select heights` and `arch compile --view axon`. It is written in three tiers, narrowing: # the plan's `height 2700` is every storey's floor-to-floor, the upper `level … height 3000` # overrides it for that storey alone, and a `sill`/`head` on a window bounds that one piece # of glazing. `heights.elevation` ACCUMULATES the storeys below rather than multiplying, so # the first floor sits at 2700 — the ground floor's height — not at 2 x 3000. Most windows # here write nothing and take the 900/2100 defaults; the two that do write are the two a # drawing cannot tell you about. plan "Two-storey house" { units mm grid 50 height 2700 # floor-to-floor for every storey that does not override it paper A3 landscape north up dims auto all let W = 8000 # outer width (wall centerlines) let D = 7000 # outer depth let T = 200 # exterior wall thickness let HALL = 2200 # the stair hall / landing runs the full depth on the left level 1 "Ground floor" { wall id=shell exterior thickness T { (0,0) (W,0) (W,D) (0,D) close } wall id=hall_w partition thickness 100 { (HALL,0) (HALL,D) } wall id=kitchen_w partition thickness 100 { (HALL,3600) (W,3600) } room id=hall at (0,0) size 2200x7000 label "Hall" uses hall room id=living at (2200,0) size 5800x3600 label "Living" uses living room id=kitchen at (2200,3600) size 5800x3400 label "Kitchen" uses kitchen door id=front on shell at 21900 width 1000 swing into hall door id=d_living on hall_w at 1800 width 900 swing into living door id=d_kitchen on hall_w at 5300 width 900 swing into kitchen # A tall window onto the garden: 300 off the floor and up to 2400, inside this # storey's 2700. The kitchen window beside it writes neither and takes 900/2100. window id=w_living on shell at 5000 width 1800 sill 300 head 2400 window id=w_kitchen on shell at 13300 width 1200 furniture sofa in living anchor top flush inset 300 size 2000x850 label "Sofa" furniture kitchen_sink against wall kitchen_w offset 1200 in kitchen furniture stove against wall kitchen_w offset 2200 in kitchen furniture counter against wall kitchen_w offset 2900 in kitchen furniture fridge against wall kitchen_w offset 3600 in kitchen stair id=stair at (100,1000) size 900x2900 dir up } # A taller first floor than the ground: `height` in the level HEADER overrides the plan's # 2700 for this storey only (a `height` in the body would be E_LEVEL_MIX). level 2 "First floor" height 3000 { wall id=shell exterior thickness T { (0,0) (W,0) (W,D) (0,D) close } wall id=hall_w partition thickness 100 { (HALL,0) (HALL,D) } wall id=bath_w partition thickness 100 { (0,4900) (HALL,4900) } wall id=bed_w partition thickness 100 { (HALL,3600) (W,3600) } room id=landing at (0,0) size 2200x4900 label "Landing" uses circulation room id=bath at (0,4900) size 2200x2100 label "Bath" uses bath room id=bed1 at (2200,0) size 5800x3600 label "Bedroom 1" uses bedroom room id=bed2 at (2200,3600) size 5800x3400 label "Bedroom 2" uses bedroom # No exterior door up here: the `stair` below carries the same id as the ground # floor's, so the access graph reads the landing as reached from outside via the # storey below. (Before vertical circulation was modelled this floor needed a # made-up balcony door to lint clean.) door id=d_bed1 on hall_w at 1800 width 900 swing into bed1 door id=d_bed2 on hall_w at 4250 width 900 swing into bed2 door id=d_bath on bath_w at 1100 width 800 swing into bath window id=w_bed1 on shell at 5000 width 1500 window id=w_bed2 on shell at 13300 width 1200 # A bathroom window set high for privacy: `sill` alone, so the head still defaults to # 2100 — an authored bound and a defaulted one on the same opening. window id=w_bath on shell at 24200 width 600 sill 1500 furniture bed in bed1 anchor top-right flush inset 300 size 1500x2000 label "Double" furniture bed in bed2 anchor bottom flush inset 300 size 1000x2000 label "Single" furniture wc against bath.right offset 1100 size 400x700 furniture basin in bath anchor bottom-right flush size 600x450 furniture shower in bath anchor bottom-left flush size 900x900 stair id=stair at (100,1000) size 900x2900 dir down # The landing looks down into the hall below over a balustrade: there is no floor # here, so the plan says so. A `void` is drawn (dashed rectangle + both diagonals) # and it OBSTRUCTS circulation — you cannot walk across a hole — with the walkable # halo suppressed on every edge, because you can stand at the railing. It does NOT # come off the landing's area: that number is the room's floor area and it is what # the schedule and `describe --json` both report, so subtracting the well here would # leave the drawing and the table disagreeing. `describe --json` lists it under # `voids[]` with the room it falls in, which is where a net figure comes from. void id=gallery at (100,1000) size 900x2900 # The eaves, on the top storey only — this level's `shell` is the plan's one # closed exterior ring on THIS page, so no `wall` clause is needed. roof overhang 400 } title { project "Two-storey house" drawn_by "ArchLang" date "2026-07-26" } }