Graph files
Read what a .bqbehavior file stores, what Unity prepares from it, and what to do when one refuses to import.
On this page
A graph you authored is one text file in your project. It is readable, every change to it is a line you can read, and it carries everything the editor showed you, down to the layout you arranged.
The problem
Section titled “The problem”A decision you cannot inspect is a decision you have to trust. Platformer’s patrol is EnemyPatrol.bqbehavior, and its first lines say what it is:
%% behavior-version: 1.0.0%% layer: behavior%% source-format: bitquirky.behavior/1.3%% validation-profile: platformer_multi_point_patrol%% fields:%% field-types:%% services: movement%% variables:%% - name: route%% type: UnityEngine.Vector2, UnityEngine.CoreModule%% shape: listHorde Survival’s EnemyBrain.bqbehavior opens the same way and adds one line, %% runtime-path: entity, because that graph binds entity members. The body below those headers is Mermaid-compatible flowchart text, so the structure reads as structure.
These files are data, so the editor owns them. Change them there and let Unity import the result.
What a graph file remembers
Section titled “What a graph file remembers”- Nodes, states, connections, and their stable identities.
- Child order, transition order, conditions, plus every node setting.
- Blackboard declarations with their shapes and saved starting values.
- Exact C# member bindings: declaring type, member, overload parameters and modifiers, generic arguments, argument sources, plus result mapping.
- References to other graph assets, for a subgraph or a referenced state machine.
- The layout you arranged on the canvas, excluded from the semantic hash so tidying a graph leaves its meaning alone.
What Unity prepares from it
Section titled “What Unity prepares from it”The imported asset is a BehaviorSourceAsset, which is the API type name for a graph asset. From it Unity derives the executable cache, generated member access, a managed blackboard companion where one is needed, and build preservation metadata.
Those are prepared data. A GameObject agent or an entity registration materializes its own runtime artifact from that cache at initialization, so no game code needs a parser or a manual bake step.
A C# change can alter the prepared result while the graph file stays byte for byte the same. Change a method’s optional default and a binding that passes Default passes the new value after the reimport. Change its name and the binding goes stale and says so.
Save it and run it
Section titled “Save it and run it”-
Edit the graph in Static and let autosave finish. Autosave writes the graph file only; Save imports it and regenerates the member provider for that graph, and is also how you retry a failed write.
-
Wait for Unity’s import, and for generated C# to compile when the graph binds members.
-
Clear the validation findings the toolbar reports.
-
Assign the imported asset to a Behavior Agent, or register it with
BehaviorEntityRuntime.RegisterGraphfor the entity host. -
Press Play. A newly initialized agent starts from the saved values.
Reusing one graph from another
Section titled “Reusing one graph from another”A Subgraph node or a Referenced State Machine points at another graph asset by stable identity. Unity tracks that dependency, so editing the referenced graph reimports the graphs that use it.
Composition has one hard rule worth knowing early: the referenced graph has to share the parent’s runtime path. A GameObject graph cannot reference an entity graph, and the mismatch is reported when the parent bakes.
Reading or editing the text
Section titled “Reading or editing the text”The file is precise about type identity, overloads, argument order, result mapping, and collection values, which is what makes a binding survive a refactor honestly. If you edit the text by hand, reopen the graph afterwards and clear the diagnostics before running it.
The format is Mermaid-compatible graph text. There is no JSON import or export API, so an external authoring tool has to produce the real format and preserve its identities and binding records.
Comment lines beginning with %% survive a round trip unchanged, and the editor’s own records use structured %% lines too. Leave those structured records to the editor and keep your own comments to prose.
When a graph will not import
Section titled “When a graph will not import”A parse, reference, validation, or bake failure leaves the asset with no usable executable cache, and hosts refuse it instead of running an older interpretation.
-
Select the
.bqbehaviorasset and read the first diagnostic. -
Use its graph, its line, plus the declaration it names to find the problem.
-
Repair the graph value, the referenced asset, or the bound C# declaration.
-
Reimport, and let generated C# finish compiling.
-
Reopen the graph and read the validation result before starting a new instance.
When it goes wrong
| Symptom | Check | Fix |
|---|---|---|
| The asset shows an import error and the agent throws on Play. | Read the first structured diagnostic on the asset. | Repair that one, reimport, and read the next. They are ordered for a reason. |
| A binding is stale after a rename. | Compare the saved identity with the current declaration. | Rebind in the picker, or use Reference Scan for a project-wide repair. |
| A referenced graph cannot compose. | Compare the runtime path and the validation profile of both graphs. | Keep a reusable graph on one host, and match the profile the parent expects. |
| A hand edit made the file unreadable. | Read the parse diagnostic and its line number. | Repair that line, or restore the file and make the change in the editor. |
| Layout moved and you expected behavior to change. | Layout is excluded from the semantic hash. | Reorder children in the rail to change execution order. |
- Format and migrations: the format line, what each version added, and how an older file moves forward.
- Reference Scan: finding every graph that still names something you renamed.
- Addressables and builds: what a player build checks.