# Graph Asset Wrapper

## Stability

Supported Runtime API Level: Advanced

## Goal

Choose or validate the Flow Graph that a `FlowCoreProcess` should run while keeping runtime creation inside the supported graph asset boundary.

## When To Use This

Use a graph asset wrapper when the process should not always run one fixed `FlowGraphAsset`. Typical cases include difficulty-specific graphs, platform variants, mode-specific graphs, downloadable graph packs, or a project validation layer that refuses to create a runtime when required data is missing.

Do not use a wrapper to mutate a graph asset at runtime, share runtime instances, or bypass trigger registration. The wrapper decides which graph creates the runtime; it should not become a custom runtime engine.

## Runtime Contract

`FlowCoreProcess` stores a `FlowGraphAssetBase`. During runtime build, the process prepares its blackboard collection, then calls `CreateRuntime(FlowBlackboardCollection blackboards)` on the assigned asset or wrapper.

The wrapper contract is small but important:

| Requirement                                                                      | Why it matters                                                                         |
| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Return a fresh `FlowGraphRuntime` for each process build.                        | Runtime state, active chains, triggers, and context must not leak between GameObjects. |
| Use the provided `FlowBlackboardCollection`.                                     | Local, Scene, and Global scopes must match the process that is being built.            |
| Delegate normal graph execution to `FlowGraphAsset.CreateRuntime` when possible. | Built-in trigger setup and compiled graph behavior stay intact.                        |
| Return `null` only when no runtime should exist.                                 | A process with no runtime will not execute graph chains.                               |

`CreateRuntime` may be called again when the process rebuilds. Treat it as runtime construction, not a one-time project initialization hook.

## Minimal Wrapper

```csharp
using UnityEngine;
using TwoCatsCode.FlowCore;

[CreateAssetMenu(menuName = "Flow Core/Difficulty Graph Wrapper")]
public sealed class DifficultyGraphWrapper : FlowGraphAssetBase
{
    [SerializeField] private FlowGraphAsset normalGraph;
    [SerializeField] private FlowGraphAsset hardGraph;
    [SerializeField] private bool useHardGraph;

    public override FlowGraphRuntime CreateRuntime(FlowBlackboardCollection blackboards)
    {
        FlowGraphAsset selected = useHardGraph ? hardGraph : normalGraph;
        if (selected == null)
            return null;

        return selected.CreateRuntime(blackboards);
    }
}
```

This wrapper still lets Flow Core create the actual graph runtime. The wrapper only selects which asset is responsible.

## Scene Verification

1. Create the wrapper asset and assign its graph fields.
2. Select a GameObject with `FlowCoreProcess`.
3. Assign the wrapper asset to the process graph field.
4. Bind the same Local Blackboards that the selected graphs expect.
5. Add a visible test result to each candidate graph, such as a `Start` Trigger that logs a different string.
6. Enter Play Mode and confirm the selected graph runs.
7. Switch the wrapper selection, rebuild or re-enter Play Mode, and confirm the alternate graph runs.

If neither graph runs, debug the process as a graph binding issue first: assigned asset, Local Blackboard list, Trigger settings, and Debug Context.

## Failure Modes

| Symptom                                                  | Likely cause                                                  | Fix                                                                                                     |
| -------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Nothing fires in Play Mode.                              | Wrapper returned `null` or selected graph was not assigned.   | Assign a fallback graph or make the missing graph an explicit validation error.                         |
| One GameObject affects another.                          | Runtime instance is shared between processes.                 | Always call `selected.CreateRuntime(blackboards)` for each build.                                       |
| Local Blackboard reads resolve against the wrong object. | Wrapper ignored the provided blackboard collection.           | Pass the exact `blackboards` argument through to the selected graph.                                    |
| Unity or event triggers do not run.                      | Wrapper bypassed normal graph runtime creation.               | Delegate to `FlowGraphAsset.CreateRuntime` unless you are implementing a documented runtime source.     |
| Selection changes are ignored.                           | Process runtime was not rebuilt after changing wrapper state. | Re-enter Play Mode or call the supported process rebuild path after changing the assigned graph source. |

## Common Mistakes

* Storing a `FlowGraphRuntime` in the wrapper asset.
* Using wrapper fields as per-object runtime state.
* Choosing a graph based on Local Blackboard values before confirming those values exist.
* Returning `null` silently for normal gameplay cases.
* Modifying a `FlowGraphAsset` node list at runtime instead of selecting a different asset.

## Related

* [Architecture](/flow-core-docs/documentation/runtime-guide/architecture.md)
* [Lifecycle and Dataflow](/flow-core-docs/documentation/runtime-guide/lifecycle-and-dataflow.md)
* [Extension Points](/flow-core-docs/documentation/api-extension-guide/extension-points.md)
* [Third-party Bridges](/flow-core-docs/documentation/api-extension-guide/third-party-bridges.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/api-extension-guide/graph-asset-wrapper.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.
