Lost Lily/Grid ToolkitDocs 1.0
Table of Contents

Choose structure instance IDs

When to use

Choose an ID strategy when placed structures must retain identity across actions, saves, replays, network messages, or project-owned game objects. A structure definition ID identifies a reusable type; a structure instance ID identifies one placement. The instance ID provider is only the fallback that creates that value when the request does not supply one.

Before you start

Decide whether the caller already owns a stable identity. Pass that ID explicitly whenever it is part of saved or networked game state. An ID provider is used only when placement omits the ID.

Procedure

Strategy Choose it when
Explicit instance ID A save record, entity, or command already owns the identity.
GridDeterministicStructureInstanceIdProvider Replays, tests, or synchronized simulations need reproducible generated IDs.
GridGuidStructureInstanceIdProvider Placements need globally unique IDs and reproducibility is not required.
Project implementation of IGridStructureInstanceIdProvider Identity follows a save, network, or domain naming convention.

Custom providers run while an action plan is built. Read only the supplied planning context, return a non-empty ID that is absent from ExistingInstanceIds, and do not mutate the board or external state. When a preferred project ID already exists, choose the next available suffix deterministically so repeated previews produce the same plan.

Excerpt — generate a collision-free deterministic instance ID. Tested using public APIs.

public sealed class DocumentationStructureInstanceIdProvider :
    IGridStructureInstanceIdProvider
{
    private readonly string prefix;

    public DocumentationStructureInstanceIdProvider(string prefix)
    {
        this.prefix = string.IsNullOrWhiteSpace(prefix)
            ? throw new ArgumentException("An ID prefix is required.", nameof(prefix))
            : prefix.Trim();
    }

    public string CreateId(GridStructureInstanceIdContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        string preferred =
            $"{prefix}.{context.DefinitionId}.r{context.SourceRevision + 1:D6}.p{context.PlacementOrdinal:D3}";
        HashSet<string> existing = new(
            context.ExistingInstanceIds,
            StringComparer.Ordinal);
        if (!existing.Contains(preferred))
            return preferred;

        for (int suffix = 1; suffix < int.MaxValue; suffix++)
        {
            string candidate = $"{preferred}.{suffix:D3}";
            if (!existing.Contains(candidate))
                return candidate;
        }

        throw new InvalidOperationException("No unique structure instance ID is available.");
    }
}

For an authored project, assign the provider to the runtime defaults asset or the relevant board override, then generate runtime settings. For a code-owned board, include it in the GridRuntimeConfiguration supplied when the state is built.

Result

Every placed instance has a non-empty identity from the explicit request or the configured provider. Preview and Apply plan against the same identity rules, while applying an action performs fresh planning against current state.

Troubleshooting

Symptom Check
Replays produce different IDs Use the deterministic provider and keep its seed inputs stable.
Restore cannot match a structure Preserve the saved instance ID rather than generating a replacement during restore.
A custom provider duplicates an ID Check ExistingInstanceIds and add a deterministic suffix, or use an explicit project-owned ID.