Verse Wiki — the Verse handbook for Blueprint authors
Technique · EXTRA

@editable and the Details Panel: Let Artists Tune Your Component

A component only a programmer can tune is half-finished. @editable pushes fields into the Details panel so designers and artists can tune them themselves. This page covers it end to end: which types can be exposed, how to add sliders and numeric bounds, how to write categories and tooltips, and who actually wins between the code default and the level override.

1. Where It Goes and What It Means

@editable is an attribute: it starts with @, occupies its own line, and sits above the field it modifies. That's a different syntax family from specifiers like <public> and <final_super>, which live inside angle brackets. Don't blend them.

lift_platform_component.verse
lift_platform_component<public> := class<final_super>(component):

    @editable
    Height<public>:float = 200.0
#   ▲          ▲       ▲      ▲
#   attribute  access  type   default (required)

Adding it does three things: the field shows up in UEFN's Details panel; the value written in code becomes the panel's initial displayed value; and when the component is attached to different entities, each copy can hold a different value. The official wording on that last point is blunt: changing an editable property's value only changes it for that instance — five copies of the same component in a level can hold five different values. And editing the panel requires no recompile.

Those three points together are exactly the semantics of Blueprint's Instance Editable. That little eye you light up next to a Blueprint variable has become one line of text in Verse.

Conversely: a field without @editable is purely internal data and simply doesn't appear in the panel. That's a design discipline in itself — expose only what genuinely needs tuning by someone else. Dump your whole internal state into the panel and your designer, faced with twenty boxes of unknown consequence, will just come ask you anyway.

2. Which Types Can Be Exposed

Here is the official list of editable types. Note the recursive condition on the containers and structs tier: whatever is inside must also be editable, or the whole field never reaches the panel.

Tier Types What the panel shows
Primitives logic, int, float, string, enum Checkbox, numeric field, text field, dropdown
Containers array and map of editable types An add/remove list, or a key-value list
Structs struct whose fields are all editable An expandable group
Class instances Instances of classes (including device types) A reference slot you can point at an object in the scene

Hold that table next to Blueprint's Variable Type dropdown and the coverage almost lines up: boolean, integer, float, string, enum, array, map, struct, object reference. Nearly anything you'd tick Instance Editable on in Blueprint can carry @editable in Verse.

The class-instance tier is the closest analogue to Blueprint's "Actor reference variable": in Blueprint you'd declare a Target Door variable typed to some Blueprint class, then eyedropper a specific door in the level. In Verse you give the field a class-instance default value, and the same reference slot appears in the panel.

3. Variants: Putting Guardrails on the Box

A bare @editable hands over an unguarded input box — a designer can type -99999 into Height. In Blueprint you'd set Slider Range and Value Range in the variable's Details; in Verse you switch to a more specific attribute variant instead. The main variants in the official docs:

Variant Purpose Blueprint equivalent
@editable_number(type) A numeric field with MinValue / MaxValue Value Range in a variable's Details
@editable_slider(type) A slider with bounds and a step size Slider Range in a variable's Details
@editable_text_box Multi-line text field with an optional character limit A String variable with Multi Line ticked
@editable_vector_slider(type) Per-component sliders on a vector, with ratio lock / normalize The three boxes of a Vector variable
@editable_vector_number(type) Per-component numeric fields on a vector (no sliders) Same as above, without the drag bars
@editable_container Container display config (arrays for now), e.g. whether reordering is allowed Details options on an array variable

Syntactically, these variants take a colon and the config items are indented underneath — consistent with block structure everywhere else in Verse:

guarded_component.verse
guarded_component<public> := class<final_super>(component):

    # Slider: 0.0 to 10.0, one step per 1.0
    @editable_slider(float):
        MinValue := option{0.0}
        MaxValue := option{10.0}
        SliderDelta := option{1.0}
    Speed<public>:float = 1.0

    # Numeric field clamped between 0 and 10
    @editable_number(int):
        MinValue := option{0}
        MaxValue := option{10}
    Lives<public>:int = 3

Note the bounds use option{...} — the optional values from Lesson 18: you can set a lower bound without an upper one by writing only the MinValue line. That's a touch more flexible than Blueprint's two Range pairs, which want both boxes filled.

4. Categories and Tooltips: Making the Panel Presentable

Once a component has a lot of parameters, the panel turns into soup. Blueprint's fix is filling in Category and Tooltip on the variable. Verse's fix is the same, except the text has to be declared as a message first and then hung on the attribute:

tidy_component.verse
# Category name and tooltip text, declared as localizable messages
MotionCategory<public><localizes>:message := "Motion"
HeightTip<public><localizes>:message := "How high the platform rises, in centimeters"

tidy_component<public> := class<final_super>(component):

    @editable:
        ToolTip := HeightTip
        Categories := array{MotionCategory}
    Height<public>:float = 200.0

<localizes> is the localization specifier: text marked with it enters the translation pipeline, so panel labels can follow the user's language later. That's more disciplined than Blueprint, where a Category is a raw English identifier that never gets localized.

Categories takes an array, so one field can belong to several groups at once. The practical pattern: one category constant per functional axis, declared together at the top of the file, with each field hanging off whichever it belongs to.

5. Defaults versus Overrides: Who Wins

This is the section that causes the most misunderstandings, and the one most worth memorizing.

Which yields a practical rule: write defaults that produce a correct-looking result when nobody fills anything in. A default height of 0.0 or a default name of "" just makes whoever attaches your component first assume it's broken. Giving every editable field a self-evident default is the most basic courtesy you owe a collaborator.

One more comparison carried over from Lesson 27: Blueprint variables also have Expose on Spawn, and Verse has no switch by that name. To pass parameters at spawn time, assign the field directly when constructing the instance — for example lift_platform_component{ Height := 300.0 }. That path and the Details panel are two parallel ways to fill a value; they don't conflict.

You change Height's default in the component code from 200.0 to 300.0. One platform in the level was previously set to 150.0 by a designer in the Details panel. After recompiling, what is that platform's Height?

Sources

Compiled from Epic's official documentation:

The exact config options on each attribute variant get extended release by release; check the official docs of the day before you build.