Why all Marketplace inventory objects made with data tables?

In my team we are making our own inventory system, and we deciced to use some Marketplace inventory as a starting point. We have tried several inventory systems and all systems use base object + data table inventory objects system, but we think, that building inventory object system base on inheritance is much more convenient and easier way.
Just wondering: what are the pros and cons of building inventory system by base object + data table, and why Marketplace creators likes to use base object + data table object system?

Maybe you could elaborate on what you mean by using inheritance?

I can see why all marketplace inventory systems use an inventory item + data table- that’s by far the most simple and efficient way of doing it.
There are countless pros, but the only con I can kinda think of is that using inheritance would make it easier to select items in presets since they’re individual classes (individual classes are bad and ugly and no good and bad) meaning you’d be able to select an object directly rather than having to type a name.

I mean a class inheritance. For example, a base class “BP_PickableObj”, it has 4 children “BP_Weapon”, “BP_Armor”, “BP_Food”, “BP_Heal”. And whose 4 classes have their child classes of exact weapon (“BP_AR”, “BP_MG”, “BP_Pistol”), armor (“BP_Heavy”, “BP_Light”) and etc objects.

The idea of using inheritance in, as we think, the easiness of managing individual objects: easy to identify and get some data, also encapsulate some unique logic for each child (for example, shooting and reloading for weapons, or health restoration for heals). The only reason what we have found to use data table is, probably, mass stats changing while balancing.

The fact what probably all Marketplace inventory systems uses data tables for system implementation was a surprise for our team, so we began to doubt if inheritance is a good approach for inventory creation. I decided to research and compare both implementation types to select the most suitable, so that’s a reason why I asked this question.

The two methods aren’t mutually exclusive. If you need specific/unique functionality within item blueprints, you can always define the class in the data table. If bp_food, bp_armor, bp_weapon and such all inherit a generic “use” function from the base class, activating them should be rather painless.

1 Like

Either way is perfectly viable.

Personally I’d lean toward making your inventory system manager the same way you make your other content managers. You probably have management systems for meshes, particle effects, sounds, materials, meshes, abilities, NPCs, achievements, missions, etc. Make your inventory management system in a similar way to how you make all those.

1 Like

A combination of the two is probably best. Different objects are pretty necessary for good unique logic, but using a data-table prevents you from having a unique class for 10 items that all just heal a slightly different amount.

As @illspiritx says, you can add another variable to the data table struct for the overridden item class.

You can then store any default data you want with an FName->FString map. Unfortunately blueprint doesn’t have std::any, so we have to parse the data to/from strings (ie “MaxDurability”->“122” or “HealAmount”->“20”).

The base item class may just be an object that can be picked up and stored in the inventory. This would likely be the case for something like a exclusively-crafting material. Child classes would deal with things like healing/eating.

1 Like

There is one huge problem with making database/tables with Pointers or references to objects.

For reference to work you need to have spawned actor/object before referencing it.

So you using BP_SomeActor may get you into loading order problems.

I got such problem recently:

  • several actors BP_Place spawned from level
  • and then umg widgets spawned for each of that actor
  • 3d widgets were spawned before those actors, so they could not cast to actor
  • normal widgets spawned after BP_Place
    I solved it yes, but it was 2 weeks of “WTF?!” before i found out loading and constructing all those objects is quite messed up. I do not blame Epic devs, i cannot think about method to solve it all that is clean and always works. Load order problems are here to stay.

However you are right referencing objects and using them for inventory is best solution (when it works).

However there are some things to be aware of with using references to actors:

  • if actor is referenced it will stay in memory, on big streamed maps this may lead to keeping lots of useless actors in memory.
  • invalid pointers, while they do not crash blueprints it is not that safe in c++

For real and robust inventory, quests, items etc system. I would use C++ code that keeps database of items in game their states etc. But it needs to be coded by your team. Game Tags do not work for it as you need to declare them in ini file or in editor. GAS is overkill and a lot of referencing silly chains etc.

You need simple GAS (made for your needs) together with system that can store it (simple database like code). And probably some code that reads database defaults from JSON or CSV.

2 Likes

What you have to reference is the soft class, so you can spawn the bp with the logic you want. When you want something from the inventory to be used in the game you look at the class and spawn it

You are mixing the logic of the object with the logic of the inventory, an inventory should have only the ids of the tables.
Only when you want to use it do you spawn them in the game

If a blueprint uses widgets, what I do, let it be that Bp that manages the widget including the spawn, and add to viewport, so what you say never happens, there is nothing more terrifying than a widget manager hahaha