Loot and random stats

Module PulseInventory. Loot tables say what a chest, an enemy or a quest reward gives; random stats make every dropped sword a little different. Both are deterministic for a seed, so a server can roll once and everybody sees the same result, and tests can check exact outcomes.

Loot tables

A Pulse Loot Table data asset (UPulseLootTable, Primary Asset Type PulseLootTable):

Field Meaning
Entries Items (Item) or other tables (SubTable) with MinCount / MaxCount and a Weight.
bAlways on an entry Always drops, in addition to the weighted rolls (keys, gold).
Conditions on an entry Pulse conditions (see Conditions, costs and rewards): Context Tags (tag query on the tags of the roll), Loot Level (range of Level), Has Item or a quest of the player, … Rolls run on the authority, so only Passed counts.
MinRolls / MaxRolls Number of weighted picks over the other entries.
NothingWeight Weight of “nothing” in every pick.
bAllowDuplicates Whether an entry can be picked twice in the same roll.

Sub tables can nest; a table that would roll itself again (a cycle) is skipped with a warning, and nesting stops after 8 levels. Validate Assets reports empty entries and tables that use themselves.

FPulseLootContext context;
context.Level = EnemyLevel;
context.Tags.AddTag(DifficultyTag);
context.Player = Killer;    // conditions about the player read it, may be null
const TArray<FPulseLootDrop> drops = Pulse::Inventory::Loot::RollTable(Table, Seed, context);
Pulse::Inventory::Loot::SpawnLoot(Enemy, drops, Enemy->GetActorTransform(), 80.f, true);

The conditions of an entry get the context of the roll (FPulseLootContext::MakeConditionContext): Player, Tags and Source of the roll, and the loot context itself as extra data (Loot Level reads Level from there).

Blueprint: Roll Loot Table, Give Loot (into an inventory, returns what did not fit) and Spawn Loot (as pickups through the pickup subsystem, spread on a circle). Give and spawn run on the authority. Spawn Loot places each drop completely or not at all: a drop whose pickup cannot be created changes no other pickup.

Random stats

  • Put Random Stats (FPulseItemTrait_RandomStats) on an item definition: possible stats (Pulse.Stat.* tag, range, weight, whole numbers), how many (MinStats / MaxStats) and optional rarity tiers (Pulse.Rarity.*, weight, extra stats, value multiplier).
  • When the item is created by a loot roll (bRollRandomStats on the entry) or by Pulse::Inventory::RollInstanceTraits, it gets the instance trait Rolled Stats (FPulseItemTrait_RolledStats): the rarity and the rolled values. Items with random stats drop one by one, every item with its own stats.
  • FPulseItemTrait_RolledStats::GetStat(Tag) sums a stat (child tags included).

The inventory does not know what a stat does. Other modules map stat tags to effects, for example PulseInventoryEffects to attribute bonuses while equipped and PulseCombatInventory to damage modifiers.

Cheats

Command Does
PulseLootRoll <table> [seed] [drop] Rolls a table, prints the items with their stats and puts them into the inventory (or drops them in front of the player)

PulseCore plugin documentation.

This site uses Just the Docs, a documentation theme for Jekyll.