ArchLang Playground

Tiny House — an ArchLang floor plan example

A 7.2 x 3.0 m micro-home that argues over millimetres: barn and bifold doors, and the clearances they need.

This plan compiles to 2 rooms, 19.6 m² of floor area and 5 windows; every room is reachable from the entrance.

Ladder Living / Sleep 14.8 m² Wet room 4.8 m² 1850 7200 3000 N 02 m PROJECTTiny HouseDRAWN BYArchLangDATE2026-08-16
"Tiny House" — a 2-room floor plan, 19.6 m² total: Living / Sleep (14.84 m²), Wet room (4.76 m²); 3 doors, 5 windows, entrance via d_front.
Open in the editor

The source

This is the whole plan. The drawing above is what the compiler produced from it — nothing was drawn by hand.

# A 7.2 x 3.0 m micro-home on one level — the DOOR-KINDS-AND-CLEARANCE example.
#
# A tiny house is the building where every millimetre is argued over, so it is the right
# plan to show the three language forms that are about *fit* rather than shape:
#
#   door barn   … open 0.6   a leaf that hangs on the FACE of the wall instead of in it
#   door bifold … width 1600 two leaves that fold into their own opening
#   dim clear   (a)->(b)     a dimension pulled in to the two INNER wall faces
#
# Why a barn door and not a hinged one? The wet room is 1.55 m wide. A hinged leaf
# swinging in fouls the WC; swinging out it sweeps the only walkway in the house. A barn
# leaf sweeps nothing at all — `doorSwing()` returns null for every non-hinged kind, so
# `W_SWING_OBSTRUCTED` cannot even apply to it — and parks on the wall it came from.
# `slide right` sends it toward the wall's far end (the same left/right convention
# `hinge` uses, read along the wall's own traversal direction), which here is the blank
# south-east corner of the living room rather than back over the loft ladder.
#
# `open 0.6` is DRAWING-ONLY. Nothing measured reads it: it changes how far along the
# wall the panel is drawn and nothing else. It is written here because a barn door drawn
# shut is indistinguishable from a hinged one on paper, and the point of the drawing is
# to show where the leaf goes when it is open.
#
# The wardrobe is a built-in recess, not a room — at 1.9 x 0.65 m it is far under the
# 4 m2 floor `lint` expects of a room, and calling it one would be a fiction. It is
# simply two partitions and a `bifold` door: two leaves, each half the 1600 opening,
# folding out of the way instead of swinging 800 mm into a galley that is 1.85 m wide.
#
# That 1.85 m is what `dim clear` reports. An ordinary `dim` measures between the two
# points you wrote; `clear` pulls each endpoint in onto the inner FACE of the wall the
# measurement runs into — here the galley face of the wardrobe front and the inner face
# of the north shell — so the number is the built clear width, derived, never typed.
# Take 600 mm of worktop out of it and 1250 mm of walkway is left, which is why the
# fridge door and the wardrobe leaves can both be open at once.
#
# ONE DELIBERATE WARNING, left in on purpose:
#
#   W_PATH_TOO_NARROW x1 — the walk to the Wet room. `arch describe --json` reports it
#   under `circulation.blocked` with a MEASURED `widestWayInMm` of 400 against the
#   700 mm minimum. The 800 mm barn door is not the pinch; the room is: 1700 x 2800 mm
#   holding a shower, a WC and a basin, which is what a wet room in a 7.2 x 3.0 m house
#   costs. The warning appeared in v1.33.0, when the rule stopped going silent on a room
#   it could not reach — before that this plan reported nothing at all, which was worse
#   than reporting 400 mm. It stands rather than being nudged away: moving a piece to
#   silence a measurement is how a plan stops being evidence. `arch validate` is clean;
#   `arch validate --strict` reports this one.
plan "Tiny House" {
  units mm
  # `grid 50`, not 100: every partition here is 100 thick, so a fixture placed `flush`
  # against one lands on a half-thickness (...50) coordinate, and a 100 grid would snap
  # it back INTO the wall.
  grid 50
  north up

  # ---- shell + the two pieces of joinery that act as structure ---------------
  # 7200 x 3000 over the outer faces; 6800 x 2600 inside. The shell is one closed
  # outline so its corners mitre, and openings on it are written `at (x,y) wall shell`
  # — an exact centreline point, which can no more be off-wall than `on … at <pos>` can.
  wall id=shell exterior thickness 200 { (0,0) (7000,0) (7000,2800) (0,2800) close }

  # The wet room's only partition. Named, because the barn door is hung on it by run
  # distance from its first point, (5300,0).
  wall id=w_wet partition thickness 100 { (5300,0) (5300,2800) }

  # The wardrobe: a front and a return. Everything they enclose is still living-room
  # floor as far as the plan is concerned — a recess, not a space.
  wall id=w_ward   partition thickness 100 { (0,2000) (2000,2000) }
  wall id=w_ward_e partition thickness 100 { (2000,2000) (2000,2800) }

  # ---- rooms ----------------------------------------------------------------
  # One room does living, sleeping and cooking, which is what `uses living kitchen`
  # says: it is a kitchen for the fixture rules and a living room for everything else.
  room id=r_main at (0,0)    size 5300x2800 label "Living / Sleep" uses living kitchen
  room id=r_wet  at (5300,0) size 1700x2800 label "Wet room"       uses bath

  # ---- doors ----------------------------------------------------------------
  # The front door is the only hinged leaf in the house, and the only one with a swing
  # arc to keep clear: 900 mm of quarter-disc between the wardrobe return and the bench.
  door id=d_front at (2700,2800) width 900 wall shell hinge left swing in

  # The wet room. `swing` on a barn door does not mean a sweep — there is none — it
  # names the FACE the leaf hangs on, and `in` is the wall's +normal side: the living
  # room, where there is 1600 mm of blank wall for the panel to park on.
  # `open 0.6` draws the panel 60% of the way along that travel.
  door id=d_wet barn on w_wet at 1500 width 800 swing in slide right open 0.6

  # The wardrobe. A bifold's two leaves fold toward the `swing` face — out into the
  # galley, because there is nothing behind them to fold into.
  door id=d_ward bifold on w_ward at 1000 width 1600 swing out

  # ---- windows --------------------------------------------------------------
  window id=n_galley at (700,0)     width 900  wall shell   # over the sink
  window id=n_bed    at (3700,0)    width 1200 wall shell   # over the bed
  window id=w_gable  at (0,1400)    width 900  wall shell
  window id=s_bench  at (4300,2800) width 1200 wall shell
  window id=e_wet    at (7000,1500) width 600  wall shell

  # ---- galley: three catalogued fixtures, no coordinates --------------------
  # `offset` is the distance of the piece's CENTRE along shell segment 0 — the north
  # run, walked from (0,0) — and the footprints come from the catalogue, so no width,
  # depth or wall face is written down twice.
  furniture kitchen_sink against wall shell segment 0 offset 500  in r_main
  furniture stove        against wall shell segment 0 offset 1200 in r_main
  furniture fridge       against wall shell segment 0 offset 1800 in r_main

  # ---- wet room -------------------------------------------------------------
  # Anchored to the room and `flush`, so each piece measures from the backing wall's
  # inner face rather than from a half-thickness someone worked out by hand.
  furniture shower in r_wet anchor top-left    flush size 900x900
  furniture wc     in r_wet anchor bottom-left flush size 400x700

  # The basin is the one fixture placed by coordinate, and therefore the one that has to
  # state its own quarter-turn. `rotate 0` means "back to the north", so `rotate 90` puts
  # this basin's back on its EAST edge — against the shell, in the south-east corner the
  # shower does not take. Note the declared `size` is always the plan-axis footprint:
  # the symbol turns inside it, the rectangle does not.
  furniture basin at (6450,2100) size 450x600 rotate 90 in r_wet

  # ---- living / sleeping ----------------------------------------------------
  furniture bed      at (2600,100)  size 2000x1400 label "Bed"      in r_main
  furniture bench    at (3400,2100) size 1500x600  label "Bench"    in r_main
  furniture wardrobe at (100,2350)  size 1800x350  label "Wardrobe" rotate 180 in r_main
  # The loft ladder's hatch, flush to the wet-room partition. 600 wide because a label
  # is drawn INSIDE its own footprint: "Ladder" does not fit a 350 mm box, and the
  # renderer has no metrics to shrink it with — it would simply run out over the wall.
  furniture ladder   at (4650,100)  size 600x700   label "Ladder"   in r_main

  # ---- dimensions -----------------------------------------------------------
  # Hand chains rather than `dims auto`: on a plan this small the automatic GB/T set
  # would out-draw the building. Endpoint ORDER picks the side — the line is offset
  # along the LEFT normal of from->to — so each of these is written in the direction
  # that throws it out into the margin. The clear dim carries no `text`: the whole point
  # is that 1850 is measured off the two wall faces, not typed in by the author.
  dim clear (200,0)->(200,2000) offset 600
  dim faces (0,2800)->(7000,2800) offset 500
  dim faces (7000,2800)->(7000,0) offset 500

  # ---- the eaves --------------------------------------------------------------
  # `shell` is the plan's one closed exterior ring, so no `wall` clause is needed to
  # disambiguate it. A micro-home wears its roof close: 400 mm, not the 600 a suburban
  # bungalow shades its glazing with.
  roof overhang 400

  title {
    project "Tiny House"
    drawn_by "ArchLang"
    date "2026-08-16"
  }
}

Read more