What's the best inventory system/framework? Best practices?

Hi, so how do you make a robust inventory system, taking into consideration saving?

  • Assuming you’re using an array for the inventory, where do you put it, and what type is it?
  • How, and where, do you store default item properties (texture, class etc.)?
  • Do you have any hard references that go into the save game object?
  • If you don’t save any hard references, where, when, and how do you load the referenced assets (like textures etc.)?

Thanks.

Generally, it seems best to put the inventory array into a component class which is added to the character or its controller. As for type, most people use a structure with members like ItemName and Quantity ( so you can do things like stack potions, arrows, or coins to one bag slot).

To setup item properties, data tables are usually used for this. Or an external database if you use an SQLite plugin or something. The inventory slot structure would just point at a row name (or row number with a normal database).

Done like this, you won’t really need hard refs in save, since you can just store the inventory array which is just made of names and ints.

And without refs, you just need the character or whatever to look up the item in the data table to set any meshes/textures/etc.. on begin play to change how they look.

1 Like

But when accessing that data table, does it load all the assets it references?

Like, imagine having 1000 items each with a texture icon of 10 Mb.

For me, inventory data i save is just name and quantity.
the rest will be in datatable.
so things like texture icon, description, bool stuff is in datatable, preferable struct.
when opening inventory, i just send list of item name to datatable and get all the ref to set in UI

about 1000 item 10MB, maybe limit the inventory to 20 or 50.
or to be more specific, maybe make a category for the item.
Like Consumable, Equipment, Costume, etc
that way, you reduce the way inventory load.
only load when you click the inventory tab category.

other than that, dont recreate the inventory list everytime.
you can just set it collapse instead of hidden or remove from parent.
and only updating it when you get new item, use item or remove item.

best practices depend on your game, ie is your item an ItemID, Struct, full object/actor.

  1. use TFastArrays
  2. I prefer Data Assets to DataTables with AssetRegistry
  3. use softobject/class references
  4. potentially separate static/mutable data
1 Like

It’s all of the above, I guess. An item will be an actor in the world, and its properties vars are best contained in a struct, I think. It has to go into some sort of inventory array, for sure, unless there’s a better way to store your inventory.

I’m not very familiar with Data Assets and Asset Registry. Do you have to load/unload stuff yourself? Can you do it in blueprints?

let me rephrase it, does you item only have static data (nothing changes ie durability) or not, or both. can it have child items (items with items like a backpack)

fast arrays are better but require c++ and arent as important if your game isnt networked

they are fully blueprintable and dont require loading to check asset tags (as opposed to a data table which loads everything in the table) but that may also require c++

Data tables are fine if you use soft objects for heavy things like mesh/materials or just have a small game

1 Like

Items will have both static and dynamic data (like values changed at runtime, say durability). I don’t know yet about parent/child items, but I’d like to make a system that’d support that as well.

If you use soft object references in the datatable’s struct, the meshes/textures/etc.. won’t be loaded automatically. This would cut down memory overhead but adds the additional step of async loading the mesh or whatevs when you equip or spawn an item.

1 Like

so id separate the static data into a DA or DT and the mutable data has to be in a struct or uobject.

structs cant nest in themselves so if you want items inside items id recommend uobjects or you can design around it, ie containers are different structs from items.

im personally against structs for items as items will likely have composite data, ie armor has armor, weapons have damage, potions have usecount etc

however these days you can use modular data like FInstanceStructs

i personally use UObjects but these can be more complicated for replication/serialization

so the key point is you really, really need to know the exact and future design of your items to choose the best system

1 Like

Thanks a lot.

so id separate the static data into a DA or DT and the mutable data has to be in a struct or uobject.

Why wouldn’t you just put everything into struct or UObject?

About that. How do you save them?

performance, again depends on you system but why save icons, meshes, classes etc that will never change, when you can just save a DT row or DA. this is especially important for networked games when you dont want to replicate all that data when you can just replicate an ‘ID’

the same way you save an object/actor serialization. so you can create a struct that has the class and serialized data which is a TArray so it can hold any data

1 Like

Sorry, I don’t quite follow. So are you storing some actor’s save data into an Object, then you push that Object into a Save Game Object. And what type is the array? Can this be done in blueprints, by the way?

I’m using instanced struct array right now, for my inventory. But there’s a few issues when you need to spawn an item with durability, even while knowing its class:

  • You can’t search for that class in your instanced struct array, to find its struct to get the durability value, unless you break it into EVERY struct you have for every item:

  • Sure, you can still spawn the actor and pass the instanced struct to a function of a custom component on the actor, but that introduces a small delay where the actor will appear in it’s default state before it applies the changed values.

  • You can also try this:

  • Have a specific struct for the inventory items that contains an instanced struct for the mutable data, like durability. And then you can compare with the class you want to spawn. The problem is, you STILL can’t tell the function to break the instanced struct into a specific struct type, based on your input class. You’d have to break it for EVERY item in the game, manually. Unless, again, you do it on the actor, after you spawn it, which introduces that delay which is not ideal.

I saw some video showing how they use Objects to store data. I thought maybe they can be used for this.

you need c++ for proper serialization but its pretty easy, it converts any data to a byte array meaning that you only ever need one struct. in blueprint you have to have difference structs for all types of data.

this is a good model for blueprint but yes you’d likely have to handle that data on the actor. there shouldnt be a delay though unless youre async loading something

1 Like