Skip to content
Bit Quirky Behavior Trees and
State Machines

Search documentation

All topics and APIs

Close returns focus to Search.

What are you looking for?

Try a common topic or enter a complete API identifier.

Browse the reference instead

Esc closes · Tab reaches results · Enter opens the focused link

v0.6.0
Menu

Live editing

Read a running agent's member-bound values while the game plays, tune the ones you are allowed to write, and know exactly why the others refuse.

Attach the editor to one running guard and every value it binds to your game gets a card: what the graph sees, what your component holds, which way the binding points, and whether you can type a new number in right now.

Dungeon Heist’s second guard patrols at 2.2. Is that too slow to be a threat? The honest way to find out is to watch it walk while you change the number. Stop, edit, replay, and walk back to the same corridor is ten slow loops for one tuning decision, and you still have to trust that the value you typed is the one the graph read.

Guard2.bqbehavior binds patrolSpeed two-way onto the guard’s FloatVariable. In Live that binding becomes a card you can type into, and the guard changes speed while you watch.

  • Tuning a number in motion: patrol speed, a cooldown, a detection radius, anything bound two-way or blackboard to member.
  • Settling an argument between the graph and your code. A card shows the value the graph received beside the value your component holds, and says so when they differ.
  • Proving an edit stays on one agent. Change patrolSpeed on Guard_2 and the other four Dungeon Heist guards keep their pace.
patrolSpeed is a two-way binding, so its Current row accepts a value while the game runs and the guard picks up the new patrol speed on the next tick.
patrolSpeed is a two-way binding, so its Current row accepts a value while the game runs and the guard picks up the new patrol speed on the next tick.

patrolSpeed typed from the authored 2.2 to 6 while the guard walks. The card confirms at once, and the graph picks the value up on its next tick.

One live value moving along one bindingA Live card in the editor, the patrolSpeed member on the Dungeon Heist guard's component, and the graph's blackboard value patrolSpeed. One authored two-way binding joins the member to the graph, and the card hangs off that same binding, so every change in the diagram travels one path. First gameplay sets the member to 4: Source reads member value 4 and the card notes Source differs 4 while Current still reads 2.2; at the graph's next evaluation what graph nodes read becomes 4, Current reads 4, Source reads game write 4, and the note clears. Then the designer types 6 into Current and commits: one request reaches the running agent, the generated setter runs once, the member holds 6, Current shows 6 at once with the note Edit accepted awaiting evaluation, and at the next evaluation what graph nodes read becomes 6 and the note clears, with nothing written twice. The graph file Guard2.bqbehavior is unchanged throughout.Live cardin the editorCurrent2.246Sourcemember value · 2.2member value · 4game write · 4runtime edit · 6Source differs · 4Edit accepted · awaiting evaluationtwo-way bindingone path for every changeone request, no echothe memberon the guard componentpatrolSpeedtwo-way onto FloatVariable.Valueauthored 2.2now2.246the graphblackboard value patrolSpeedwhat graph nodes readnow2.246Guard2.bqbehaviorunchangedgame writegameplay writes 4, and the graph reads it at the next evaluationLive editone setter call, Current at once, the graph at the next evaluationOne live value moving along one bindingA Live card in the editor, the patrolSpeed member on the Dungeon Heist guard's component, and the graph's blackboard value patrolSpeed. One authored two-way binding joins the member to the graph, and the card hangs off that same binding, so every change in the diagram travels one path. First gameplay sets the member to 4: Source reads member value 4 and the card notes Source differs 4 while Current still reads 2.2; at the graph's next evaluation what graph nodes read becomes 4, Current reads 4, Source reads game write 4, and the note clears. Then the designer types 6 into Current and commits: one request reaches the running agent, the generated setter runs once, the member holds 6, Current shows 6 at once with the note Edit accepted awaiting evaluation, and at the next evaluation what graph nodes read becomes 6 and the note clears, with nothing written twice. The graph file Guard2.bqbehavior is unchanged throughout.Live cardin the editorCurrent2.246Sourcemember value · 2.2member value · 4game write · 4runtime edit · 6Source differs · 4Edit accepted · awaiting evaluationtwo-way bindingone path for every changeone request, no echothe memberon the guard componentpatrolSpeedtwo-way onto FloatVariable.Valueauthored 2.2now2.246the graphblackboard value patrolSpeedwhat graph nodes readnow2.246Guard2.bqbehaviorunchangedgame writegameplay writes 4, read at the next evaluationLive editone setter call, read at the next evaluation
One binding carries every change. A game write reaches the graph at its next evaluation; a Live edit calls the setter once, shows on Current at once, and reaches the graph at its next evaluation, with nothing written twice. The graph file never changes.

Every change travels along the one binding you authored. There is no second synchronization path to fall out of step, and no path at all back to the graph file.

  1. Enter Play Mode with the graph editor open and select the GameObject that carries the Behavior Agent you want, here Guard_2. The toolbar switches to Live, names the follower, and reads ATTACHED.

  2. Click an empty spot on the canvas so nothing is selected. The rail opens with a Member binding section, marked surfaced, above Blackboard values. Each surfaced binding is one card.

    Four collapsed member cards under the Member binding heading: catch_reset_position with a lock, a gray edge and its Vector3 position, focusPosition with a warning triangle and an amber edge, liveFocus with a cross and a red edge, and patrolSpeed with an editable field holding 2.2
    Figure 1. Guard_2’s four cards while it patrols. Each refusing card carries an icon in its value box; patrolSpeed has a plain field, so it takes one.
  3. Find a card whose value sits in an editable field. That is a binding that writes the member, such as the two-way patrolSpeed.

  4. Type the new value into the field and press Enter (or click away). Exactly one edit goes to the running agent, through the generated setter.

  5. Read the card. Current holds your value straight away, and the line under the name reads Edit accepted · awaiting evaluation until the graph’s next evaluation reads it, which at normal speed is the next tick. While the follower is paused it reads Edit accepted · waiting for Step instead.

Every card opens with the arrow at its right edge (Show details). Open patrolSpeed and you get the whole binding in one place.

The patrolSpeed card opened, with nine numbered markers: the name, the Current field holding 2.2, the details arrow, the instance edit chip, and the Type, Target, Direction, Source, and Health rows
Figure 2. patrolSpeed on Guard_2, healthy and editable.
# Part What it tells you
1 Name The blackboard name the binding surfaces, here patrolSpeed.
2 Current The value graph nodes receive. An editable field when the chip reads instance edit, a plain reading otherwise.
3 Details arrow Show details and Hide details. Stays open across Live refreshes.
4 Status chip Whether an edit will be accepted right now. See when a card refuses.
5 Type The exact value contract and its assembly: System.Single @ BitQuirky.Core. Nothing is converted to fit it.
6 Target The declaring type and the member: BitQuirky.Core.Variable.FloatVariable. then Value.
7 Direction The authored direction: blackboard → member, member → blackboard, or two-way member ↔ blackboard.
8 Source The value on your member and what last moved it: member value, game write, or runtime edit.
9 Health Healthy whenever the binding resolves to its exact member and type, including a read only binding. The line under it is the exact type when the chip is instance edit, or a short refusal word when it is not.

Hover any icon on a card, the lock, the triangle, the cross, the type dot, or the direction glyph, for a one-line explanation of it.

A card that cannot take an edit shows no field. It keeps its last confirmed value on show (hover it and the tooltip reads Last confirmed value), draws a colored edge, and puts its reason in the details. Guard_2 carries all three refusals at once:

Three member cards opened: catch_reset_position with a read only chip and the sentence that its member → blackboard direction has no write path; focusPosition with an unavailable chip and the sentence that GuardFocusTarget.Position cannot resolve on Guard2; liveFocus with an incompatible chip and the sentence that the exact UnityEngine.Object contract does not accept the current payload. Each ends with No value sent · nothing converted · no graph edit · no undo record
Figure 3. Read only, unavailable, incompatible, top to bottom. catch_reset_position is a UnityEngine.Vector3, so its value reads as three components and its Type row names UnityEngine.Vector3.
Chip Edge and icon Why it refuses Reason under Health
instance edit none It does not. The binding resolves and writes the member. the exact type
read only gray, lock The authored direction reads the member and never writes it, or the member has no setter. read only
unavailable amber, triangle The target, the member, or the member runtime cannot be reached right now. focusPosition reads through the guard’s focus, and a patrolling guard has none. destination cannot resolve, or runtime disposed once the agent’s runtime is gone
incompatible red, cross The value has no exact form Live can carry, such as an object read into the blackboard. two identities, no conversion
no instance none The attachment has ended. See when the attachment ends. none

Under the reason, a sentence names the cause and what was kept, then one line closes every refusal:

No value sent · nothing converted · no graph edit · no undo record

Typing something the exact type cannot hold, fast into a float for instance, is refused beside the field and stays visible with the details closed: The exact System.Single contract does not accept 'fast'. No value was sent, and 2.2 is preserved.

Your code keeps writing the member while you watch, and the card keeps up. When the member moves before the graph has read it, the card says so under the name.

  1. patrolSpeed opened while the follower is paused: Current still 2.2, the note Source differs · 4, and Source reading member value · 4
    Figure 4. patrolSpeed opened while the follower is paused: Current still 2.2, the note Source differs · 4, and Source reading member value · 4

    The game set the guard’s patrol speed to 4 (Dungeon Heist’s guard.patrol-speed command, the same path its own systems use). Source reads member value · 4 and the card reads Source differs · 4, while Current still holds the 2.2 the graph last received.

  2. patrolSpeed after one step: Current 4, no note, Source reading game write · 4
    Figure 5. patrolSpeed after one step: Current 4, no note, Source reading game write · 4

    The graph’s next evaluation reads the member through the same binding. Current becomes 4, the note clears, and Source reads game write · 4. No prompt, no conflict dialog, and nothing to save.

A game write that lands after one of your Live edits replaces it the same way. The last writer wins, through the one binding.

Pause holds one follower still so you can set a value and watch exactly one evaluation use it. Choose pause in the toolbar, or press Space with the editor focused; the button becomes resume and TICK drops to 0Hz. Everything else in the scene keeps running.

The Live toolbar with the follower paused: resume and step buttons, FOLLOWER Guard_2, ATTACHED, GRAPH LOCKED, TICK 0Hz
Figure 6. The Live toolbar with the follower paused: resume and step buttons, FOLLOWER Guard_2, ATTACHED, GRAPH LOCKED, TICK 0Hz
  1. patrolSpeed holding 6 with the note Edit accepted · waiting for Step and Source runtime edit · 6
    Figure 7. patrolSpeed holding 6 with the note Edit accepted · waiting for Step and Source runtime edit · 6

    Type 6 and press Enter. The setter has already run, so Current and Source (runtime edit · 6) both confirm it. The card reads Edit accepted · waiting for Step.

  2. The rail’s Evaluation section reading Waiting for Step. Confirmed by the running instance. The row follows the game through this binding.
    Figure 8. The rail’s Evaluation section reading Waiting for Step. Confirmed by the running instance. The row follows the game through this binding.

    At the bottom of the rail, the Evaluation section spells out what the graph is waiting for: Waiting for Step. Confirmed by the running instance. The row follows the game through this binding.

  3. patrolSpeed holding 6 with no note and Source runtime edit · 6
    Figure 9. patrolSpeed holding 6 with no note and Source runtime edit · 6

    Choose step, or press ., for one ordinary evaluation. The graph reads 6, the note clears, and the Evaluation section closes. Stepping again changes nothing: the edit is applied once and never echoed back.

Pausing grants nothing new. An editable card stays editable, and a refused card stays refused.

Select something else, destroy the guard, reset its runtime, or reimport its graph, and the attachment ends. The toolbar reads LOST and the canvas shows Detached. The cards stay, because the binding is still part of the graph, but every runtime fact clears. The Blackboard values rows read cleared too, so no number left over from the old instance looks current.

Four member cards reading cleared in faint italics, patrolSpeed opened: a no instance chip, Type, Target, and Direction still showing the authored binding, Source and Health reading cleared
Figure 10. After the selection moved to the camera. Current, Source, and Health read cleared, the Current field is gone, and Target and Direction keep the authored binding in view. A card you open stays open while it waits.

Nothing you typed can reach a different guard. Select Guard_2 again while it runs and it attaches afresh.

Below 1100 pixels wide, the rail stops sharing the window and slides over the canvas instead, with two tabs: Blackboard (member cards plus every blackboard value, with a count) and Selection (the selected node). Blackboard opens first. Editing and refusal work exactly as they do full width.

The toolbar makes room the same way. When the row runs short it drops the TICK reading first (the status bar still carries the rate), then shows the verdict chips as their glyphs alone, with the words on each chip’s tooltip. The attachment pip stays, and no control is ever squeezed under its own text.

The Live toolbar at a 760 pixel window: Reload, Undo, Redo, Save, Static and Live, pause, step, Guard_2 with a green attachment pip, the graph lock, a green check chip and an amber warning chip with no words, the overflow button, and Search nodes
Figure 11. Guard_2’s toolbar at 760 wide. The verdict chips keep their glyphs and colors; hover one for its words.
The right edge of the editor at 1000 pixels wide: a strip of canvas, the canvas fold handle, and the rail laid over the canvas with Blackboard · 30 and Selection · 0 tabs above the same four member cards and the Blackboard values list
Figure 12. The right edge of the Dungeon Heist window at 1000 wide. Blackboard · 30 counts the 26 blackboard values plus the four surfaced cards.

Which values get a card

  • Every member binding the attached graph surfaces, on a GameObject agent. Entity Live observes only.
  • The Blackboard values section below the cards is a read-only snapshot of the whole blackboard. Its rows never take an edit.

When Current is an editable field

  • The chip reads instance edit: the target and member resolve, the authored direction writes the member, and the member has a setter.
  • The value is one the card has an editor for: a number (whole or decimal), a bool, a char, a string, an enum (a dropdown of its members), a vector (float2, float3, float4, or an all-float struct such as Vector3 or Quaternion, edited per component), or a Unity object reference (an object field). Other structs show their fields without a field to type into; the limits are on what it does not do yet.

What one edit does

  • One committed value sends one typed request to the one attached agent. A refresh, a repaint, a focus change, or a detach sends nothing.
  • The generated setter runs once. Current and Source confirm the value immediately.
  • The graph reads it at its next evaluation (one step while paused) and nothing is written a second time.
  • The graph file, the document’s saved state, and graph undo are untouched.

When an edit is refused

  • The card states which rule failed, keeps the last confirmed value, and sends nothing. Refusals cover the authored direction, an unreachable target or runtime, a runtime that restarted or a graph that changed since the card was drawn, a value of the wrong kind, a member that is not a property or field, and a setter that threw. A setter that throws is not retried.
  • If the game moved the value between the moment you read the card and the moment you pressed Enter, the edit is judged against the binding as it is now. It is accepted or refused; the older value you saw is never restored.

How long an edit lasts

  • Until something else writes the member, the agent’s runtime resets, or Play Mode ends.

When it goes wrong

SymptomCheckFix
The rail shows no Member binding section.Read the toolbar: Live, a follower name, and ATTACHED. Then check whether the graph surfaces any member binding.Select the running object so the editor attaches. A graph with no surfaced binding has nothing to edit here.
Current shows a value and no field.Open the details and read the chip and the Type row.A read only, unavailable, or incompatible chip names its reason. A healthy card whose value is a struct with non-float fields is read here and changed in your code.
A card says read only.Read the Direction row.A member → blackboard binding never writes the member. Make it two-way or blackboard → member in Static if the graph should drive it.
A card says unavailable.Read the sentence under Health for what could not resolve.Usually the target does not exist yet, such as a focus the guard has not acquired. It clears by itself when the target resolves.
A card says incompatible.Read the Type row.An object read into the blackboard has no Live edit. Make the binding two-way in Static if you need to set it while the game runs, or change it from your own code.
The card says Source differs.Gameplay changed the member since the graph last read it.A binding that reads the member takes the new value at its next evaluation, so step once if the follower is paused.
The edit worked and then went away.Look for a runtime reset, a graph replacement, or your own code writing the member every frame.The last writer wins. For a value only the graph should drive, author a blackboard → member binding.
Both guards changed.Check whether the binding target is Static, or whether both guards share one asset instance.Bind an instance target, or give each agent its own copy of the asset, for per-agent tuning.
The number you typed is gone after you stopped.Live edits never write back to the graph file.Set the starting value in Static mode, or on the asset your binding targets, once you know the number you want.
Full-size image