Why is my inventory array garbage collected every 60 seconds?

Update Jul 24, 2014: I think I’ve figured out what’s causing the problem. But I don’t have a solution yet.

I was assuming my ‘add to inventory’ function was adding a copy of the item to the inventory array. However, what actually happened was that my function added a reference to the item to my inventory array. And at the end of the function, the item (in the world) is deleted. Every 60 seconds, Unreal’s garbage collector finishes removing all references to the destroyed actor, which is what caused my inventory item references to disappear.


There’s a bug in my game where my player inventory array seemingly empties itself at random. After testing many sequences of action in my game (picking up items, dropping items, organizing my inventory), I could not pinpoint the action or the action sequence that caused my inventory to clear itself. It seemed like no matter what I did, my inventory array wiped itself clean for no reason.

I decided to pick up an item and then do nothing at all, just to see what happens. My inventory still cleared itself. This was interesting.

I finally discovered it was time-related by tracking it with a stopwatch on my phone:

Time = 0: I start the game
Time = 8s: I add an item to my inventory
Time = 60s: My inventory array is cleared
Time = 61s: I add an item to my inventory
Time = 120s: My inventory array is cleared again
Time = 125s: I decide to wait until close to the three minute mark to loot
Time = 170s: I loot an item
Time = 180s: My inventory array is cleared again

I stopped here because I could see a pattern.

Now, is this an issue with my blueprint code or are arrays supposed to clear themselves every 60 seconds? I don’t think I have a variable set to 60 seconds anywhere in my code. And it seems odd that a variable would clear itself for no reason.

Aside

Also, after my inventory array is cleared, I’m still able to add items to it. I have an EventBeginPlay node attached to resizing my inventory array to 60. I’m guessing an array that is cleared retains its original length?

I found a related question here: How can I store a reference of target blueprint permanently or until removal? - Editor Scripting - Unreal Engine Forums

In the answer, mikepurvis states “You would want the inventory list to either be on the pawn, or on the controller class.”

I have my inventory list on my player controller blueprint, and yet it’s still being wiped every 60 sec.

Has anyone run into anything similar? Or have ideas how to keep my inventory array in memory?

Here’s my full Event Graph for my player blueprint:

Event Graph notes:

  1. Event Tick checks to see if player cursor is hovering over a hitbox. If not, then:
  2. If left mouse button is down and an item is attached to the cursor, drop the item in the world.
  3. If mouse buttons are not pressed and player has an order to loot an item, move the player to the item. Otherwise:
  4. Stop trying to pick up an item. If player right clicks, attack if there’s enough mana and the cooldown is up. If the player is not right clicking:
  5. If the player left clicks on an item, order it to loot the item. Otherwise:
  6. Move the player to the destination point in the world.

Let me know if it would help for you to see the inside of the functions.

He meant that local function varables is garbage collected once they are needed (function been already executed)

Your problem is how you assain array and how you add items to it and how those items been created

Oh, thanks for the clarification. Here’s how I assign my inventory array and add items to it:

Edit: ignore the errors, I just forgot to recompile. This code works fine.

Still looking for help on this. My inventory array is a global variable in my Player Controller class. I don’t know why it’s clearing itself every minute even if the player does nothing.

Just some random troubleshooting thoughts…

Are you sure there is nothing in your code that is recreating your inventory and re-initiating it?

Do you have any other arrays that you can check to see if they are emptied as well?

Can you try renaming your Inventory array to something random just for the hell of it?

Does anything happen if you change the inventory size?

Would it be possible to test your inventory array being held in some other blueprint?

Thanks for the ideas Zeustiak.

I tried some of them, and will try more:

  • I attached a print string to my Player Controller’s EventBeginPlay node, and found that the inventory is only resized once.
  • I used “Make Array” to set an empty array to five strings of text. I had the strings printed to the screen every second. This array seems to last past 60 seconds.
  • I renamed my Inventory to InventoryRenamed and the issue still occurs.
  • I changed the inventory size to 10 from 60, and the issue still occurs.
  • I made a new level with just a plane to stand on, the player pawn, and some items to loot. The issue still occurs.

I think I’ve figured out what’s causing the problem. But I don’t have a solution yet.

I was assuming my ‘add to inventory’ function was adding a copy of the item to the inventory array. However, what actually happened was that my function added a reference to the item to my inventory array. And at the end of the function, the item (in the world) is deleted. Every 60 seconds, Unreal’s garbage collector finishes removing all references to the destroyed actor, which is what caused my inventory item references to disappear.

Ah, in that case you might want your actual inventory to hold not the object’s reference, but say a byte that would spawn that object whenever you actually need it it displayed and interacting in the world.

So you could pick up item, update inventory with that object’s array value, destroy work object, and then if you threw it back on the ground, it would call that array member, perhaps run through a switch on enum, and spawn the correct item.

If the item had a number of stats on it, you could contain those stats in other arrays that would correspond to the same index as the item and would run the range of options that your item could have. You could even make a struct for each item type which would contain all the possible stats that an item could have.

This could also allow you to draw on those arrays for equipping and other similar functions without requiring the actual item.

But that is one way to do it. Probably dozens of ways to run an inventory and solve your current problem, including some that keeps the object around.

Structs seem very limited compared to blueprints however. I have a hierarchical item system in mind where every item in game inherits from a master blueprint with stats like damage, value, random magic effects, durability, level requirement.

Variations of an item would be child blueprints. Damage, magic effects and name need to be able to be randomized and generated at runtime a la Diablo and Borderlands. I was hoping to save the save random seed to regenerate the item when moving it from the world to the inventory.

It seems difficult to replicate that with just structs.

I wonder what the performance would be if I just kept the item actor blueprints in the world but hidden.

You can use the base item/object to transfer/create that information, I am just saying when you pick it up, take all the information, store it in a struct that is then stored in your inventory array, and then destroy the object.

The struct could store specific info such as 10 Strength, 5 Intelligence, Modifier X, Y, and Z, etc. Or you could do multiple structs, one for base stats, one for special item abilities, etc.

If you want the item in the world again, get it’s type and any other key information from your struct(s), then pump all your stats back into it, and release/spawn it into the world(such as equipping it or dropping it).

IE expose all the variables on your item BP’s, and you can dump your struct back into it as you spawn it. Keep all the pertinent information around without having to hide an object somewhere.

You wouldn’t even have to spawn the object to equip it, just move the struct information over to your character and spawn a model for your character to swing around.

Oh I see now. That would totally work. Thanks for the explanation!

I could make a struct/structs that contain fields for every possible attribute an item might have, e.g.:

  • RandomSeed
  • Strength
  • Intelligence
  • Modifier
  • Etc

And then when I feed that struct data into my Item blueprint it should be able to reconstruct the item.