Weighted Loot Table (Bug fix needed)

To start, all of my work towards my inventory has been based on Ryan Laley’s youtube series the inventory system, and his weighted loot table videos. I have been trying to solve this issue for days but to no avail.

I am trying to create a system where loot randomly spawns inside a container. When I say loot I mean, items that are classes that include all of the information such as Thumbnail, name, isStackable, isConsumable etc. Basically, I want for this loot system to spawn over 1000’s of items in each container throughout the world on beginPlay. Think of Rust’s barrel system or Rust’s medical crates that spawn throughout the world. I also would like it to be highly optimized so I can keep adding items and easily add them to the loot table. Right now, I think I’m in a good spot, I’ve got everything done and all I’d have to do to insert a new item to the loot table is choose the items class, then give it the spawn percentage. This one bug is not allowing me to finish though.

Here is an imgur link to pretty much all of the functions/event graphs that involve this lootTable, if you need anything more such as another function please let me know! For me, I think the problem lies between the functions provided through the imgur link. But someone please double check that. I only say this because, for my inventory system, everything works as intended including picking up items, items showing in inventory with the quantity and thumbnail.

Basically, when I hit play, it will go through all of the print strings I set for development which include (Prep, Calc, Past Choose Loot, and Success) but once I walk over to the container and open its inventory, the inventory is completely empty. Despite being able to hit play and pick up that same item that I am trying to test spawn in the crate. It does show in the inventory as well when I pick it up.
P.S: Ignore the imgur “This is where my problem starts” I now have no clue where my problem is since Prep now works correctly. I have also tried moving around the event InsertLoot to before, after, and on the completed loop in that graph and still no avail. For those wondering, I am not getting any errors through any of my systems which include (Inventory Component, Loot Table, Container, or any blueprint in my game really)

Are you actually “spawning the items” in the crate or setting a crate inventory in which the player chooses items from (ui list)? I’m not seeing anything off hand that would cause a problem given the posted bp’s.

Optimization wise… I wouldn’t spawn items on begin play. My system uses spawners that have a collision radius (50-100m) the player must overlap server-side. On overlap the server (gamemode) chooses the items and spawns small data sm variants at the spawners location. The sm has a reference to the sk high data class which is what’s spawned on pickup (guns and the like). I use the collision overlap approach to reduce early game server load. Spawning tens of thousands of structured items eats a lot of server memory.

For loot table I’m doing max spawn rates which simply limits the total number of each item that can spawn. Choose, check if item is in table and availability is > 0 …on spawn deduct. Simple and fast.

What spawns is determined by the spawner itself. It has config options to do completely random, or list based random. List based random is an array setup where the designer selects what can potentially spawn there. The game mode chooses from that list, validates against loot table and proceeds.

Here’s a look at the early prototype. Each “item type” has its own array.

You can add the same item multiple times to increase its chance/weight.

“I want for this loot system to spawn over 1000’s of items in each container throughout the world on beginPlay.”
“I also would like it to be highly optimized”
Is an oxymoron.

You need to just have a list and generate a random item when the barrel is interacted with.

running things on begin olay is ridiculous and would add A LOT to loading times depending on the size of the loot list * the amount of barrels.

Never seen the tutorial series you mention, that said, the concept of having weighted random list should be simple.

assuming > 1 item per barrel,
The table should contain a list of items, and a % for how likely they are to appear.
It doesn’t have to total 100% in fact you can use the 100% to force any item to always appear.

example. random int is 45.
item list is
A 5%
B 88%
C 100%
D 45%
E 30%

Now because of how % works, the system should allow for
c, b. And D to spawn, but not A or E.
So all ints > 45 can spawn.

I would suggest using floats instead of ints. You can fraction percentages off better that way.

Thank you for this and your help! I do agree with the collision spawning and that was probably really dumb of me for begin play. But I’d rather not have to put items multiple times to increase their chances of spawning. Since I’d have 5 different tier levels of loot which include common, unique, rare, ultra-rare, and legendary. Putting all those into account and trying to figure out the percentages for them to spawn correctly would be a nightmare if I kept adding items. Also, with the 100’s (thousands was a bit of an overstatement) of crates around the map, I want them to have the same items able to spawn. There would be no need for me to create multiple different containers, or select which items spawn in certain containers. So, if I could just somehow get this system to work it would be perfect, but still open to other options!

Edit: I am trying to spawn the objects in the crate randomly (without players selecting loot or loot being predetermined). So no real player UI, just want the items to spawn, and the player to drag the items to their inventory.

Yes that is an oxymoron and that’s my bad, I meant spawn <5 items in one crate but there are hundreds of crates around the world (just like Rust)

And I currently do have that function CalculateSum which does include the ‘above 100% issues’. Even though it’s not really an issue. Also, I have realized that would take a long time and I’d like to blame it on testing but I really can’t since I was going for it lol. I am changing it to the collision-induced loot spawns as mentioned previously.

Use interaction. Make yourself a blueprint interface and a scene component to attach to any BP in order to allow loot spawns…

I’ve already gotten the collision based loot spawns to work (loot doesn’t spawn though). I am going to try this, but what exactly should I specify inside the scene component or the blueprint interface? Is it basically just the same thing I setup; I.E: insert loot function to AddToInventory function.

I may have covered something similar in video #4 or #5 of this list:

A blueprint inteface is basically just a way to call something that is defined by the interface, but completely individualized within each obeject you add the interface to.

The component is a good way to make code that can be added to any actor or BP by simply adding in the component.

You may be better off with a child actor instead of a component, so you can use it to define the collision area to use for the interaction. That is also covered within the camera tutorial, in the first videos.

Good ideas, I decided to try and use the child actor but problem is, I’ve already been using an actor BP for my LootTable and I already have the collision working. Really not sure what’s wrong with this system.

UPDATE: I think I have figured out where the problem is. In another function I have added a print string, where it gets the inventory title that is trying to create the stack in. I put this in the CreateStack function which is where it adds the items. Hit play, and went into the collision, it printed “DefaultInv” despite the container having the name “Container”. It is believed that container is not grabbing the items, instead, DefaultInv is. Which explains why the item is not appearing in the containers inventory when I open it. Now, DefaultInv is set from the default class values in LootTable. When I dragged LootTable onto the containerBP and set the values, I technically now have 2 inventories for 1 object. How do I remove this “DefaultInv” default value inside container? It is apart of the inventory component, of which my lootTable inherits from because I need to have the AddToInventory function.

This is my LootTable one “DefaultInv”. This is the one I want to remove, but it inherits from InventoryComponent which I need to use the AddToInventory function.
This is the inventory I WANT to use, the “container” inventory.

I was mainly showing a different approach that might stimulate ideas.

My game mode needs flexibility/control in what can spawn per location. Most of the spawners use pure random from loot table…125 different items. But there are locations/spawn points in my levels where I don’t want high tier loot (rare, ultra rare, legendary) spawning… Or I want to increase probability of certain items spawning.

Say for example a random one room shack. I won’t want a higher tier items spawning there, so I’ll use the list to only have low tier items (range of 50 or so items). Thus ensuring nothing of high tier is ever spawned. There also might be an outcrop on a mountain side where I want I higher probability of a rare 8x scope or sniper rifle to spawn.

Couple the “list option” with low spawn rates (limited counts) in the loot table for higher tier I can ensure these items are limited (rare, ultra rare, legendary). e.g. “Rare Item A” has a limit of 20. “Legendary Item A” has a limit of 5.

My approach with collision based (proximity) spawning and loot table limits comes with a few caveats. The more time that has passed (game time) the less loot availability there is. Essentially meaning the first triggered spawner has more options of loot than the last triggered spawner. As items are spawned they are deducted from the loot table. Say I have M416’s at a max availability of 250. Each time one is spawned I deduct 1 from the loot table …249, 248 etc. Once it reaches 0 no more will be spawned.

Having pure random means that there’s the potential for all my m416’s being spawned on one side/area of my map. In some instances potentially having multiple in a 2 story building where there’s 11-15 spawners and each can spawn 1-3/5 items.

At the end of the day your implementation needs to be based on the needs of “your game mode”. How I or a dude on youtube does it might not fulfill your modes niche, or be efficient. Scope it out 100% (or as close as possible) … think about all the caveats etc. Then build. There’s pros and cons to every design.

Yeah very true, I guess thats apart of being a game dev, which you have to be innovative to fit your needs.
Anyway I’ve almost solved the problem for my inventory system anyway, the big question now is “How do you remove default values from class defaults when a child blueprint inherits the parent”
You can see what I’m talking about more in-depth if you scroll up to the last post I made.

You set them.

Based on what you posted you have an Actor class that is your loot table. That class has a variable “Loot Table” that’s a struct.

Typically you’d simply drop one of those actors into the level and set the values, then save.

In the game mode: Begin Play -> get all actors of class (loot table) -> get (index 0) -> Get Loot Table -> Set GM Loot Table variable. Then reference the GM’s loot table var for all future processes.