Attributes — Public API¶
The supported surface. Anything not listed here is internal and may change without a major version — including the internal value store and the shipped adapter component, which is wired in the inspector rather than constructed.
This page is kept against Tests/EditMode/ApiSnapshots/Lib/Goldens/RevFramework.Attributes.PublicApi.txt. If the two disagree, the golden is right and this page is stale.
Supported surface at a glance¶
| Type | Kind | What it is |
|---|---|---|
AttributeSet | MonoBehaviour | The owner's container: authored rows, runtime ids, bounds, events |
AttributeEntry | struct | One authored row: id, base value, optional bounds |
IAttributeSource | interface | The read seam: TryGetValue(id, out value) |
IAttributeModifierProvider | interface | Contributes modifiers from the owner's chain |
IAttributeCombiner | interface | Folds base and contributions into an effective value — yours |
AttributeModifier | readonly struct | One contribution: a value and an opaque tag |
AttributeDelta | readonly struct | Change payload: owner, id, before, after |
AttributeSetSnapshot / AttributeBaseValue | class / struct | What one owner persists: base values only |
AttributesSaveParticipant | class | The save participant, in Integrations/Save/Attributes |
AttributeSet¶
// Reading
bool TryGetValue(string attributeId, out float value); // effective (IAttributeSource)
bool TryGetBaseValue(string attributeId, out float value); // stored base
bool HasAttribute(string attributeId);
void GetAttributeIds(List<string> results); // cleared, sorted ordinal
// Writing
bool SetBaseValue(string attributeId, float value); // creates when the id is new
// Combining
void SetCombiner(IAttributeCombiner combiner); // code wins; null falls back to the slot
// Persistence
AttributeSetSnapshot CaptureSnapshot();
void RestoreSnapshot(AttributeSetSnapshot snapshot); // a rewind; silent
// Events
event Action<AttributeDelta> BaseValueChanged; // plus the inspector UnityEvent mirror
The behavioural details each of these carries — trimming, clamping, refusals, event timing — are the contract, and they live in the System Guarantees Matrix rather than being repeated here loosely.
Reading¶
TryGetValue is total: null, blank and unknown ids return false, never an exception. With a combiner wired it collects providers and combines; without one it returns the clamped base and consults nobody. TryGetBaseValue always answers from stored state, combiner or not — the pair is how a HUD shows "12 (+3)".
Writing¶
SetBaseValue trims the id, refuses blank ids and non-finite values loudly, clamps into the attribute's bounds, and creates the attribute when the id is new — created ids are unbounded, because bounds are authored configuration. The return value says whether the write was accepted, not whether the value changed.
Persistence¶
CaptureSnapshot returns base values only, sorted by id so identical state serialises identically. RestoreSnapshot is a rewind: authored rows re-seeded, saved values applied on top through the same clamping a live write gets, runtime-created ids the snapshot does not mention removed, and no events fired. Most projects never call either directly — register an AttributesSaveParticipant with the save manager and the coordinator drives them.
manager.Register(new AttributesSaveParticipant());
AttributeEntry¶
Authored rows are plain serialized fields: id, baseValue, and bounds as has-flags plus values (hasMin/min, hasMax/max). Rows that cannot mean anything — blank or duplicate ids, non-finite numbers — are reported and skipped, never repaired; an inverted bound pair is reported and ignored as a pair.
Authored rows are read once
The rows seed the container on first use. Editing them in the inspector during Play Mode does not rewrite live values — the same posture Health takes with its defaults asset. OnValidate reports inverted bound pairs at authoring time.
What is deliberately not public¶
- The value store (
Core/Internal) — reach values throughAttributeSetor the seams. AttributeLevelSource— a component you add fromRevFramework ▸ Integrations ▸ Attributes ▸ Craftingin the Add Component menu and configure in the inspector, not a type you construct. Its mapping decisions are documented on the component and in Integration Surfaces.- Removal. There is no
RemoveAttribute. A runtime-created id lives until a restore rewinds it away; if removal turns out to be a real need, it is an additive API later rather than a compatibility hazard now.