Skip to main content
Glama

set_properties

DestructiveIdempotent

Write editable properties of assets, CDOs, actors, or components in the editor world, with undoable changes, clamping, optional saving, and a report of what was set or failed.

Instructions

Write one or several editable properties of one object in the editor world, as the Details panel does: an asset, a CDO, a placed actor, one of its components ("Actor.Component") or an asset's sub-object. Each write is undoable, dirties the package and re-registers the component, and the reply lists what was set and what failed, with why.

Use it for any setting of a light, fog, sky, decal, camera, post-process volume, sound, Niagara system, material expression or other asset. Not for: a component in a live PIE world (set_component_property), a Blueprint's component template (set_blueprint_component_properties), a widget inside a Widget Blueprint (set_widget_property), or an object's own setter function (call_function).

Take the property names from get_object_info, and object_path from the tool that found the object: find_assets_by_name for an asset, get_graph_nodes for a graph node, or "Label.ComponentClass" for a placed actor, such as "Sun.DirectionalLightComponent". Example: {"object_path": "Sun.DirectionalLightComponent", "properties": {"Intensity": 10, "LightColor": {"R": 255, "G": 200, "B": 150}}} writes two properties; property_name "Intensity" with value 10 writes one, and both forms together write properties first. A struct takes only the fields to change: {"RelativeLocation": {"Z": 200}} keeps X and Y.

A name can also be a PATH, to write one value deep inside without rewriting what holds it: "RelativeLocation.Z", "Items[2]" or "Items[2].Name" (an existing element; to resize an array, write the whole array), and through an object reference to the object it points to, such as an instanced sub-object: "Layer.Settings.Size". The object holding the last segment is the one written, made undoable and notified with the chain of its segments, as the Details panel does for a nested edit; every segment it holds must be writable, and a reference the path goes through only needs to be visible.

A sub-object's asset is finished as its editor does it: a graph node is reconstructed and its Blueprint marked modified (compile it), a sound cue recaches, a Niagara system recompiles and a blend space is resampled; no Blueprint is compiled. clamp=true keeps numbers inside ClampMin/ClampMax and lists what it clamped. save=true saves an asset's package and is refused for an object in a level, which save_level writes. Refused before anything is written: a struct key that names no field, an unregistered gameplay tag, and any call during Play-in-Editor (see force).

Returns: { object_path: string, resolved_path: string, set: [string], failed: [{property, error}], owning_asset?: string (a sub-object's asset), finished?: [string] (what ran on that asset), clamped?: [string] ("name=value", with clamp), saved?: bool, save_error?: string (with save), success: bool }

Input Schema

NameRequiredDescriptionDefault
saveNoSave the asset's package after the writes (default false); refused, before anything is written, for an object in a level
clampNoClamp each number written to the ClampMin/ClampMax of its property, struct fields and array elements included (default false)
forceNoOptional. This command is REFUSED while a Play-in-Editor session is running: it either compiles a Blueprint (the reinstancer can retain a world, and CheckForWorldGCLeaks is Fatal -- it KILLS the editor) or writes to disk (Editor.AllowSavingAssetsDuringPIE=0 makes the engine refuse the write, so it would report success without writing a byte). Stop PIE and retry instead; force=true runs it anyway, at your own risk.
valueNoOptional new value for property_name: string, number, boolean, JSON object (struct), JSON array (array/set/tag container), or a UE-format text string like "(X=1,Y=2,Z=3)"
propertiesNoOptional dict of {property_name or path: value}; values can be scalar, nested object, or array (UE-format text like "(X=1,Y=2,Z=3)" is also accepted for structs). Required unless property_name + value is given; both together write properties{} first.
object_pathYesThe object, resolved in the EDITOR world: an asset path, a full object path, a CDO/archetype, an asset's sub-object as the readers give its object_path -- a graph node from get_graph_nodes, a sound cue node, a Niagara renderer or simulation stage, a PCG node's settings_path, a behavior tree node, a camera rig node, a Mass trait, a physics body -- also written "/Game/Asset:SubObject", or "Actor[.Component[.Subobject]]" where Actor is an internal name or a unique label and Component a component name or a class only one component has.
property_nameNoOptional single property, or path such as "Items[2].Name", to write (must be CPF_Edit and not EditConst, or it lands in failed[] with the reason). Needs value.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv2.10.0
    • changedInput schema / properties / properties / description
      Previous value: -"Optional dict of {property_name: value}; values can be scalar, nested object, or array (UE-format text like \"(X=1,Y=2,Z=3)\" is also accepted for structs). Required unless property_name + value is given; both together write properties{} first."New value: +"Optional dict of {property_name or path: value}; values can be scalar, nested object, or array (UE-format text like \"(X=1,Y=2,Z=3)\" is also accepted for structs). Required unless property_name + value is given; both together write properties{} first."
    • changedInput schema / properties / property_name / description
      Previous value: -"Optional single property to write (must be CPF_Edit and not EditConst, or it lands in failed[] with the reason). Needs value."New value: +"Optional single property, or path such as \"Items[2].Name\", to write (must be CPF_Edit and not EditConst, or it lands in failed[] with the reason). Needs value."
  2. Changed2 schema fields changedv2.5.0
    • addedInput schema / properties / force
      Added value: +{
      +  "description": "Optional. This command is REFUSED while a Play-in-Editor session is running: it either compiles a Blueprint (the reinstancer can retain a world, and CheckForWorldGCLeaks is Fatal -- it KILLS the editor) or writes to disk (Editor.AllowSavingAssetsDuringPIE=0 makes the engine refuse the write, so it would report success without writing a byte). Stop PIE and retry instead; force=true runs it anyway, at your own risk.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / object_path / description
      Previous value: -"The object, resolved in the EDITOR world: an asset path, a full object path, a CDO/archetype, or \"Actor[.Component[.Subobject]]\" where Actor is an internal name or a unique label and Component a component name or a class only one component has."New value: +"The object, resolved in the EDITOR world: an asset path, a full object path, a CDO/archetype, an asset's sub-object as the readers give its object_path -- a graph node from get_graph_nodes, a sound cue node, a Niagara renderer or simulation stage, a PCG node's settings_path, a behavior tree node, a camera rig node, a Mass trait, a physics body -- also written \"/Game/Asset:SubObject\", or \"Actor[.Component[.Subobject]]\" where Actor is an internal name or a unique label and Component a component name or a class only one component has."
  3. Changed3 schema fields changedv2.3.0
    • addedInput schema / properties / clamp
      Added value: +{
      +  "description": "Clamp each number written to the ClampMin/ClampMax of its property, struct fields and array elements included (default false)",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / object_path / description
      Previous value: -"Path or name of the object instance, resolved in the EDITOR world: full object path, asset path, CDO/archetype, or a dotted \"Actor[.Component[.Subobject]]\" whose first segment is the actor's internal name."New value: +"The object, resolved in the EDITOR world: an asset path, a full object path, a CDO/archetype, or \"Actor[.Component[.Subobject]]\" where Actor is an internal name or a unique label and Component a component name or a class only one component has."
    • addedInput schema / properties / save
      Added value: +{
      +  "description": "Save the asset's package after the writes (default false); refused, before anything is written, for an object in a level",
      +  "type": "boolean"
      +}
  4. Changed3 schema fields changedv2.0.0
    • changedInput schema / properties / properties / description
      Previous value: -"Dict of {property_name: value}; values can be scalar, nested object, or array (UE-format text like \"(X=1,Y=2,Z=3)\" is also accepted for structs)"New value: +"Optional dict of {property_name: value}; values can be scalar, nested object, or array (UE-format text like \"(X=1,Y=2,Z=3)\" is also accepted for structs). Required unless property_name + value is given; both together write properties{} first."
    • addedInput schema / properties / property_name
      Added value: +{
      +  "description": "Optional single property to write (must be CPF_Edit and not EditConst, or it lands in failed[] with the reason). Needs value.",
      +  "type": "string"
      +}
    • addedInput schema / properties / value
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "array"
      +    },
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    }
      +  ],
      +  "description": "Optional new value for property_name: string, number, boolean, JSON object (struct), JSON array (array/set/tag container), or a UE-format text string like \"(X=1,Y=2,Z=3)\""
      +}
  5. First observedv1.1.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses that writes are undoable, dirty the package, re-register components, and report set/failed results with reasons. It also explains PIE refusal and force behavior, save refusal for level objects, and asset-specific finishing actions such as graph-node reconstruction and Niagara recompilation. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is long but front-loaded: purpose, usage, exclusions, examples, path semantics, finishing behavior, refusals, and return shape appear in a logical order. Some sentences are dense and could be trimmed, but most carry operational detail rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex mutation tool with seven parameters and no output schema, the description covers the return shape, failure reporting, refusal conditions, undoability, and asset-finishing side effects. An agent has enough context to call it correctly and understand the consequences.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds substantial meaning: path syntax like 'RelativeLocation.Z' and 'Items[2].Name', partial struct writes, interaction between properties and property_name/value, nested-object traversal, and clamp/save semantics. This goes well beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource: 'Write one or several editable properties of one object in the editor world.' It enumerates supported object types and explicitly distinguishes this tool from set_component_property, set_blueprint_component_properties, set_widget_property, and call_function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool ('Use it for any setting of a light, fog, sky, decal...') and when not to use it, naming the correct alternative for each excluded case. It also gives concrete guidance for PIE sessions, save behavior, and property-name discovery via get_object_info.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.