If the non-negotiables are “works inside Unity,” “interoperable with all Unity systems,” and targets creative coders + large live AV, I’d bias toward a TouchDesigner-style “typed operator graph + cooking (demand-driven) + component encapsulation” as the primary architecture — and then deliberately graft in vvvv’s spread/vectorization as a data model feature rather than as the whole execution model.
Unity already has strongly-typed subsystems with clear boundaries and lifecycles:
- Rendering (SRP, RenderGraph, textures/buffers/materials)
- Animation (Playables)
- Audio (DSP graph-ish constraints, audio thread)
- Physics
- UI
- Entities/DOTS + Jobs + Burst
- Timeline / time sources
- Serialization / assets
A TD-like operator family approach maps cleanly onto Unity because you can create first-class “domains” that align with Unity primitives:
- GPU image/texture graph (TOP-like) → RenderTextures, GraphicsBuffers, compute kernels
- Time-sampled signals graph (CHOP-like) → animation curves, audio control-rate signals, envelope followers
- Geometry graph (SOP-like) → Mesh, VFX Graph style buffers
- Text/table graph (DAT-like) → ScriptableObjects, JSON, tables, OSC/MIDI mappings
- Container graph (COMP-like) → Prefabs / Subgraphs / reusable rigs
And the “cook only when needed” mentality is exactly what you want when Unity is already deciding when to render, animate, simulate, etc. You want your graph to participate in Unity’s scheduling, not fight it.
vvvv’s killer feature for creative coders is the ergonomics of multiplicity:
- Make one patch, drive 1 object or 10,000 objects without manually instancing networks.
- “Spreads” (vectorized lists) + auto-alignment rules are extremely productive.
So: keep TD-ish typed domains + cook model, but make every operator vectorization-aware:
- Any input can be a scalar or a “spread”
- Operators define broadcasting rules (like numpy): scalar ⨉ list, list ⨉ list, etc.
- Under the hood, compile “spread ops” to Burst jobs (or GPU kernels if the domain is GPU)
That gives you TD’s composable “systems” feel and vvvv’s data-parallel expressiveness.
Unity doesn’t have one loop — it has many:
- Update / LateUpdate / FixedUpdate
- Render loop(s) (SRP)
- Audio thread
- Playables evaluation
- Editor vs Play Mode differences
Hard part: defining when each domain cooks and keeping it deterministic.
- If you’re sloppy, creative users will get “it works until it doesn’t” behavior, especially live.
You’ll need: explicit time sources (wall clock, audio clock, timeline time, LTC/MTC) and a routing system so operators know which clock they’re on.
- Audio callbacks must be real-time safe: no allocations, no locks, no main-thread calls.
- Many Unity APIs are main-thread-only.
- GPU work is asynchronous and tricky to synchronize without stalling.
You’ll need: a hard separation:
- Control-rate graph (main thread / jobs)
- Audio-rate graph (audio thread safe subset)
- GPU graph (render thread / command buffers)
…and clean bridges between them.
Node graphs in C# can become death-by-a-thousand-cuts:
- per-node allocations
- boxing/unboxing
- virtual dispatch
- copying big arrays per connection
You’ll need:
- value-based data containers (NativeArray, GraphicsBuffer)
- pooled memory + explicit lifetimes
- compile graphs to efficient executors (Burst jobs / codegen)
- “dirty propagation” so only affected subgraphs run
Unity systems expect to own certain things:
- Meshes/materials/textures
- Animation clips / playable graphs
- GameObject hierarchies or Entities
- Serialized assets
If your graph owns everything, Unity integration will feel bolted-on.
If Unity owns everything, your graph becomes a weak “controller.”
You’ll need a clean ownership model:
- Some operators produce assets/buffers
- Some operators bind to existing Unity objects (non-owning views)
- Some operators author reusable rigs as assets (subgraphs, prefabs, scriptable objects)
Creative coders tolerate rough edges; live AV teams do not.
You’ll need:
- live probing/scope tools (like CHOP scopes)
- GPU texture viewers
- “why is this cooking?” introspection
- dependency graphs, performance profiling per operator
- stable undo/redo and serialization through Unity domain reloads
Large productions need:
- graph diff/merge in source control
- stable GUID-based references
- forward/backward compatibility
- robust asset import/reimport behavior
This is often harder than the runtime.
TD-style typed operator/component graph + cook-on-demand + explicit domain boundaries, with vvvv-style spreads/broadcasting as a pervasive data feature, and Burst/Jobs + GPU backends as the primary execution strategy.
If you want, I can sketch a concrete architecture blueprint (core interfaces, data types, scheduling, and how it plugs into SRP/RenderGraph, Playables, DOTS, and audio) at the level of “here are the 10 operator families you start with and how cooking/dirty propagation works.”