Skip to content

Attributes — Core / Internal

Folder Overview

The state behind an owner's attribute container.

Everything here is internal. It is not an extension point — the seams are IAttributeSource, IAttributeModifierProvider and IAttributeCombiner in Abstractions, and those are the surfaces to build against.


What Lives Here

AttributeStore

A pure dictionary of id to base value and bounds. No scene, no components, no Unity lifecycle — which is what lets AttributeSet behave identically in EditMode tests, where Awake never runs, and in a player. The component creates a store lazily on first use and delegates to it.

Its internal contract: callers supply canonical ids (trimmed, non-blank) and finite values, and validation lives at the component boundary where there is a context object to warn against. Seeding from authored rows is the exception — the rows are validated here, where they are first read, and unusable rows are reported and skipped rather than repaired.


Important Notes

Runtime-created attributes are unbounded

Bounds come from authored rows, and an id created by the first write to it has no row to read them from. That is a property of the design, not an oversight: bounds are authoring-time configuration, and a later authored-definition layer can supply them additively without changing anything here.

Re-seeding is how a restore rewinds

A restore re-seeds the store from the authored rows and applies the saved base values on top, so a runtime-created attribute that is not in the save is gone afterwards — at the moment the save was taken, it did not exist. The re-seed does not repeat the authoring warnings the first seed already reported.