Skip to main content

building.place_object

Overview

  • [Build Mode Only] Places a NEW object from the Object data table onto the current site, through the build undo/redo stack (revert with building.undo). Call build.get_site_info first and read its 'build_rules' - it states the coordinate space, the rotation space and the wall auto-alignment this command assumes. This is the only way to add furniture to an empty site - building.move_object / copy_object / put_in_inventory all require an existing entity_id. Find valid ids with data.list_rows --alias=Object, and inspect one (display name, category, price, asset) with data.table_get --alias=Object --row=. COORDINATES are in centimetres with the origin (0,0) at the site's MINIMUM CORNER; the usable range is 0..site_size from build.get_site_info 'coord_space'. Do NOT use 'site_half_extent' as the full size. SLOT SNAPPING (snap=true, default): after placing, the object is attached to a free compatible slot of an OVERLAPPING object, using the same engine path as the in-game magnet. This is how a dining chair becomes a table chair - without it the chair is only a standalone seat and 'eat together at the table' interactions never appear. Detection is by COLLISION OVERLAP, not by radius: place the chair so its box actually touches the table, then check 'snapped' in the response. When it snaps, the slot decides the final position and rotation, so 'yaw' is overridden - and so are applied_x/applied_y/applied_z, which report the position REQUESTED of the engine, not where the slot ended up putting the object. Whenever 'snapped' is true, read the real final transform back with build.scan_objects. YAW IS SITE-RELATIVE, like x and y. Sites are rotated against the world (one measured at 174.5 degrees), and everything you can query - walls, rooms, floors - lives in site space, so yaw=0 means 'parallel to the site axes', not 'parallel to the world axes'. The response reports both applied_yaw (site) and applied_world_yaw. Which way the object visually faces also depends on how its mesh is authored - measured on Chair03, yaw=0 seats face -Y (the backrest faces +Y). Prefer snapping over hand-computed yaw for slotted furniture. DOORS AND WINDOWS are aligned for you: give any x/y NEAR the wall and the command snaps the object onto that wall's centre line, turns it to lie ALONG the wall (the only two valid facings differ by 180 degrees, which is what 'flip' picks between), and cuts the opening. This is required, not a convenience - the engine only cuts an opening when the object sits within 0.1cm of the wall centre line, which is at 25*k+12.5cm, so hand-picked round coordinates never work. Use 'flip' to choose which of the two valid facings it takes, and 'max_wall_distance' to widen or tighten the search. If no wall is close enough the call FAILS instead of leaving a door floating in mid-air; pass allow_free_place=true to override that. When you omit 'z', a door is put on the wall bottom and a window at a 90cm sill. Check 'wall_aligned', 'wall_edge_key', 'wall_opening' and 'applied_yaw' in the response. STAIRS AND LADDERS are quantised to 90 degrees, because their floor/ceiling hole is cut on an axis-aligned grid and a diagonal placement would gouge a much larger hole than the object. The value actually used comes back as 'applied_yaw'. Note that this command does NOT reproduce the in-game ghost preview's stair fitting (AB1BuildModeStairs), so the stairs keep their default rise: place them where the upper floor is one storey up. The object's price is charged to the household wallet and refunded by building.undo. Requires phase == 'ready' (see build.get_mode_state).

Metadata

FieldValue
DisplayPlace Object
Categorybuilding
AccessScriptCheat
ScopeB1Standalone
TagsExperimental
Aliases—

Parameters

NameTypeRequiredDefaultDescription
object_table_idnameyes—Object data table row id, e.g. MedicalKit01 (from data.list_rows --alias=Object)
xfloatyes—X in CENTIMETRES from the site min corner (0..site_size.x; see build.get_site_info coord_space). For a door or window an APPROXIMATE value is fine - it is snapped onto the nearest wall centre line for you.
yfloatyes—Y in CENTIMETRES from the site min corner (0..site_size.y). For a door or window an APPROXIMATE value is fine - it is snapped onto the nearest wall centre line for you.
zfloatno—Z in cm above the site origin plane (default 0). Omit for doors/windows and a wall-appropriate height is chosen instead (door: wall bottom, window: 90cm sill).
floor_levelintno0Floor level to place on (same name as build.scan_walls / build.scan_floors)
yawfloatno0SITE-RELATIVE Z rotation in degrees (+yaw turns site +X toward site +Y), the same space as x/y. yaw=0 is parallel to the site's own axes, so it lines up with axis-aligned walls even though the site itself is rotated in the world. Ignored when the object snaps into a slot or is aligned to a wall; quantised to 90 degrees for stairs and ladders.
scalefloatno1Uniform scale (must be positive)
snapboolnotrueAttach to a free compatible slot of an overlapping object (in-game magnet behaviour). Set false to force a standalone free placement.
flipboolnofalseFor doors/windows: take the opposite of the two valid facings (adds 180 degrees to the wall normal).
max_wall_distancefloatno200For doors/windows: how far (cm) x/y may be from a wall centre line and still snap onto it. 0 disables the distance limit.
allow_free_placeboolnofalseFor doors/windows: place at the raw x/y even when no wall is found, accepting that no opening is cut. Off by default because the result is always visually broken.
assembled_parts_00intno0Assembled part variant index 0 (for modular objects)
assembled_parts_01intno0Assembled part variant index 1
assembled_parts_02intno0Assembled part variant index 2

Usage

await inzoi.cli.execute('building.place_object', {
object_table_id: '',
x: 0.0,
y: 0.0,
z: 0.0, // optional
floor_level: 0, // optional
yaw: 0, // optional
scale: 1, // optional
snap: true, // optional
flip: false, // optional
max_wall_distance: 200, // optional
allow_free_place: false, // optional
assembled_parts_00: 0, // optional
assembled_parts_01: 0, // optional
assembled_parts_02: 0, // optional
});