GitHub - ch-bas/threejs-sims-house-builder: A browser-based 3D house builder inspired by The Sims. Design multi-floor homes with furniture, walls, roofs, and walkthrough mode. Built with Three.js + Next.js.

GitHub

4 min read Original article ↗

A lightweight, open-source Sims-like house builder built entirely in the browser using Three.js.

This repository provides a polished, grid-based architecture and interior design system featuring wall patterns, floor styles, modular stairs, and dynamic UI panels.

Built with Next.js 15, React 18, Three.js, and Tailwind CSS. No backend, no authentication — everything runs client-side.

app/                                     Next.js entry (+ error / global-error boundaries)
components/
├── ui/                                  shadcn-style primitives
└── room-organizer/
    ├── room-organizer.tsx               Orchestrator (~850 lines)
    ├── index.ts                         Barrel export
    ├── contexts/                        React Context (eliminates prop drilling)
    │   ├── room-editor-context.tsx      Layout, actions, view, history, game state
    │   ├── selection-context.tsx        Selected item(s), multi-select, selectOnly()
    │   └── index.ts                    Barrel
    ├── lib/                             Pure domain code, no React/Three
    │   ├── types.ts                     RoomLayout / FloorLayout / ViewSettings / etc.
    │   ├── constants.ts                 Catalog (68 items), templates, MAX_FLOORS
    │   ├── schema.ts                    Type guards + legacy migration
    │   ├── geometry.ts                  Collision, bounds, snap, auto-organize
    │   ├── alignment.ts                 Align/distribute pure functions
    │   ├── achievements.ts              15 predicate-based achievements
    │   ├── cctv-models.ts               Real-world CCTV model specs for cameras
    │   ├── persistence.ts               Active-layout localStorage I/O + unreadable-save recovery backup
    │   ├── library.ts                   Named-layout library I/O
    │   ├── share.ts                     Share-URL encode/decode (base64url)
    │   ├── blueprint.ts                 Print-friendly 2D blueprint HTML
    │   ├── catalog-drag.ts              HTML5 drag MIME constants
    │   ├── themes.ts                    Theme definitions + applyTheme
    │   ├── furniture-sets.ts            Pre-built combos
    │   ├── surprise.ts                  Random one-shot floor populate
    │   ├── sounds.ts                    Web-Audio synth for UI cues
    │   ├── wall-snap.ts                 Vertex + right-angle snap for interior walls
    │   ├── opening-snap.ts              Door/window snap + shared wall-mount settle rule
    │   ├── room-shapes.ts               Predefined room shape presets
    │   └── file-io.ts                   JSON / image / PNG / CSV / GLB I/O
    ├── three/                           Three.js builders, no React
    │   ├── furniture-builders.ts        Registry + factory (~110 lines)
    │   ├── builder-utils.ts             Shared types + mesh()/material() helpers
    │   ├── drag-handlers.ts             Canvas mouse events: select/drag/hover/wall-pick
    │   ├── builders/                    Per-category builder functions
    │   │   ├── builders-seating.ts      Chair, armchair, bench, sofa
    │   │   ├── builders-bedroom.ts      Bed, nightstand, dresser
    │   │   ├── builders-tables.ts       Table, desk, coffee/side/dining
    │   │   ├── builders-storage.ts      Bookshelf, cabinet
    │   │   ├── builders-kitchen.ts      Fridge, stove, sink, counter
    │   │   ├── builders-bathroom.ts     Toilet, bathtub, shower
    │   │   ├── builders-electronics.ts  TV, computer, WiFi, router, CCTV
    │   │   ├── builders-lighting.ts     Lamp, pendant, lamppost
    │   │   ├── builders-decor.ts        Rug, painting, vase, mirror, etc.
    │   │   ├── builders-plants.ts       Plant, tree, flowers, hedge, etc.
    │   │   ├── builders-outdoor.ts      Fence, pool, BBQ, mailbox, etc.
    │   │   ├── builders-people.ts       Person, pet
    │   │   └── builders-structure.ts    Door, window, stairs
    │   ├── room-builder.ts              Floor + walls (yOffset, ghosting)
    │   ├── wall-openings.ts             Door / window → exterior wall cutouts
    │   ├── interior-walls.ts            Drawn-segment interior walls with cutouts
    │   ├── measurement.ts               Distance-tool spheres + line
    │   ├── item-labels.ts               Floating sprite labels above items
    │   ├── roof.ts                      Flat / gable / hipped roof
    │   ├── floor-patterns.ts            Procedural CanvasTexture floors
    │   ├── wall-patterns.ts             Procedural CanvasTexture walls
    │   ├── texture-lru.ts               LRU cache for texture masters (evict + dispose)
    │   ├── signal-overlay.ts            Wi-Fi / CCTV ring overlays
    │   ├── camera-vision.ts             Directional CCTV vision-cone overlays
    │   ├── lighting.ts                  Sun-arc continuous time of day
    │   └── outdoor.ts                   Garden / path / bush scenery
    ├── canvas-2d/render.ts              Pure 2D top-down renderer
    ├── plotcraft/icon.tsx                Lucide-react icon wrapper for UI panels
    ├── hooks/
    │   ├── layout-reducer.ts            Action union + reducer (withActiveFloor)
    │   ├── use-layout-store.ts          Zustand store (reuses the reducer) + selectors
    │   ├── use-layout-state.ts          Adapter over the store (activeFloor, actions)
    │   ├── use-three-scene.ts           Renderer / controls / RAF lifecycle
    │   ├── use-scene-effects.ts         Keyed scene-rebuild effects
    │   ├── use-item-drag.ts             Drag fast-path + camera wall-seat on drop
    │   ├── use-item-placement.ts        Snapping + wall-aware catalog placement
    │   ├── use-import-export.ts         Screenshot / GLB / share link / JSON import
    │   ├── use-walkthrough.ts           PointerLock + WASD movement
    │   ├── use-npcs.ts                  Animated wandering pedestrians
    │   ├── use-camera-presets.ts        Iso/top/front/corner + fit + focus
    │   ├── use-camera-vision.ts         Vision-cone sweep animation loop
    │   ├── use-history.ts               Snapshot undo/redo
    │   ├── use-achievements.ts          Diffed unlock detection
    │   ├── use-recent-colors.ts         Persisted LRU colour palette
    │   ├── use-keyboard-shortcuts.ts    Centralised key handling
    │   └── use-layout-persistence.ts    Hydrate (share → local) + auto-save + cross-tab notice
    └── panels/                          Presentation (most use context)
        ├── lot-badge.tsx                Top-left lot name + sidebar toggle
        ├── sidebar-drawer.tsx           Full sidebar with 4-tab panel layout
        ├── sidebar-tabs.tsx             Build / Buy / Style / Manage tabs
        ├── build-tools-panel.tsx        Bottom-left glass panel (categories + mode)
        ├── catalog-strip.tsx            Bottom-centre drag-source tile row
        ├── mode-panel.tsx               Bottom-right LIVE / BUILD / BUY + stats
        ├── item-context-popover.tsx     Floating per-item editor on selection
        ├── color-swatch-picker.tsx      Shared swatch + recent-colours picker
        ├── slider-row.tsx               Shared label + range + readout row
        ├── floor-switcher.tsx
        ├── walls-panel.tsx
        ├── roof-panel.tsx
        ├── room-settings-panel.tsx
        ├── furniture-catalog-panel.tsx
        ├── placed-items-panel.tsx
        ├── item-resize-panel.tsx
        ├── align-panel.tsx
        ├── templates-panel.tsx
        ├── themes-panel.tsx
        ├── library-panel.tsx
        ├── sets-panel.tsx
        ├── statistics-panel.tsx
        ├── header-stats.tsx
        ├── time-of-day-panel.tsx
        ├── camera-presets-panel.tsx
        ├── camera-pad.tsx
        ├── floor-pill.tsx
        ├── room-shapes-panel.tsx
        ├── wall-display-pill.tsx
        ├── wall-paint-panel.tsx
        ├── actions-panel.tsx
        ├── shortcuts-panel.tsx
        ├── welcome-banner.tsx
        ├── minimap.tsx
        ├── achievements-panel.tsx
        ├── achievement-toast.tsx
        └── viewport.tsx