Concept: Providers and Identity

A slot stores two things: which provider understands it and an opaque payload that provider defined. Everything else - what it looks like, whether it is ready, what pressing it does - is rebuilt from those every time, by the provider. This is what lets one bar hold abilities, potions, mounts, emotes and macros without the bar knowing any of those words.

Per-bar provider gate
The asset's Providers array is the shared vocabulary for every bar in the layout, but each bar can narrow it: AllowedProviders (empty = all) lists the ProviderIds the bar takes, so one asset serves the whole HUD - the main bar takes abilities while the consumables strip takes only objects. Enforced by the write validator on the server and in the client pre-flight ("This bar does not take that kind of thing"), skipped by TryAutoPlace, warned about by IsDataValid when a default binding violates it, and queryable by pickers via UCrimsonActionBarComponent::IsProviderAllowed.

The provider contract

VerbCalledAnswers
GatherBindableEntriespicker opensWhat may the player choose right now? (FCrimsonBindableEntry: binding + display + filter tags)
ResolveBindinglayout rebuild, stale re-resolve, every 2 sSaved binding -> FCrimsonSlotBindingDisplay (+ the live object). false = stale.
QueryBindingStateevery poll (10 Hz)FCrimsonSlotBindingLiveState: enabled, reason, cooldown, global cooldown, active, charges, count, cost, failure tags.
HandleBindingInputkey / click edgePress or release. Default: press -> ExecuteBinding.
ExecuteBindingwheel confirmDo the thing (a full tap).
GetBindingFilterTagsserver validates a writeThe tags a stored binding carries, for AcceptedEntries.
BindingMatcheshighlights, dedupeDo two bindings mean the same thing?
GetPayloadStructserver validates a writeThe one USTRUCT this provider accepts inside Data.

Providers are Instanced on the layout asset and shared by every player using it, so they hold no per-player state. Everything per-player arrives in FCrimsonSlotBindingContext: the owning player, the layout's provider table (so a composite provider can reach its siblings), and an optional cached ResolvedObject the caller keeps per slot - a hint, never a promise.

Identity, not pointers

The shipped payloads carry an FCrimsonSlotBindingIdentity { TypeTag, Key } rather than an object reference, because the object may not exist when the save is read back, or may be replaced under the binding while playing:

ThingTypeTagKeyWhy that key
Ability implementing ICrimsonSlotBindingPresentableSlotBinding.Identity.Abilitywhatever Get Slot Binding Identity returns - a gameplay-event trigger tag is the durable choice, because the provider sends that tag as an event when it fires the slotSurvives the ability class behind the trigger being swapped out; the same key CrimsonCore's authored radial action dispatches on.
Stock UGameplayAbilitySlotBinding.Identity.Abilityclass path (compared by name, never loaded)No richer identity exists.
Inventory itemSlotBinding.Identity.Objectitem definition class pathBind Healing Potion, not this stack: drink the last one, buy more, the slot resolves to the new stack.

The bridges

The generic providers include nothing from your ability, item or input systems. They talk to whatever is there through two interfaces and an adapter, all owned by this plugin, and fall back gracefully when nothing implements them:

InterfaceImplemented byGivesWithout it
ICrimsonSlotBindingPresentableYour ability classes, your item instances - anything with a name and an iconidentity, display (name/icon/description), count, filter tagsclass name, no icon, class-path identity
ICrimsonSlotBindingObjectResolverYour inventory / bag / stash component - any container of yoursidentity -> live object + total count; what is bindablethe Objects provider resolves nothing
UCrimsonSlotBindingAbilityAdapter (subclass)A subclass you set on the Ability provider's Adapter, or as FCrimsonActionBarIntegrationHooks::DefaultAbilityAdapterClassTap / Hold / Toggle input semantics, charges, global cooldown, instance-safe cost checkgameplay event / TryActivateAbility; no charge badge; engine CheckCost
Where the shipped providers live and why
The base provider, _Tag, _Ability, _Object and _Sequence all live here in CrimsonActionBar; CrimsonCore (free to download, compiles only with all Crimson plugins installed) adds UCrimsonCoreSlotBindingProvider_Equipment. A picker of yours can list the same providers in its own Providers array.