---
title: "57 3D Furniture Assets and a Placement System in 24 Minutes"
description: "Talos built 57 consistent 3D furniture assets, a 14×14 m two-storey villa and a drag-and-drop placement editor from three spec-driven prompts in 24 minutes."
canonical: https://taloswork.ai/en/blog/3d-furniture-system
language: en
last_updated: 2026-10-19
---

# 57 3D Furniture Assets and a Placement System in 24 Minutes

![01 prompt](../../assets/images/blog/3d-furniture-system/01-prompt.webp)

## Project background

In home DIY and management simulation games, the amount of content is almost equal to the number of assets, and you also need a set of placement rules so that furniture can be placed correctly. Doing this entire set by hand (57 assets + a two-storey villa + a placement system + an editor) was estimated to take more than a week. With Talos, this run produced 57 3D assets, a 14×14 m two-storey villa and a drag-and-drop editor in 24 minutes.

![02 deliver](../../assets/images/blog/3d-furniture-system/02-deliver.webp)

## The challenge

This kind of task has two difficulties. The first is asset consistency: dimensions, pivots and orientation must be uniform, otherwise assets will float or intersect once they are in the engine, and fixing dozens of them by hand one at a time is slow. The second is the correctness of the placement rules: get support surfaces, overlap, out-of-bounds or cross-floor snapping wrong in one place, and the result is a lamp floating in mid-air or a second-floor desk snapping to a first-floor countertop.

General-purpose modeling tools give you model files, but not the structured data that comes with precise dimensions, support surfaces and mounting methods. The goal here was a set of assets and rules that a program can call directly and that check themselves.

![03 editor](../../assets/images/blog/3d-furniture-system/03-editor.webp)

## Approach

### Step 1: Specify the requirements across three rounds

In this run, the intent of each round was written as a prompt with constraints and acceptance criteria, and the work proceeded in three rounds. The full specifications are below and can be reused as they are.

### Round 1 · Set up the project, define the spec, produce the first asset batch

```
[Role] Senior game 3D asset pipeline engineer.
[Goal] Produce a set of 3D furniture assets for a home DIY game that can go straight into the engine.
[Technical approach]
Generate models procedurally in Python (trimesh + numpy). Do not use Blender and do not produce .blend files.
Add no dependencies beyond trimesh and numpy. Every asset must be reproducible by script.
[Asset spec (every asset must satisfy this, no exceptions)]
- Unit 1 = 1 meter; Y axis up
- Pivot at the center of the horizontal bounding box; local y = 0 is the lowest point of the object itself
- Front faces +Z; with a 0° rotation around Y, the front faces the camera
- Grid snap 0.25 m
- Materials are flat-color PBR (metalness/roughness), no textures; material names are shared across assets so the whole set can be recolored together
- Node name format <assetkey>__<materialkey>
- Dimensions follow real furniture proportions, and the visual geometry must match the declared dimensions exactly (the engine uses the manifest directly for collision)
[First batch] 22 assets
Seating 4, tables 3, storage 4, bedroom 2, kitchen 1, decor 2, lighting 2, room shell 4
[Deliverables]
- One GLB per asset
- manifest.json: dimensions, footprint grid, material names, triangle count
- An asset-pack overview GLB and an isometric preview image
- README: spec notes and how to add new assets
[Acceptance]
Self-checks must be all green: sits on the ground (lowest point exactly y=0), pivot centered, no floating parts, every part a closed manifold,
declared dimensions match measured geometry, GLB can be read back with node and material names intact.
[Working method]
Define the spec and tooling first, then produce assets in batches. Run the full self-check at the end of each batch; it is only done when everything is green.
```

### Round 2 · Add the placement system and the room editor

```
[Goal for this round] Turn static assets into an interactive placement system and build a room editor.
[Room as data]
Define the room as data rather than hard-coding it: interior clear dimensions, number of floors, wall height and slab thickness become parameters.
Walls, floor tiles, slabs and doors are laid out automatically from the dimensions. Change a number and the whole room regenerates.
[Placement rules] The order of checks is fixed; rules are written as pure functions shared by the generation side and the editor
1. Plan bounds: the overall bounding box must lie inside the placeable area of the current floor
2. Occupied zone: must not cover the stairs or the slab opening
3. Clearance: object height must not exceed the ceiling of the current floor
4. Overlap: objects on the same floor at the same height must not overlap in footprint (floor coverings such as rugs excepted)
[Mount semantics] Every asset declares placement and mount_y
- floor: pivot at (x, current floor level, z); check support-surface snapping first, drop to the floor if there is nothing to snap to
- wall: y = current floor level + mount_y; the overall bounding box is set flush against the inner face of the wall
- ceiling: y = current floor level + mount_y; x/z are used directly
mount_y is relative to the current floor level (not world height). Support snapping must be limited to the same floor.
[Editor] Single-file HTML with models and manifest embedded; double-click to open
Click to place, drag to snap at 0.25 m, R key to rotate 90°, Delete to remove, scroll wheel to zoom, right-drag to orbit;
dragging onto the top of furniture snaps to the surface height, dragging off drops back to the floor;
illegal positions are highlighted in red and the object returns to its original position on release;
export the layout as JSON — this is the save format the engine will store;
built-in placement-rule self-check that runs automatically when the page opens.
[Acceptance]
The editor self-check is all green and matches the Python-side result; every item in the sample room is judged legal and support heights are self-consistent.
```

### Round 3 · Scale up, add a floor, add recoloring

```
[Changes in this round]
1. Room: floor area increased about 10× → 14 × 14 m per floor
2. Floors: now two floors, floor-to-floor height 2.90 m (wall height 2.80 + slab 0.10)
Add slabs, a straight-run staircase, the slab opening and opening railings
Stair rise must equal the floor-to-floor height; slabs must cover the full area and the opening must sit exactly over the stairs
3. Assets: add 35
Bathroom 6 (bathtub, shower enclosure, toilet, washbasin, mirrored cabinet, towel rack)
Kitchen 5 (refrigerator, countertop stove, range hood, wall cabinet, kitchen island)
Storage and study 8 (chest of drawers, filing cabinet, folding screen, floor mirror, child's bed, desk, office chair, bench)
Lighting and decor 7 (ceiling light, pendant light, wall light, wall clock, framed picture, vase, large potted plant)
Living room and other 5 (L-shaped corner sofa, side table, television, shoe cabinet, coat rack)
Structure 4 (slab, staircase, railing, corner column)
Wall-mounted and ceiling-mounted items declare their mounting height with mount_y; ceiling items must satisfy mount_y + height = floor-to-floor height
4. New capability: color DIY
Recolor a single item (per material slot)
Recolor a whole palette (change every material with the same name throughout the house)
Recolor results export with the layout JSON
[Unchanged] Asset spec, placement check order, mount semantics, deliverable format, acceptance criteria
[Acceptance] Self-check all green; house cross-validation passes; editor and Python results agree
```

Together, the three prompts locked down four things:

- Asset spec: units, pivot, orientation, grid, material naming and node naming. Fix these once and every asset lines up automatically.
- Placement semantics: three mounting types — floor, wall and ceiling — plus the rule that support snapping only looks at the same floor.
- Acceptance criteria: self-checks must be all green, and the editor and Python results must agree.
- Change boundaries: round 3 spells out what stays "unchanged", so conventions that already line up are not rewritten along the way.

### Step 2: Talos generates and self-checks

Talos then carried out the following steps:

1. Confirm the technical approach and establish the spec: unit of 1 meter, Y axis up, pivot at the center of the base, front facing +Z, 0.25 m grid snapping — binding on every asset.
2. Dispatch four asset groups in parallel: bathroom, kitchen, storage/study, and lighting/decor, 31 new pieces in total, each generated independently and then merged into the asset library.
3. Extract the placement rules into a standalone module: the decision logic (dimension conversion, overlap detection, support snapping, bounds and clearance) written as pure functions shared by the generation side and the editor.
4. Build and render: output 57 GLB files, the asset manifest, the two-storey villa scene and preview images.
5. Self-check and fix: all 11 Python-side check categories and all 15 editor self-checks passed; during the run the self-check reported that "the second-floor desk snapped to the first-floor kitchen countertop", which was traced to support snapping not filtering by floor, and fixed.

The whole run took about 24 minutes.

### Step 3: Output structure and asset spec

Asset breakdown: 57 items in 11 categories.

| Category | Count | Contents |
| --- | --- | --- |
| Seating | 7 | Three-seat sofa, armchair, dining chair, L-shaped corner sofa, bench, office chair |
| Tables | 5 | Coffee table, dining table, desk, side table, child's desk |
| Storage | 6 | Bedside table, wardrobe, bookshelf, TV stand, chest of drawers, filing cabinet |
| Kitchen | 6 | Kitchen cabinet, refrigerator, countertop stove, range hood, wall cabinet, kitchen island |
| Bathroom | 6 | Bathtub, shower enclosure, toilet, washbasin, mirrored cabinet, towel rack |
| Bedroom | 3 | Double bed, single bed, child's bed |
| Entryway | 2 | Shoe cabinet, coat rack |
| Decor | 9 | Rug, potted plant, large potted plant, television, folding screen, floor mirror, wall clock, framed picture, vase |
| Lighting | 5 | Floor lamp, table lamp, ceiling light, pendant light, wall light |
| Structure and floors | 4 | Slab, staircase, railing, corner column |
| Room shell | 4 | Wall segment, floor tile, door leaf, window frame |

About 23,000 triangles in total, 1.1 MB of GLB in total.

The house itself is data too: each floor of the two-storey villa is 14×14 m with a floor-to-floor height of 2.90 m, and walls, floor tiles, slabs, stairs, railings and doors are all laid out automatically from dimension parameters — 510 shell components in total.

Placement rules: every asset carries its dimensions, protrusion, support surfaces and mounting method in the manifest, and checks run in a fixed order.

| Check order | Rule |
| --- | --- |
| 1 | The overall bounding box must lie inside the placeable area of the current floor |
| 2 | Must not cover the stairs or the slab opening |
| 3 | Object height must not exceed the ceiling of the current floor |
| 4 | Objects on the same floor at the same height may not overlap in footprint (floor coverings such as rugs excepted) |

There are three mounting types: floor items snap to support surfaces first, while wall and ceiling items position themselves automatically at their declared mounting height. Wall-mounted items dragged near a wall attach to it automatically and turn to face into the room.

Color DIY: material names are shared across assets; recoloring a single item applies per material slot, and a whole palette can recolor every material with the same name throughout the house in one click. Recolor results export together with the layout JSON.

## Results

| Metric | Manual production | Talos | Change |
| --- | --- | --- | --- |
| Total time | More than a week (estimate) | 24 minutes | About -99% |
| Asset count | 57 | 57 | Same |
| Dimension and pivot consistency | Must be checked item by item | Enforced by self-check | More reliable |
| Placement rule validation | Hand-written test cases | 26 self-checks across both sides | Automatic |
| Output format | Model files | GLB + structured manifest + drag-and-drop editor | Ready to integrate |
| Reusability | Remodel from scratch each time | Change parameters for a new variant | High |

In 24 minutes, Talos produced 57 3D assets under a uniform spec, a two-storey villa and a drag-and-drop editor. All 11 Python-side check categories and all 15 editor self-checks passed, with the editor self-check running automatically when the page opens. (Data as of October 2026.)

## Business impact

- Output per run: instead of "write the spec, then model item by item", the sequence becomes "establish the spec, then generate in batches". The spec is enforced by code, so the team no longer relies on manual review to catch floating assets and off-center pivots.
- Cost of scaling: adding a new piece of furniture means writing one function; it automatically enters the asset library, manifest, editor and collision checks. New variants are a parameter change, so marginal cost is low.
- Rule correctness: with placement checks extracted into a standalone module, the generation side and the editor run the same rules and the same self-checks. If either side is wrong, the other reports it first.
- Engine integration: the asset manifest carries dimensions, support surfaces and mounting methods, so the engine side can implement the placement system without adding hidden parameters.

## What you can reuse

1. Set the spec before scaling up. Once units, pivot, orientation and grid are fixed, every later asset lines up automatically; skip this step and you will be redoing dozens of items.
2. Put acceptance criteria in the prompt. Once "all self-checks green" is written down, the completion signal becomes decidable and you do not have to re-align on what counts as done every round.
3. When adding requirements, state explicitly what stays unchanged. Draw the boundary and the scope of change stays controllable.
4. Require the same self-checks on both sides. When the generation side and the runtime side each have their own validation, the side that errors first is often the one that is right.

## FAQ

**Q: Can you make 3D models without installing Blender?**

A: For low-poly structures like boxes, cylinders and lathed forms, yes — all 57 pieces of furniture in this run were generated that way. Organic surfaces (upholstery wrinkles, irregular chair backs) cannot be produced by code alone; they need a modeling tool or a 3D generation model, exported afterwards under the same spec.

**Q: Can the generated assets go straight into Unity or Godot?**

A: Yes. The assets are GLB files with a JSON manifest containing precise dimensions, footprint grid, support surfaces and mounting methods. The engine side only needs to implement placement checks from the manifest, with no need to measure anything.

**Q: Can the room be changed to another layout or size?**

A: Yes. Room dimensions, number of floors and stair position are all parameters; change one number and the entire set of walls, floors and slabs regenerates. The project already includes a small-apartment preset.

**Q: Can these three prompts be reused for other themes?**

A: Yes. The three rounds correspond to "establish the spec and produce the first batch", "add interaction and rules", and "scale up and add capabilities" — a general sequence for asset-based projects. The core is to define the spec and acceptance criteria first, then proceed in batches, each closing with all self-checks green.

## Call to action

With Talos, generate 57 pieces of 3D furniture and a drag-and-drop placement editor in 24 minutes. Try it free at taloswork.ai.
