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 (
bRollRandomStatson the entry) or byPulse::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) |