@rbxts/a-plant-generator - v0.2.0
    Preparing search index...

    Seed determinism

    Generation is deterministic for the same compiled model, seed, iterations, parameters, time, and limits. This example uses a weighted grammar so the first two trees replay exactly while the remaining trees change only the seed.

    Four generated trees: two identical seed replays followed by two alternate seeded topologies.

    Left to right: seed 42 reference, seed 42 replay, seed 7, and seed 99. Canopy color is a diagnostic aid; the matching cyan pair has identical graph hashes.

    import {
    PlantCompiler,
    PlantGenerator,
    hashBranchGraph,
    symbol,
    type ModelSpecification,
    } from "@rbxts/a-plant-generator";

    const stochasticTree: ModelSpecification = {
    schemaVersion: 1,
    id: "seed-determinism-tree",
    grammar: {
    alphabet: ["A", "F", "+", "-", "^", "&", "\\", "/", "[", "]", "!"].map((id) => ({ id })),
    axiom: [symbol("A")],
    productions: [
    {
    id: "wide",
    predecessor: "A",
    weight: 1,
    successor: [
    symbol("F", 1.65),
    symbol("!", 0.78),
    symbol("["),
    symbol("+", 0.62),
    symbol("^", 0.22),
    symbol("A"),
    symbol("]"),
    symbol("["),
    symbol("-", 0.45),
    symbol("\\", 0.55),
    symbol("A"),
    symbol("]"),
    symbol("A"),
    ],
    },
    {
    id: "narrow",
    predecessor: "A",
    weight: 1,
    successor: [
    symbol("F", 1.35),
    symbol("!", 0.82),
    symbol("["),
    symbol("+", 0.32),
    symbol("/", 0.7),
    symbol("A"),
    symbol("]"),
    symbol("["),
    symbol("-", 0.32),
    symbol("&", 0.18),
    symbol("A"),
    symbol("]"),
    symbol("A"),
    ],
    },
    ],
    branchOpenSymbol: "[",
    branchCloseSymbol: "]",
    },
    turtle: { stepSize: 2.2, initialWidth: 0.46, widthDecay: 0.86, unknownSymbolPolicy: "ignore" },
    geometry: { enabled: false },
    organs: { terminalLeafKind: "leaf", leafDensity: 1 },
    };

    const model = PlantCompiler.compile(stochasticTree);
    const options = { seed: 42, iterations: 5 } as const;

    export const reference = PlantGenerator.generate(model, options);
    export const replay = PlantGenerator.generate(model, options);
    export const seed7 = PlantGenerator.generate(model, { ...options, seed: 7 });
    export const seed99 = PlantGenerator.generate(model, { ...options, seed: 99 });

    export const deterministicHashes = {
    reference: hashBranchGraph(reference.branchGraph),
    replay: hashBranchGraph(replay.branchGraph),
    seed7: hashBranchGraph(seed7.branchGraph),
    seed99: hashBranchGraph(seed99.branchGraph),
    };

    export const replayMatches = deterministicHashes.reference === deterministicHashes.replay;

    replayMatches is a topology check, not an image comparison. A networked game can replicate the compact descriptor and regenerate the same plant instead of sending every branch transform.

    Try changing iterations in only one call; the hashes should then differ even when the seed matches.