# FlowGraphObject vs FlowGraphInstanceObject: Understanding Container Differences in Ceres

> Understand the difference between FlowGraphObject and FlowGraphInstanceObject in Ceres. Learn how FlowGraphObject embeds graph data and FlowGraphInstanceObject references an external asset.

- Repository: [AkiKurisu/ceres](https://github.com/akikurisu/ceres)
- Tags: deep-dive
- Published: 2026-02-24

---

**The difference between FlowGraphObject and FlowGraphInstanceObject containers is that FlowGraphObject embeds graph data directly within the MonoBehaviour via source-generated code, while FlowGraphInstanceObject references an external FlowGraphAsset to supply the graph data.**

Both classes are Unity MonoBehaviours in the akikurisu/ceres repository that expose runtime FlowGraphs, but they implement the `IFlowGraphContainer` interface through fundamentally different storage mechanisms. Understanding these container patterns is essential for deciding whether to store graph data per-object or share it across multiple instances.

## Container Source: Embedded vs External Asset

### FlowGraphObject: Self-Generated Container

In [`Runtime/Flow/FlowGraphObject.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/FlowGraphObject.cs), the `FlowGraphObject` class uses source generation to turn the MonoBehaviour itself into an `IFlowGraphContainer`. The `[GenerateFlow(GenerateRuntime = false, GenerateImplementation = true)]` attribute (lines 136-144) triggers the generator to create a partial class that stores persistent `FlowGraphData` as a hidden sub-asset inside the component.

This approach makes each GameObject fully own its graph data. The generated implementation handles serialization automatically, embedding the graph definition directly within the prefab or scene object.

### FlowGraphInstanceObject: Asset Reference Container

Conversely, [`Runtime/Flow/FlowGraphInstanceObject.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/FlowGraphInstanceObject.cs) (lines 7-15) defines an explicit container reference:

```csharp
public class FlowGraphInstanceObject : FlowGraphObjectBase
{
    [SerializeField] internal FlowGraphAsset graphAsset; // External container
    
    // Container calls forwarded to graphAsset
}

```

Rather than generating container code, this class implements `IFlowGraphContainer` by delegating all calls to the serialized `FlowGraphAsset` field. The graph data lives in a separate asset file, allowing multiple components to reference the same graph definition.

## Runtime Container Resolution

The `FlowGraphObjectBase` class determines which container to use at runtime through the `GetContainer()` method implemented in [`Runtime/Flow/FlowGraphObject.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/FlowGraphObject.cs) (lines 76-90):

```csharp
protected IFlowGraphContainer GetContainer()
{
    // Check for external asset reference first
    if (this is FlowGraphInstanceObject instanceObject && instanceObject.graphAsset != null)
    {
        return instanceObject.graphAsset;
    }
    
    // Fall back to self-contained container
    return this as IFlowGraphContainer;
}

```

This logic ensures that `FlowGraphInstanceObject` instances return their referenced `FlowGraphAsset`, while `FlowGraphObject` instances return themselves as the container.

## Implementation Architecture

### Source Generation vs Explicit Implementation

**FlowGraphObject** relies on compile-time code generation:

- The `partial class FlowGraphObject` is augmented by the Ceres source generator
- The generator implements `IFlowGraphContainer` and `IFlowGraphRuntime` interfaces automatically
- Graph data persists as a sub-asset within the MonoBehaviour (visible in [`Runtime/Flow/Models/FlowGraph.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/Models/FlowGraph.cs) interface definitions)

**FlowGraphInstanceObject** uses runtime composition:

- Explicitly declares the `graphAsset` field of type `FlowGraphAsset` (defined in [`Runtime/Flow/FlowGraphAsset.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/FlowGraphAsset.cs))
- No source generation required for container implementation
- All container interface methods forward to the referenced asset

### Data Persistence Locations

- **FlowGraphObject**: Stores `FlowGraphData` inside the component as a hidden serialized object (self-contained)
- **FlowGraphInstanceObject**: Stores data in the external `FlowGraphAsset` file (shared resource)

## When to Use Each Container Type

**Choose FlowGraphObject when:**
- Each GameObject requires unique graph data
- You want self-contained prefabs without external dependencies
- The graph should serialize with the scene or prefab directly

**Choose FlowGraphInstanceObject when:**
- Multiple objects must share identical graph logic
- Memory efficiency is critical (avoid duplicating graph data across instances)
- You need to update graph logic in one place (the asset) and affect all instances

## Summary

- **FlowGraphObject** implements a **self-container pattern** where the MonoBehaviour itself becomes the `IFlowGraphContainer` through source-generated code, embedding `FlowGraphData` as a sub-asset
- **FlowGraphInstanceObject** implements an **external-container pattern** that references a `FlowGraphAsset` to supply graph data, enabling data sharing across multiple GameObjects
- The `GetContainer()` method in `FlowGraphObjectBase` automatically detects which pattern is in use at runtime
- Use `FlowGraphObject` for per-object unique graphs and `FlowGraphInstanceObject` for shared, asset-based graph definitions

## Frequently Asked Questions

### Can I switch a FlowGraphObject to use an external asset without changing the component type?

No, the container architecture is determined by the class type itself. `FlowGraphObject` relies on source-generated container implementation that embeds data within the MonoBehaviour, while `FlowGraphInstanceObject` explicitly implements container forwarding to a `FlowGraphAsset` field. Migrating between patterns requires changing the component type and manually transferring graph data to a `FlowGraphAsset` file.

### Where is the graph data physically stored in a FlowGraphObject?

According to the source code in [`Runtime/Flow/FlowGraphObject.cs`](https://github.com/akikurisu/ceres/blob/main/Runtime/Flow/FlowGraphObject.cs), the data persists as a hidden sub-asset directly inside the MonoBehaviour component. The source generator creates this embedded storage when processing the `GenerateFlow` attribute, making the graph data serialize as part of the GameObject or prefab rather than as a separate asset file.

### Does modifying a FlowGraphAsset at runtime affect all FlowGraphInstanceObject instances?

Yes, since `FlowGraphInstanceObject` forwards all `IFlowGraphContainer` calls to its shared `graphAsset` reference, any runtime modifications to that asset would propagate to all instances using it. For independent runtime states, you should instantiate unique copies of the graph data or use `FlowGraphObject` instead, which stores data per-instance.

### How does the Ceres source generator know to implement IFlowGraphContainer for FlowGraphObject?

The `GenerateFlow` attribute applied to the partial class in [`FlowGraphObject.cs`](https://github.com/akikurisu/ceres/blob/main/FlowGraphObject.cs) includes the parameters `GenerateRuntime = false` and `GenerateImplementation = true`. This configuration signals the Ceres source generator to create the container implementation and embed the graph data within the component, as seen in the generated code linked through the attribute at lines 136-144 of the source file.