Inventory system with ES

Hi

Reading through old topics, I kind of understood it that an item is an entity that either can be linked to the player by an InInventoryOf component or I can use an InContainer component to link it to a bag and then use an OwnedBy/ChildOf component on the bag entity to link it to the player.

Not sure which approach I should follow.

The idea with bags seems complicated, if I want to know who is the owner of an item I must first get its bag then get the owner from the bag.

What are the use cases for having bags? (except that I can organize stuff visually which I can do in the first one as well)

Regards

A lot depends on what you need.

An item can be in a chest on the ground. Who owns it?

An item can be in a bag on the ground and then that bag picked up by the player. Who owns it?

When is “ownership” actually needed and what for?

InContainer is very clear (and can even have container position as part of it if there is never a reason to separate them). It does just the aspect it says: “this entity is inside this other entity”. Whether the container is a chest on the ground, a bag being carried, or the player’s hand just depends on how you want to model things. (I think my first approach had inventory slots: left hand, right hand, back, belt, etc. to which items could be attached… and those items could be containers. So ‘inventory’ and ‘containers’ were separate.)

If you need to find out “what player is holding this arrowhead” then that seems like a relatively rare request and it’s probably ok to see that it’s in a small silver box inside of a bag inside of the player’s backpack.

For me, it was only during transitions that I cared about this stuff. And there is almost a transactional quality to it because you don’t want the InContainer to get removed and the world Position not to get set when something is dropped on the ground. You have to make sure to always do them both together. I struggled with several ways to do that when I’m running “take” and “drop” scripts and have to sort that out through container hierarchies and stuff. (Example I used was a cursed item that the player is not allowed to drop.)

…in the end, I cleaned up a lot of problems by leaning into the ES ideas and using a MoveTo component. A separate system would handle the script mechanics and kept multiple systems from trying to write the same components. (The ‘cursed item’ thing is still tricky as you need ‘CanDrop’ handlers and such.)

I don’t know what the best solution or if I will think of something better for the new engine but that’s essentially where I ended up last time I played with this.

Looks like that was almost 7 years ago, though. :slight_smile:

3 Likes

For example in combat. An enemy NPC can have multiple weapons that can be used in different combat situations (near attacks, far attacks,…). So the combat system wants to check what weapons an NPC has in his inventory to automatically take a proper one based on the situation. Here it does not matter where the item is, in his back, in his bag,…

I mean, it could matter if you want to model each search as an action. Pulling a potion from his belt versus rummaging around in the bag he keeps in the bottom of his backpack.

Either way, searching for an item is not particularly difficult or costly. And that would depend on how deep you allow your inventory to be. Is the NPC the container or does have have backpacks and bags and boxes and stuff? If the former then it’s no problem… if the latter then you can’t really get away from searching anyway.

And maybe the AI just needs quick slots like the player has.

1 Like

Yes, I see.

Regarding loot items. Are you handling them like real items that have all the stats and stuff on them or they are just a placeholder for a real item that when picked up, the “take” script will make a real one?

This is only “the plan” because none of this was implemented yet.

…but loot drops would be real items. I needed NPCs, mobs, etc. to be able to interact with them just like any dropped object. So it’s easier if they are real and not a particularly strong reason for them not to be real in my case.

1 Like

Do you ever had an idea for shared containers in your game?

For example in multiplayer game, when a team member finds an object that can be used by others (like a key to a door) you put it to that shared container so anyone can use it.

Or a loot container, so when a team member finds a loot, it will go into that container and only Game Master should be able to take them and split them among players.

What do you think?

And what about stackable items, how do you handle them?

For example say you have one “PowerUpPotion” and find an other one on the ground.

Would you have an ItemAmount component on an item and increase/decrease it or you would prefer to keep them separately (each has it’s own entity)?

It would depend on the item I think:

Items that are non-unique can stack, like a stack of health potions, a stack for mana potions, a stack of arrows, etc etc

But an item that can possibly have unique instances (like a weapon-item that can be customized, leveld up, has durability, etc) should not stack, so that the player can differentiate between them in their inventory.

That’s how I do it for my game, and most games do it this way I think. Like minecraft does not let you stack pickaxes or armor - but you can stack iron ore, seeds, and other non-unique items

1 Like

And do you do this by increasing a number on that item?

Yes, I check for an isStackable() boolean on the item, and if its true I increase the quantity, otherwise if its false and not stackable I create a new instance of the Item that gets added to the list of items.

I should note I do not use Paul’s Zay-ES since I started my project before I knew of many extra libraries like that. But I think I do things in a way that sounds similar to an entity sytem in a lot of cases.

1 Like

You mean a container that actually exists in multiple places? So it can be opened anywhere in the world?

When an object is clicked to open the container it runs the open script for that entity… which will popup the inventory for some entity on the user’s screen. They need not be the same entity.

For stackable items, the entity is not the item but the stack… so when it’s only one item it’s just a stack of 1.

So if potions can be stacked, you are never holding a “potion” but always a stack of potions… which may only have one item in it.

In my original engine, the handler scripts could be chained… so the “use” action of ‘potion’ and the “use” action of ‘stack’ would both be called. The latter would decrement the count and destroy the entity if 0.

I think I didn’t implement stacks yet in that version of Mythruna but I can’t remember. I’m 99% sure that I did in a little 2D RPG I started just to play with inventory mechanics. So this is just from memory.

1 Like

No I mean a virtual container which has not a position on scene, it is just visible from inventory menu and will be displayed for all players. I find a key and put in there then all other players can use that key to open locked doors.

My answer still applies. There is an item in the inventory that opens the container for some other entity that’s shared.

Is each potion in stack an entity itself with its own buffs and stats?

No. The stack is the entity.

Ah I see, I thought stack was a container itself.

Nah, it’s like an item with multiple uses… but you recharge it by stacking more there.

Stacks have to specifically be accounted for in whatever ‘move system’ manages that actual moving of an item from one place to another.

1 Like

So a stack can have stat buffs like an item, yes?

A stack is an item like any other item. It just has a limited number of uses.

So, whatever question you are going to ask next, if you can do it with a “sword” or “a pen” or “an amulet” then you can do it with a stack… because a stack is literally just an item with an extra StackCount component or something.

Exactly the same as an item. It is an item. It’s just when you run out of uses it disappears.

Edit: like a wand with a certain number of recharges. It’s not a ‘special kind of thing’… it’s just another item that when there are no more ‘whatever’ then it’s gone.

1 Like