Runtime
Put a finished graph in your game on the host your game already uses, a Behavior Agent component on a GameObject or a registration in an ECS World.
On this page
A graph decides. Your game acts. This section is about the seam between the two: which component or system owns a running graph, when it steps, and what you hand it at composition time.
The problem
Section titled “The problem”Platformer’s enemy is a GameObject with a sprite, a collider, and a patrol script, so its graph belongs on a component beside them. Horde Survival’s enemies are entities by the hundred with no GameObject at all, so their graph belongs to a system that advances every matching entity in one job. Both games run the same kind of graph, authored in the same editor, with the same node semantics.
Picking the wrong host shows up late: a graph full of coroutine waits will not run on entities, and a graph written against component data has nothing to read on a plain GameObject.
One graph file, two hosts
Section titled “One graph file, two hosts”A graph file declares which member targets it is allowed to bind. The header line %% runtime-path: entity puts a graph on the entity vocabulary, and a graph that leaves the line out keeps the GameObject vocabulary, which is the default. Validation holds that line: it refuses a target belonging to the other host, naming the graph’s own path, so the message reads either “does not belong to the graph’s entity runtime path” or “does not belong to the graph’s GameObject runtime path”, and it refuses a graph whose member nodes straddle both surfaces with the flat sentence “one graph must use one backend.” Composing a subgraph whose runtime path disagrees with its parent blocks the bake as well. What decides the host at run time is where you compose the graph: a Behavior Agent component, or a RegisterGraph call on a BehaviorEntityRuntime. A graph that binds no host-specific member, like Horde Survival’s HordeDirector.bqbehavior, carries no marker and still runs on the entity host.
One project can use both hosts. Platformer, Dungeon Heist, and Racing Line run their graphs on Behavior Agent components; Horde Survival registers EnemyBrain.bqbehavior, an entity graph, for its whole swarm on one BehaviorEntityRuntime, and registers its director graph on a second BehaviorEntityRuntime in the same World. Nothing stops those two kinds of actor from sharing a game, and nothing lets one graph mix host surfaces internally.
Pick your host
Section titled “Pick your host”| Concern | GameObject | Entity |
|---|---|---|
| Owner | One Behavior Agent component | One BehaviorEntityRuntime for a World you supply |
| Instances | One per component | One per entity matching the registered query |
| Step | The Update Mode you chose, or TickOnce from your own code |
TickGraph or TickAll from your system |
| Facts in | IBehaviorGameObjectInputBinder |
IBehaviorEntityInputBinder |
| Effects out | IBehaviorGameObjectCommandHandler, movement adapters, services |
IBehaviorEntityCommandHandler |
| Managed values | Supported through the managed companion | Unsupported on this path |
| Coroutines, awaitables, C# events | Supported | Unsupported on this path |
| Live debugging | Attach, pause, step, breakpoints | Attach and observe |
Choose GameObject when the decision touches a MonoBehaviour, a scene reference, a coroutine, or a C# event. Choose Entity when every fact and every effect already lives in ECS data and you want the tick inside a Burst job.
Where to go next
Section titled “Where to go next”Compose a host:
- GameObject agents: the component, its fields, when it steps, reset and replacement.
- Entity agents: registering a graph against a query, ticking it from a system, disposal.
- Adapters and services: the interfaces your game implements so a graph can ask for work.
Make it fast and ship it:
- Burst and jobs: what is compiled, what stays managed, and where the boundary is.
- Performance: the recorded Horde Survival figures, with their method and their machine.
- Addressables and builds: what a player build validates, and the optional loader.
Before you blame the host
| Symptom | Check | Fix |
|---|---|---|
| The graph does nothing in Play Mode. | Confirm the agent has a graph assigned and an Update Mode chosen, or that your system actually calls TickGraph. | Assign the graph and pick an update mode, or add the tick call to the system that owns the runtime. |
| A member target is refused by validation. | Read whether the graph is an entity graph and the target is a GameObject mode, or the reverse. | Use the target modes that belong to the graph’s runtime path, or author a second graph for the other host. |
| A subgraph refuses to compose. | Compare the runtime path of the parent graph and the referenced graph. | Keep a reusable branch on one host. A graph cannot be shared across hosts by reference. |
| The agent throws about a missing provider on entering Play Mode. | A graph with bindings needs its generated provider composed on the host. | Assign the generated provider, as in Addressables and builds. |
| Two ticks happen per frame. | Look for game code calling TickOnce on an agent that is also enabled with an Update Mode. | Pick one owner of that agent’s schedule. |