vvvv-spreads

Helps write code using vvvv gamma's Spread<T> immutable collection type and SpreadBuilder<T>. Use when working with Spreads, SpreadBuilder, collections, arrays, iteration, mapping, filtering, zipping, accumulating, or converting between Span and Spread. Trigger whenever the user writes collection-processing C# code in vvvv — even if they say 'list', 'array', or 'IEnumerable' instead of Spread, this skill likely applies.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vvvv-spreads" with this command: npx skills add Tebjan Halm/vvvv-spreads

vvvv Spreads

What Are Spreads

Spread<T> is vvvv's immutable collection type, conceptually similar to ImmutableArray<T>. It is the primary way to pass collections between nodes.

Key properties:

  • Immutable — never modify in place, always create new spreads
  • Value semantics — two spreads with same elements are considered equal
  • Cyclic indexing — in visual patches, indexing wraps around (not in C# API)
  • Never null — use Spread<T>.Empty instead of null

Creating Spreads

SpreadBuilder (Primary Method)

var builder = new SpreadBuilder<float>(expectedCount);
for (int i = 0; i < count; i++)
    builder.Add(ComputeValue(i));
Spread<float> result = builder.ToSpread();

From Existing Data

// From array (extension method)
Spread<int> fromArray = new int[] { 1, 2, 3 }.ToSpread();

// From array (static factory)
Spread<Waypoint> fromResult = Spread.Create(resultArray);

// Empty spread (NEVER use null)
Spread<float> empty = Spread<float>.Empty;

// Single element
var single = new SpreadBuilder<float>(1);
single.Add(42f);
Spread<float> one = single.ToSpread();

Accessing Elements

// Always check Count before indexing
if (spread.Count > 0)
{
    float first = spread[0];
    float last = spread[spread.Count - 1];
}

// Iterate (preferred — no allocation)
foreach (var item in spread)
    Process(item);

// Index access in loop
for (int i = 0; i < spread.Count; i++)
    Process(spread[i]);

Common Patterns in C#

Map (Transform Each Element)

public static Spread<float> Scale(Spread<float> input, float factor = 1f)
{
    var builder = new SpreadBuilder<float>(input.Count);
    foreach (var value in input)
        builder.Add(value * factor);
    return builder.ToSpread();
}

Filter

public static Spread<float> FilterAbove(Spread<float> input, float threshold = 0.5f)
{
    var builder = new SpreadBuilder<float>();
    foreach (var value in input)
    {
        if (value > threshold)
            builder.Add(value);
    }
    return builder.ToSpread();
}

Zip (Process Two Spreads Together)

public static Spread<float> Add(Spread<float> a, Spread<float> b)
{
    int count = Math.Max(a.Count, b.Count);
    var builder = new SpreadBuilder<float>(count);
    for (int i = 0; i < count; i++)
    {
        float va = a.Count > 0 ? a[i % a.Count] : 0f;
        float vb = b.Count > 0 ? b[i % b.Count] : 0f;
        builder.Add(va + vb);
    }
    return builder.ToSpread();
}

Accumulate (Running Total)

public static Spread<float> RunningSum(Spread<float> input)
{
    var builder = new SpreadBuilder<float>(input.Count);
    float sum = 0f;
    foreach (var value in input)
    {
        sum += value;
        builder.Add(sum);
    }
    return builder.ToSpread();
}

ReadOnlySpan as High-Performance Alternative

For hot-path output (e.g., per-frame simulation data), ReadOnlySpan<T> avoids allocation entirely:

[ProcessNode]
public class ParticleSimulator
{
    private ParticleState[] _states;

    public ReadOnlySpan<ParticleState> Update(SimulationConfig config, float deltaTime)
    {
        // Simulate into pre-allocated array — zero allocation
        Simulate(_states, config, deltaTime);
        return _states.AsSpan();
    }
}

Use Spread<T> for infrequent config inputs; use ReadOnlySpan<T> for high-frequency frame data.

Performance Rules

  • Pre-allocate builder: new SpreadBuilder<T>(expectedCount) when count is known
  • No LINQ in hot paths: .Where(), .Select(), .ToList() create hidden allocations
  • Cache spreads: If output doesn't change, return the cached spread reference
  • Avoid repeated .ToSpread(): Build once, output the result
  • For large spreads: Consider Span<T> internally, convert to Spread at the API boundary
  • Spread change detection: Since Spreads are immutable, reference equality (!= or ReferenceEquals) is sufficient — if the reference changed, the content changed

Spreads in ProcessNodes

[ProcessNode]
public class SpreadProcessor
{
    private Spread<float> _lastInput = Spread<float>.Empty;
    private Spread<float> _cachedOutput = Spread<float>.Empty;

    public void Update(
        out Spread<float> output,
        Spread<float> input = default)
    {
        input ??= Spread<float>.Empty;

        if (!ReferenceEquals(input, _lastInput))
        {
            var builder = new SpreadBuilder<float>(input.Count);
            foreach (var v in input)
                builder.Add(v * 2f);
            _cachedOutput = builder.ToSpread();
            _lastInput = input;
        }

        output = _cachedOutput;
    }
}

For more code examples, see examples.md.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Gpu Cluster Manager

Turn your spare GPUs into one inference endpoint. Auto-discovers machines on your network, routes requests to the best available device, learns when your mac...

Registry SourceRecently Updated
Coding

Local Llm Router

Local LLM model router for Llama, Qwen, DeepSeek, Phi, Mistral, and Gemma across multiple devices. Self-hosted local LLM inference routing on macOS, Linux, a...

Registry SourceRecently Updated
Coding

yuhang

一个"制造技能的技能"。这个工具自动化了将任意 GitHub 仓库转换为标准化 Trae 技能的全过程,是扩展 AI Agent 能力的核心工具。

Registry SourceRecently Updated
Coding

Venn Nino

Safely connects Gmail, Calendar, Drive, Atlassian (Jira/Confluence), Notion, GitHub, Salesforce, and dozens of other enterprise tools via a single MCP endpoi...

Registry SourceRecently Updated