logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Namespace Serenity.Global.Application.References

    Classes

    AdoptedIdentityRules

    The pure decision behind adoption's Id renaming: every cloned IFoundationSettings asset — a collection member, a singleton, a prefab's identity-carrying component, all alike — gets a fresh, project-local Id so it never collides with the shipped asset it was cloned from and is unambiguously a NEW asset, never a shipped one re-saved. The CreateGame editor's own adoption-time reference remapper (AdoptedReferenceRemapper) then re-points every reference the adopted set holds so this renaming never stands alone.

    CollectionSettingsSelection

    The rule every COLLECTION settings lookup applies once a project has adopted Serenity content: a shipped asset whose Id has an adopted twin (X beside X_Project, see RenamedId(string)) is dropped, so an adopted project installs the clone it owns instead of installing both.

    Deliberately NOT the same question SingletonSettingsSelection answers. That rule asks "which of these candidates is authoritative for one slot" and decides by OWNERSHIP (the origin:project label). This one asks "is this asset the one another was cloned FROM" and decides by ID PAIRING, without consulting ownership at all: a clone that lost its label would otherwise silently reinstate the duplicate, and the label query costs a second asset round-trip at every call site.

    Engine-agnostic and Unity-free — the caller decides what "Id" means for its own candidate type.

    EffectiveSettingsSet

    The set of settings a COLLECTION-cardinality system installs from, stated once so the runtime lookup and the editor's own boot-scene check cannot drift: what the composition root PINS is the whole set when it pins anything at all, and label discovery answers only for a field left empty.

    A pinned list is taken exactly as authored — nothing added, nothing removed. An author pins a subset precisely to exclude shipped members they do not want installed, so folding discovery back in would silently reinstate them. Leaving a field EMPTY is how a project asks for everything by label, and that branch already prefers an adopted twin over the origin it was cloned from (WithoutShadowedTwins<T>(IReadOnlyList<T>, Func<T, string>, out IReadOnlyList<string>), applied by the discovery loader).

    Engine-agnostic and Unity-free.

    FoundationDistinctReferenceGroup

    One group of PropertyPaths on a single IFoundationSettings owner type whose stored references must each name a DIFFERENT asset. Two fields of the group carrying the same Id is an authoring mistake — the two controls they drive can never be operated independently — and the remaining tables say nothing about it, because a contract row describes one field in isolation.

    FoundationDistinctReferenceGroups

    The declarative table of every FoundationDistinctReferenceGroup — the companion to FoundationReferenceContracts, which describes each field on its own and therefore cannot say that two of them must not name the same asset. Only a field pair whose two controls are operated independently belongs here; a collection row (Options[].Value, ExposedParameters[].Value) never does, since its elements legitimately repeat.

    FoundationReferenceContract

    One declarative row describing a single cross-asset string reference an IFoundationSettings owner type holds: which serialized property carries it, whether the stored value is a Serenity Id or Guid (or the owner's own post-rename Id, for a self-reference like UiOption.ViewId), which settings type the value must resolve against, and how the value's shape must be treated when it is read or rewritten. See FoundationReferenceContracts for the full table this feeds.

    FoundationReferenceContracts

    The complete table of every cross-asset string reference (by Serenity Id or Guid) an IFoundationSettings asset can hold. It is DERIVED, not written: each row is a serialized string field carrying FoundationIdReferenceAttribute, read by FoundationReferenceFieldGraph from the field's own declaration — so the statement lives next to the field it describes, a new foundation type (the package's or an extender's) is covered by annotating its field, and a field nobody annotated is caught by the completeness ratchet over the shipped assets rather than by someone remembering to edit a second list.

    Consumers read this table and nothing else: the project validator and the adoption remapper walk it against real assets (FoundationReferenceWalker), Clone Directory re-points exactly the declared fields onto the clones, SerenityDiscoveryRegistry's id-contracts report is a projection of it, and GameSettingWiringMap looks its wiring targets up here.

    FoundationReferenceFieldGraph

    Reads, by reflection, every serialized string field an IFoundationSettings asset type holds — including the fields of serializable classes nested in it and of arrays/lists of them — and which of those carry a FoundationIdReferenceAttribute. Engine-agnostic: Unity's serialization rules are recognised by attribute NAME, so this compiles and runs without a UnityEngine reference. FoundationReferenceContracts is the declared subset of this graph; the completeness ratchet walks the whole of it.

    A polymorphic [SerializeReference] member (a signal list, an effect list) is read as every concrete serializable subtype of its declared type, all under the member's own path: the walker finds the one that is actually stored there by the property name. A serializable class already on the path being walked (a recursive tree) is visited once, at its first level.

    FoundationStringField

    One serialized string (or string collection) field reached from an IFoundationSettings owner type, with the serialized property path it has on that owner and every FoundationIdReferenceAttribute declared on it. The unit FoundationReferenceFieldGraph enumerates: the contract table is the declared subset, the completeness ratchet reads the whole set.

    PinnedCollectionSelection

    How a PINNED collection on the composition root relates to the project's own adopted clones. A pinned list is the author's chosen set, so adoption re-points it in place rather than replacing it: each pinned member that has an adopted twin becomes that twin at the same position, every other member is left exactly as it was, and nothing is appended — a project-owned definition the author never pinned is reported to them, never added behind their back.

    A list that already holds BOTH an origin and its twin loses the ORIGIN, the way label discovery drops a shadowed one: rewriting it in place would put the twin in twice, and a collection carrying one Id twice is what makes the game-settings service throw at boot. An entry that names nothing keeps its slot — shrinking the author's list silently would hide the hole instead of reporting it.

    The twin link is the Id rename rule (RenamedId(string)). Adoption regenerates a clone's Guid, so there is no Guid lineage to follow.

    Engine-agnostic and Unity-free — the caller decides what "Id" means for its own candidate type.

    In this article
    © 2026 Serenity. All Rights Reserved