Prompt the Construct agent

Drive 3D scene editing with OPAL chat

When you open the OPAL chat inside Construct, the assistant has direct access to the scene. Good prompts make the difference between a quick edit and a frustrating round trip. This page collects the patterns that work.


What the agent can do

The Construct agent operates through a fixed set of tasks. It cannot run arbitrary code, click UI buttons, or read files outside the scene. Available tasks fall into a few groups:

  • Build — Create a whole SDF tree atomically. Tasks: construct.scene.build_tree.
  • Item editing — Add, rename, move, duplicate, reparent. item.add adds an SDF item, a group, a null object, a camera, bounds or a reference. Tasks: construct.item.add, item.rename, item.set_transform, item.duplicate, item.set_parent.
  • Selection and grouping — Select items in the tree and the viewport, group them as one undo step, dissolve a group. See selection and grouping tasks. Tasks: construct.scene.set_selection, scene.get_selection, scene.group_selection, scene.ungroup.
  • Visibility — Hide an item (add the tag) or show it (remove the tag). The same undoable step as a click on the item's icon in the tree. Tasks: construct.item.set_tags with the tag hidden.
  • SDF parameters — Tweak primitive/operator inputs. Tasks: construct.sdf.set_parameter, sdf.set_all_parameters, sdf.set_definition.
  • Definitions — Write a primitive or a transform operator in GLSL for this document, change or remove it, read one, check one, and copy it to your user library. definition.get returns the record text with its comments as source; add and update take that text as source, and definition.validate reports each problem with its tab and line. A transform operator can ship an inverse; scene.list_definitions reports whether the editor accepted it. See Write a transform operator. Tasks: construct.definition.add, definition.update, definition.remove, definition.get, definition.validate, definition.publish.
  • Definition editor — Drive the editor window you see: open a definition in it, read what it shows (state includes the validation and the preview statistics), edit a value or a tab, save, revert, and turn the preview camera. Save of a built-in definition and delete take confirm: true. See Edit an SDF definition. Tasks: construct.definition_editor.open, definition_editor.state, definition_editor.edit, definition_editor.save, definition_editor.revert, definition_editor.new, definition_editor.duplicate, definition_editor.delete, definition_editor.camera.
  • Materials — Manage the material library. Tasks: construct.material.add, material.update, material.duplicate, material.list.
  • Rendering — Read what the viewport renders and how far it has refined, choose the viewport mode (Clay, Engineering, Presentation or one of your own), pause and resume the refinement, and queue a render to a file. See Construct render tasks. Tasks: construct.render.status, render.set_shading, render.pause, render.resume, render.export.
  • Variables — Author parametric variable sets. Tasks: construct.varset.set_variable, varset.add_named, varset.reorder.
  • Settings — Read and adjust the settings of the open scene or a camera by id, including the path tracer's budget (ptMaxSamples, ptMaxBounces, ptSecondarySteps, ptSecondaryEpsilon, ptRenderScale, ptTimeBudgetMs, ptStepsPerSubmit, ptMinSamples, ptNoiseThreshold, ptViewportNoiseThreshold, ptViewportMaxSamples, ptMaxGlossyBounces, ptMaxTransmissionBounces, ptFireflyClamp, ptEnvironmentNee). See Config OPAL tasks. Tasks: config.get, config.set, config.set-bulk, config.revert, with schema: "construct".
  • Queries — Read scene state before acting. definition.get returns a definition's full GLSL source, so the agent can explain how any primitive or operator works. scene.get_item also returns the item's place in the scene (world) and, for a mesh or another non-SDF child of an SDF item or a group, whether Construct could place it (leaf). Tasks: construct.scene.list_items, scene.get_item, scene.search_items, scene.list_definitions, definition.get, material.list.
  • Bounding volumes — Frame regions, measure geometry, export meshes. Tasks: construct.bounds.list, bounds.add, bounds.set, bounds.fit, bounds.activate, bounds.remove, bounds.export.
  • Batches — Inspect and undo previous agent batches. Tasks: construct.list_batches, construct.undo_batch.
  • Diagnostic reports — When you describe a defect, or a task fails with an internal error, the agent offers a report. create collects the files with the agent's summary, and its own notes with attach. compose opens the report window. The agent never sends a report: only you press Send. See Diagnostic reports. Tasks: diagnostics.report.create, diagnostics.report.compose.

You don't need to memorize these — the agent already knows them. Treat the list as a sanity check when a request feels close to "what tasks does it have?"

Pro Tip

If a request has no matching task, the agent will tell you — it will not pretend. If it ever invents a task name, that's a bug worth reporting.


Patterns that work

1. Describe geometry, not steps

Prefer the goal, not the procedure:

Less effective More effective
"Add a sphere. Then a box. Then union them." "Make a soft union of a sphere and a box, smoothness 0.4."
"Add 8 spheres in a circle." "Make a ring of 8 spheres around the Y axis, radius 3, sphere radius 0.5."

The agent prefers building a whole tree at once via construct.scene.build_tree because that lands as a single undoable batch. Step-by-step prompts force individual ops which are noisier and harder to undo cleanly.

2. Be explicit about parameters

The agent has reasonable defaults but cannot read your mind. Numbers help:

"Smooth subtract a torus (major 2, minor 0.5) from a box (3×1×3) with smoothness 0.3."

Vague phrasing ("a small torus") may produce something that looks wrong. Iterate by quoting the parameter you want to change.

3. Query before you mutate complex scenes

If the scene already has dozens of items, ask the agent to list or search first:

"List all items, then rename the one called 'Ball' to 'Hub'."

The agent will run a query task, see the actual UUIDs/names, and then issue a safe mutation. This avoids referencing items that don't exist.

4. Reference items by name when you can

Names survive across edits; UUIDs don't read well in chat. Either set names when you create things ("name it 'arm_base'") or refer to existing names ("the item called 'cap'"). The agent will resolve names to IDs internally.

5. Iterate, don't retry verbatim

If a result is wrong, describe the difference rather than restating the whole prompt:

"Make the smoothness 0.5 instead of 0.3." "Move the ring up by 0.5 along Y."

The agent keeps conversation context, so deltas are usually all it needs.

6. Use bounding volumes for regions, measurement and export

The construct.bounds.* tasks make regions first-class for the agent:

"Add a bounding volume named 'bed' fitted to the scene, then export it to /tmp/bed.stl."

construct.bounds.list is the discovery call — it returns every volume's name, extents, parent, flags and stored expressions, so the agent can act without a second query. bounds.fit measures the real surface (the same detector the editor's fit buttons run), which makes it the reliable way to ask "how big is this actually?".

Value fields on bounds.set accept expressions as well as literals — {"sizeExpression": "[$width, $depth, 20]"} keeps the box parametric, and a later bounds.list returns the expression verbatim, so set-then-verify round trips.

7. Rig with null objects

A null object is a point with no geometry that holds other items. Ask for the motion, and the agent builds the rig from nulls, parenting and an expression, with no special tool:

"Make a turntable of the wheel: the camera 6 units out and 1 up, one turn over the frame range."

The agent adds a null at the middle of the wheel, puts the camera under it, and sets the null's rotate to =vec3(0, (anim.frame - anim.first) / (anim.last - anim.first + 1) * 360, 0). The camera goes around in the viewport and in a rendered video. The same works for any item under a null or a group: an expression on the parent's transform moves everything it holds. See Make a turntable video.


What the agent will not do

  • It will not invent tasks. If your request requires something Construct doesn't expose (e.g. arbitrary mesh sculpting), the agent will say so. Take that as a real signal, not a hint that you should rephrase.
  • It will not silently swallow failures. If a step fails, the response says which steps succeeded and which failed before it proposes a fix.
  • It will not click UI for you. OPAL drives the model directly; it does not poke buttons. Anything that lives only in a UI dialog (e.g. exporting a mesh) is currently out of scope.
  • It will not read or write files outside the scene unless a specific task is granted that permission.

Undo and the agent

Every agent edit goes through Construct's unified undo stack — the same one Ctrl+Z drives.

  • A build_tree call lands as one undoable batch, no matter how many instances it created. One Ctrl+Z removes the whole tree.
  • A multi-step plan ("add a box, then a sphere, then union them") lands as multiple steps. You can either Ctrl+Z each, or ask the agent to undo_batch the whole thing.
  • After agent actions, the scene is left in a dirty state, so the title-bar dot appears and Save still works as expected.

See Undo & redo in Construct for details.


Permission modes

The OPAL chat has a permission dropdown that controls how aggressive the agent is allowed to be:

Mode Behavior
Ask Every mutating task asks for approval before it runs.
Safe auto Read-only and reversible mutating tasks run automatically; risky ones still ask.
All auto All tasks run without asking.

Start in Ask until you trust your prompts, then promote to Safe auto for routine work. There's no mode that bypasses Construct's undo stack — agent edits are always reversible.


When something goes wrong

If a task plan fails partway through, the response will list what succeeded and what didn't. Common fixes:

  • "Definition 'foo' not found" — ask the agent to list_definitions to see what's actually available.
  • "Cycle detected in children references" — your tree references itself; rename one of the offending instances.
  • "Item not found" — the UUID changed (e.g. you reverted a change). Ask the agent to list_items and retry with the new ID.
  • Plan refused / "Submit exactly ONE task plan per response" — the agent tried to split work across messages. Ask it to combine everything into a single plan and try again.

If you keep hitting the same wall, see Troubleshoot errors for provider-side issues.

Topics
howto LLM OPAL construct prompting
See also