How-To: Make an Item Usable

Goal: give an item a Use action that applies gameplay effects, spends the item and starts a cooldown - from the context menu, a double-click, or an action bar slot, all through one ability you grant once.

Prerequisites
How-To: Author an Item Definition, and an ability system component on your player. The bridge is ICrimsonUsableObject (Usable/ICrimsonUsableObject.h): this plugin ships the interface and the fragment that answers it, and you grant one ability that reads it. See API Reference for the full contract.
One ability, not one per item
You author GA_UseItem once and grant it once. Every consumable in the game routes to it and supplies its own effects and cooldown, so a hundred potions still cost the ability system component a single spec. There is no per-item ability to make.

1. Register the tags

Two project tags: one gameplay event that reaches the ability, and one cooldown identity per item (or per family of items that should share a cooldown). Add them in Project Settings -> GameplayTags, or in an ini:

ini
[/Script/GameplayTags.GameplayTagsList]
GameplayTagList=(Tag="Ability.Event.UseItem",DevComment="Activates the shared use-item ability.")
GameplayTagList=(Tag="Ability.Cooldown.Item.HealthPotion",DevComment="Cooldown identity for the health potion.")
Restart after an ini edit
Tags added to an ini by hand are only registered on editor start. Tags added through Project Settings are available immediately.

2. Author the effect the item applies

A plain UGameplayEffect Blueprint. Leave the NUMBER off it: set the modifier's Magnitude Calculation Type to Set by Caller and give it a Data Tag, and the item supplies the value at use time. One authored heal then serves the minor, greater and supreme potions instead of three near-identical assets that drift apart the first time the heal formula changes.

ForDuration PolicyModifierMagnitude
An instant healInstantyour health set's incoming-healing attribute, Add (Base)Set by Caller, Data Tag SetByCaller.Value
A heal over timeHas Durationyour health set's incoming-healing attribute, Add (Base)Set by Caller, Data Tag SetByCaller.Value
Over-time effects need two more fields
Set Period to how often it ticks (1.0 for once a second), and set Duration Magnitude to Set by Caller with its own Data Tag so the item can name the window. The per-tick amount is what the modifier's magnitude carries - a 50-over-5-seconds draught ticks 10 five times.
Prefer a meta attribute over the pool
If your attribute set exposes an incoming-healing meta attribute, modify that and never the health pool directly. A meta attribute is where a set folds the amount into the pool, clamps it to the effective maximum, and applies any healing modifiers - writing the pool directly bypasses all of it.

3. Create the use-ability

One ability, granted to the player like any other, answers the event for every consumable in the game. Set its Ability Triggers to a Gameplay Event on Ability.Event.UseItem, its Instancing Policy to Instanced Per Execution (the ability carries which object this activation is for, so a shared instance would let two uses in the same frame overwrite each other), and its Net Execution Policy to Local Predicted. Leave the ability's own Cooldown Gameplay Effect Class unset unless you want a shared lockout across every consumable - the per-item cooldown comes from the item, not from here.

In the abilityCall on the object (all ICrimsonUsableObject)
Resolve what is being usedThe triggering FGameplayEventData carries it in OptionalObject - it is a replicated subobject, so the client and the server resolve the very same one.
Check before anything is spentCanBeUsedBy(User, OutReason). Asked on both sides; end the ability and show OutReason when it says no.
Pay for itCommit the ability, then GetUseCooldown(OutCooldown) and apply CooldownEffect for BaseSeconds, granting CooldownTag for the duration.
Do the thingGetUseGameplayEffects(OutEffects) and apply each Effect, feeding its SetByCallerMagnitudes in as SetByCaller values.
Spend itConsumeUse(User) under authority only. false means nothing was spent and the use must be abandoned.

Create a Gameplay Ability Blueprint, name it GA_UseItem, and set the three properties above in Class Defaults. Then build the graph from the table: Event ActivateAbilityFromEvent -> break the payload -> Can Be Used By (Branch) -> Commit Ability -> Get Use Cooldown -> Get Use Gameplay Effects -> Consume Use (Has Authority branch). Add it to the ability set you already grant your player.

Want a drink animation? Commit first, then play your montage and run the effects-and-consume half from an anim notify. Because the cooldown is paid at commit, the window is not spammable while the montage plays.

4. Add the Consumable fragment to the item

Open the item definition and add UCrimsonInventoryItemFragment_Consumable to Fragments. This is the whole integration - the item now answers ICrimsonUsableObject, and every path that offers a Use finds it.

PropertyFor a health potionWhat it does
UseEventTagAbility.Event.UseItemWhich ability answers. Per item, so a potion, a bomb and a scroll can reach three different abilities from the same bar. Unset makes the item inert everywhere.
EffectsToApplyone entry: GE_Item_HealthPotionThe effects, each with the SetByCaller magnitudes this item feeds it. For the potion: key SetByCaller.Value, value 50.0. The number lives here, not on the effect.
ApplicationInstantWhether the effects land at once or run for a window. Over Time reveals the two duration fields below.
DurationSeconds(hidden)Over Time only. How long the effects run. Fed to every effect under the tag below.
DurationSetByCallerTag(hidden)Over Time only. Data Tag of the effect's duration SetByCaller. Leave unset to let the effect keep its authored duration.
ConsumeCount1How much of the stack one use spends. 0 makes the item reusable without being consumed - a refillable flask, a rune that only pays a cooldown.
CooldownTagAbility.Cooldown.Item.HealthPotionGranted on the user while the item is on cooldown. Two items sharing a tag share a cooldown; different tags run on independent clocks even though one ability serves both. Unset means no cooldown.
CooldownSeconds10.0The authored length, before modifiers and the user's cooldown recovery rate.
CooldownEffectyour shared cooldown effectCarries the cooldown. Its duration is overwritten per use; CooldownTag is what keeps this item's cooldown separate from everything else using the same effect.
One effect, many strengths
A greater potion is the same EffectsToApply entry with 75.0 instead of 50.0, and a regeneration draught is Application = Over Time plus a duration - all three pointing at authored effects that never mention a number. That is the whole reason the magnitudes live on the item.
The tags must match exactly
If nothing supplies a Data Tag the effect asks for, the engine logs Unable to find SetByCaller magnitude and that modifier evaluates to ZERO. The effect still applies and quietly does nothing, which reads like the use never fired at all. The fragment validates this on save, so a mismatch is reported against the item rather than discovered in play - see Validation below.

Set the definition's ItemType too (for example Item.Type.Consumable) - the type action set in the next step is keyed on it.

5. Offer Use in the context menu

From your UI, call UCrimsonUsableStatics::SendUseEvent for the item (or your own menu's Use action). (CrimsonCore - requires all Crimson plugins) ships UCrimsonInventoryContextAction_Use as the default action of its item context menu.

The entry hides itself on items with no Consumable fragment, and on vendor stock, loot and container contents. It grays out with a reason when the player has none left or the item is still on cooldown.

Use is an OwningClient action (ExecutionPolicy on UCrimsonContextAction): picking it runs on the player's own machine and sends the item's use event there, the same path as an action bar press. That is not optional - the use ability is locally predicted, and GAS only triggers a locally predicted ability from a gameplay event where the ability system is locally controlled, so an event sent by the server for a remote client is dropped silently. The ability still re-checks CanBeUsedBy and spends through ConsumeUse under authority, so nothing is trusted client-side.

It does not do the work itself
ExecuteAction runs on the server and sends the item's use event - exactly what an action bar press sends. Both paths land in the same ability, pay the same cooldown and hit one authority check, so a menu and a hotbar cannot drift apart about what using a potion means.

6. Put it on an action bar (optional)

An action bar resolves the bound item by identity and presses it through the same use event. (CrimsonCore - requires all Crimson plugins) supplies the action-bar resolver and presentable for inventory items. The slot draws its cooldown sweep from the effect the ability applied - the same place an ability's sweep comes from.

Verify
Right-click the item in your bag: Use appears and is enabled. Pick it - your health rises by 50 and the stack drops by one. Bind the item to an action bar slot and press it: the same thing happens, the slot dims and sweeps for 10 seconds, and pressing again during the sweep is refused.

7. Make the cooldown respond to stats

The authored CooldownSeconds is a starting point, not the final number. What the item hands over is an FCrimsonUseCooldown (Usable/ICrimsonUsableObject.h), and its BaseSeconds is explicitly pre-modifier: the ability that answers folds in the owner's cooldown modifiers and cooldown recovery rate before it applies anything. Ask the ability for the effective number when you put one in a tooltip - never show CooldownSeconds raw.

The item also reports the tags a cooldown modifier may be keyed to, in ModifierTags, widest to narrowest:

Reported keyComes fromWhat a modifier keyed to it targets
Ability.Cooldown.Item.HealthPotionthe fragment's CooldownTagthis item, and anything else sharing the tag.
Item.Type.Consumablethe definition's ItemTypeevery item of that type at once.

So one modifier can shorten health potions specifically and another every consumable, with identical authoring, and the ability never has to know which item it is holding. An ability system that does not read ModifierTags simply ignores them; nothing else changes.

Cooldown identity is the handle
CooldownTag is what everything else grabs: the applied effect grants it for the duration, a slot view watches it to draw the sweep, and a modifier keys to it. Two items sharing a tag share a cooldown - which is how a family of potions is stopped from being chain-drunk. Two items with different tags run on independent clocks even though one ability serves both.

Where each piece runs

StepRuns on
CanBeUsedBy for the menu entry and the slot's enabled stateOwning client
Ability activation and cooldown commitOwning client (predicted) and server
ConsumeUse and effect applicationServer only
Stack count and cooldown sweep updating in the UIOwning client, from replicated state

The item is spent before its effects are applied. If the stack emptied between activation and that moment - a second press in the same frame, another player's transfer - nothing has been handed out and the use simply does not happen.

Validation

Every way this can be misconfigured fails silently at runtime - the item applies cleanly and changes nothing - so the fragment checks itself when the item definition is saved or validated. UCrimsonInventoryItemDefinition walks its fragments to make that happen; UObject::IsDataValid does not descend into instanced subobjects on its own.

ReportedWhen
ErrorAn effect entry with nothing set.
ErrorApplication is Over Time but the effect is not Has Duration - the window has nowhere to go.
ErrorThe effect asks for a SetByCaller nothing supplies. Names the tag and the effect.
ErrorCooldownTag set with no CooldownEffect, or the reverse. Either way no cooldown is applied.
WarningA supplied SetByCaller the effect never asks for - usually a mistyped tag.
WarningUseEventTag unset (the item is inert), or EffectsToApply empty (using it does nothing).
WarningOver Time with no DurationSetByCallerTag, or a cooldown of 0 seconds.

See also

  • How-To: Author an Item Definition
  • How-To: Add Context Actions
  • API Reference
  • API Reference