# Design Levers

Level: Intermediate

## Summary

Design levers are the graph settings and data choices that change player-visible behavior without changing the underlying system. In Flow Core, the most important levers are Trigger frequency, Invoke Mode, Guard Reject Result, Blackboard scope, FlowValue source, subgraph usage, and Pass Enabled control.

Good graph design is mostly the art of choosing these levers deliberately. The same graph can feel responsive, delayed, noisy, or stable depending on these choices.

## Why It Exists

Flow Core exposes runtime behavior as visible authoring decisions. That is useful only if authors understand what each decision changes.

For example, a high-frequency Trigger with `Queue` can preserve every event, but it can also create delayed chains that run after the player has moved on. Switching to `Bypass` may feel more responsive, but it means some work is intentionally skipped. Neither choice is universally correct; the design intent decides.

## Mental Model

Think in terms of pressure and ownership:

* Trigger frequency controls how much work enters the graph.
* Invoke Mode controls what happens when the graph is already busy.
* Guard Reject Result controls how strongly a blocked branch should stop.
* Blackboard scope controls who can see and change data.
* FlowValue source controls whether a value is authored, event-provided, resolved from a target, or literal.
* Subgraph usage controls reuse and context boundaries.
* Pass Enabled controls whether a node currently accepts incoming chains.

These levers combine. A frequent Trigger, a Global Blackboard, and `Queue` can create broad and delayed side effects. A Local Blackboard, a narrow Trigger, and `Bypass` can create a more isolated and responsive behavior.

## Behavior Contract

| Lever               | What changes                   | Main risk                            | Use when                                                             |
| ------------------- | ------------------------------ | ------------------------------------ | -------------------------------------------------------------------- |
| Trigger frequency   | How often chains start.        | Cost or duplicate work.              | The event should be reactive to player or runtime changes.           |
| Invoke Mode         | Busy-node behavior.            | Delay, skipped work, or abrupt stop. | A node can receive another chain before it finishes.                 |
| Guard Reject Result | Rejected-branch result.        | Quiet failures or hard stops.        | A condition decides whether work may continue.                       |
| Blackboard scope    | Data ownership and sharing.    | Accidental coupling.                 | Data must be local, scene-shared, or project-shared.                 |
| FlowValue source    | Where a value comes from.      | Null or stale data.                  | The value should come from Blackboard, payload, Target, or Literal.  |
| Subgraph usage      | Reuse and nesting.             | Hidden activation context.           | A repeated behavior deserves one reusable graph path.                |
| Pass Enabled        | Whether a node accepts chains. | Silent Invalid results.              | A branch should be temporarily blocked without removing connections. |

## Design Implications

Use `Abort` when a blocked or busy path means "this behavior must stop now." Use `Invalid` when the branch is allowed to fail quietly. Use `Queue` when order matters more than immediacy. Use `Bypass` when the newest or current state matters more than processing every request.

Use Local Blackboard data until a wider scope has a concrete reason. Local data makes Debug Context and runtime ownership easier to verify. Scene data is useful for shared encounter state. Global data is useful for project-level facts, but it should not become a shortcut for unrelated systems to communicate.

Use payload for event-specific data, such as the object that triggered an event. Use Blackboard data for state that later nodes must read again. Do not call Blackboard values "payload"; they have different lifetimes.

Use subgraphs to reuse behavior, not to hide global managers. Triggers inside subgraphs only run during the activation window of that subgraph.

## Common Misunderstandings

* `Queue` is not always safer. It can preserve stale work and create latency.
* `Invalid` is not an error by itself. It can be the expected quiet result of a branch that does not apply.
* `Abort` is not always a failure. It can be the intended hard stop for a blocked action.
* Global Blackboard scope is not a convenience default. It is a high-coupling scope.
* A hidden value is still active. Detail toggles affect editor display, not runtime behavior.
* Pass Enabled is not the same as deleting a node. Incoming chains return Invalid while the gate is closed.

## Related

* [Invoke and Reject Modes](/flow-core-docs/documentation/reference/invoke-and-reject-modes.md)
* [Graph Debugging](/flow-core-docs/documentation/troubleshooting/graph-debugging.md)
* [Work with Blackboard Data](/flow-core-docs/documentation/how-to-guides/work-with-blackboard-data.md)
* [Lifecycle and Dataflow](/flow-core-docs/documentation/runtime-guide/lifecycle-and-dataflow.md)
* [Terminology](/flow-core-docs/documentation/reference/terminology.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://flow-core.gitbook.io/flow-core-docs/documentation/core-concepts/design-levers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
