Skip to main content

Weight and durability

Both are additive modules built on Core's extension points, and both are worth reading as examples of how a feature is added without touching Core.

Weight policies​

"20kg" is not one rule. A weight limit answers three independent questions, and keeping them apart is what lets one struct express games that look nothing alike.

Scope — what counts:

ScopeCounts
ContainerOnly what sits directly in this container. Each bag is its own budget, so nesting buys capacity — deliberately
Container And NestedPlus everything its items carry, however deep. Nesting stops being a way around the limit
InventoryEverything the owner holds. One budget for the whole character

Enforcement — what happens at the limit:

EnforcementBehaviour
BlockRefuse anything that would cross Max Weight. The limit is a wall
AllowNever refuse. The limit is a line the game reads and reacts to

And two numbers: Max Weight (the hard wall, 0 = none) and Encumbered Above (the soft line, 0 = never). They are independent, so a game can have one, the other, or both.

The games this covers​

ScopeEnforcementMaxEncumbered above
Roleplay server — a firm carry capInventoryBlock40—
Extraction shooter — take it all, walk home slowlyInventoryAllow—25
...with a ceiling you truly cannot passInventoryBlock6025
A pack with its own capacityContainerBlock20—
...that its inner pouches must fit insideContainer And NestedBlock20—

The second row is the one that changes how a game feels: you can always take the loot, you just have to carry it home.

Where each one goes​

A limit that must refuse items belongs on containers, as a Weight Limit Rule — that is the only place an item can be turned away with a reason the UI can show. Put the same Inventory-scoped rule on every container to give a character one shared budget.

A limit that only reports belongs on UEDWeightComponent as its Carry Policy, which publishes Is Encumbered, Get Over Encumbrance and On Encumbrance Changed. Nothing in the framework reacts to encumbrance; the game decides what it costs.

Most games want both: the rule stops the impossible, the component reports the merely painful.

A closed bag weighs what is in it

A packed bag carries the weight recorded when it was packed, so putting one away does not make its contents weightless — otherwise closing a bag would be a way to carry anything. An open bag is counted through its live container instead, never both.

Weight​

FEDWeightFragment gives an item a unit weight. An item without one weighs nothing.

UEDWeightComponent sums the weight an actor is carrying and fires when it changes:

Weight->OnWeightChanged.AddDynamic(this, &AMyCharacter::HandleWeightChanged);
const float Total = Weight->GetTotalWeight();

By default it counts every container the actor has. Set bIncludeAllContainers false to count only its main one — which is what you want if a stash should not slow the player down.

FEDWeightLimitRule is a container rule that refuses what would push it over a cap:

FieldMeaning
Max WeightThe cap.
Weight AttributeOptional GAS attribute, so a Strength perk raises it without touching the asset.

Because it is a rule, it is consulted at the same acceptance gate as everything else. A vendor's Buy button greys out with "That is too heavy" before the player clicks, and EvaluateAddItem and the real add can never disagree.

const float Item = UEDWeightStatics::GetItemWeight(Entry);
const float Bag = UEDWeightStatics::GetContainerWeight(Container);

Durability​

FEDDurabilityFragment gives an item a maximum durability and what happens when it runs out.

Current durability is per-stack state, not a fragment field — it lives in the entry's FEDItemStateContainer, replicates with the entry, and saves with it.

UEDDurabilityStatics::GetDurability(Entry);
UEDDurabilityStatics::GetMaxDurability(Definition);
UEDDurabilityStatics::ApplyWear(Container, Handle, Amount);
UEDDurabilityStatics::Repair(Container, Handle, Amount);

Two consequences fall out of durability being per-stack state, and both are deliberate:

  • Two swords at different durability never stack. Merging them would have to invent a number.
  • A worn item keeps its wear through a move, because a transfer preserves handle and state.

What happens at zero — destroyed, rendered unusable, unequipped — is configured on the fragment, and the wear itself is your game's business. The framework does not know that swinging a sword should wear it out.

The pattern both follow​

  1. A fragment describing the item's participation. Absent means not participating.
  2. Statics that read it, so Blueprint and C++ get the same surface.
  3. Optionally a rule or an observer component, registered through Core's registries.

Nothing in Core knows either module exists. That is what "additive" means here, and it is the shape to copy for a feature of your own — see Extending.

Where next​