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

Format and migrations

Read the format line on a graph file, see what each version added, and move an older graph forward without losing what you authored.

Every graph file declares the vocabulary it needs. Platformer’s patrol says %% source-format: bitquirky.behavior/1.3, and that line is the contract between the file and the reader.

Formats that rewrite your files on open lose things quietly. A default becomes a constant, a generic loses a type argument, an out parameter gains an invented input, and the graph still opens, so nobody notices until a build behaves differently.

This format is additive. A later reader accepts valid earlier text unchanged, and a document moves forward only when an edit needs the later vocabulary. Opening and saving an unchanged 1.3 graph leaves it at 1.3.

Plain text
%% source-format: bitquirky.behavior/1.9
Format What it added
1.0 Legacy text without semantic node parameter blocks
1.1 Typed semantic node parameters
1.2 Dedicated member-binding records
1.3 Declared blackboard values, variable member targets, entity records
1.4 Exact open generic method identity with ordered concrete choices
1.5 Explicit action-state lifecycle phases and phase-specific groups
1.6 Exact method parameter names and the Declared default source
1.7 Explicit output-only parameter records and their destinations
1.8 Expanded individual params elements and the active input form
1.9 Member-binding references as argument sources

Package version, behavior version, and format version are separate identifiers. Compatibility keeps the mapping.

One version gates a feature outright: an entity graph needs at least 1.3, and a file with %% runtime-path: entity on an earlier format is reported as needing %% source-format: bitquirky.behavior/1.3.

Newer records carry information older ones could not, and they are never guessed from an older shape.

  • A 1.4 generic identity keeps the open definition and each concrete type argument separately.
  • A 1.6 parameter record distinguishes choosing the declaration’s Default from authoring a constant that happens to equal it.
  • A 1.7 out row has an output destination and no invented input value.
  • A 1.8 params binding keeps each expanded element’s source and its position.
  • A 1.9 argument can read a sibling binding on the same node, instead of being reinterpreted as a blackboard field.

An unknown, incomplete, or inconsistent record fails with a structured diagnostic. The reader will not fall back to the nearest older shape it recognizes.

Modern records keep assembly identity for non-keyword types, and older text may lack it. Resolution has three outcomes: the recorded assembly and type resolve; the identity is gone and a surviving same-named candidate is offered without being adopted; or several candidates are possible and you confirm which one you meant.

Confirming writes the chosen identity into the file, which is the migration. Nothing switches to whichever assembly happens to load first.

A saved binding resolves to one exact declaration, and parameter type, name, order, and modifier are part of that identity. Renaming or reordering a parameter, turning ref into out, changing the return type, or moving to another overload blocks the binding until you rebind it deliberately.

One compatibility case is safe: exactly one longer declaration of the same member that appends only ordinary optional parameters with concrete compile-time defaults. An ambiguous longer declaration, a required suffix, params, or optional metadata with no value does not qualify.

A changed declared default never edits graph text. It changes the derived digest and the generated call after a reimport. A default that disappears blocks the binding until you choose a constant, a variable, or another member.

Declared values keep payloads the new type cannot read instead of dropping them. Retyping keeps what the new type can read and seeds the rest with that type’s real default. Retyping a dictionary key keeps every entry and reports collisions or unreadable keys locally. None and empty stay different states throughout.

Collection shape changes follow the rules in variables and types.

  1. Keep the .bqbehavior file and its .meta file together.
  2. Open the graph and read every importer diagnostic before changing anything.
  3. Confirm ambiguous type identities explicitly.
  4. Rebind stale members in the picker instead of editing a displayed name.
  5. Inspect collection and output destinations that stayed invalid by design.
  6. Save through the editor, then reopen the graph and read its validation.
  7. Reimport and let generated C# compile.

The writer picks the minimum format the records actually need, so a bulk replacement of format tokens is a claim the file cannot back up.

A graph whose migrated text is invalid has no valid executable cache. Hosts and player builds refuse it, and none of them runs the last successful cache, invents defaults, or drops records it cannot read.

When it goes wrong

SymptomCheckFix
The importer reports an unknown record.Read the format line and the record the diagnostic names.Open and save the graph in this editor so the writer emits the format those records need.
A type is reported as ambiguous.Read which candidates the editor offers for the recorded name.Confirm the one you meant, which writes its assembly identity into the file.
A binding stayed stale after you renamed the parameter back.Compare the parameter names and order with the saved record.Rebind once in the picker. Parameter names are part of the identity.
A retyped variable kept a value you expected to lose.Declared values keep payloads instead of dropping them.Clear the entry deliberately if the old value is wrong for the new type.
An entity graph reports that it needs format 1.3.Read the header for runtime-path and source-format together.Save the graph from this editor, which writes the format its entity records require.
Full-size image