Inventory items using 2 grids

Schwee

Member
I am planning out an inventory system and I am still getting used to best practices with Gamemaker but my understanding is making use of enums and ds_grids seems to generally be the best approach. Originally I was considering one enum with properties such as name, description, etc. However, I realize that some item types will require unique properties. For example, ranged weapons could have specific accuracy, ammo capacities, reload times, etc. None of those properties apply whatsoever to say a consumable potion or even a melee weapon.

So, I am considering a second grid in addition to my 'all items' grid. This second grid would contain the 'type specific' properties for a given item type.

Example...

enum e_item_props {
name,
display_name,
description,
};

Then a ds_grid called 'all_items' that has 3 columns and one row per item. The x coordinate representing the "item_id".

enum e_ranged_weapon_props {
item_id
accuracy,
atk_power,
...
}

Then a ds grid with essentially the same setup.

So I guess my question is...does this make sense? Does it make THE MOST sense? Thanks as always!
 
H

Homunculus

Guest
My approach is to keep each item data in a ds_map and in the inventory ds_grid just point to that. Your approach could work in theory, but grids don't really seems the right solution when you have a different set of properties per item type or single item. Ideally you could have a setup like this for the item props (I use JSON to represent the ds_maps)

Code:
{
      "weapon_shortgun": {
        "name": "Shotgun",
        "type": "Ranged",
        ...
      },
      "weapon_knife": {
        "name": "Knife",
        "type": "Melee",
        ...
      },
      ...
}
and then in your ds_grid you refer to those to values to store the data

item, amount
"ammo_shells", 28
"weapon_shotgun", 1
...


The drawback is that single items all share the same properties, which may or may not be what you are looking for, but there are ways around that.
 

Schwee

Member
Looks awfully similar to some good ol' JSON...which I wish was truly usable inside GM.

You reference what is basically my main concern...something like a ranged item could have 10, 20, or more individual properties that something like a medkit has absolutely no use for.

I haven't really begin addressing the actual inventory yet which will definitely be a separate data structure .

I am debating with multiple workarounds but I am ultimately wondering if the most efficient route is to cut my losses and have potentially dozen "null" fields for items that don't require data for a specific property

Edit: I didn't see you referenced JSON in your post...yeah.
 
Last edited:
H

Homunculus

Guest
Looks awfully similar to some good ol' JSON...which I wish was truly usable inside GM.
But it is usable, see json_encode and json_decode . You get a ds_map as result of the decode function, and it takes a ds_map for the encode.

You reference what is basically my main concern...something like a ranged item could have 10, 20, or more individual properties that something like a medkit has absolutely no use for.
That's the whole point, a ds_map doesn't require you to define the same properties for every entry, and that's why I'm suggesting this instead of a ds_grid.

I haven't really begin addressing the actual inventory yet which will definitely be a separate data structure .
This is generally where I see others go for a ds_grid, but it's just one way to do it.

I am debating with multiple workarounds but I am ultimately wondering if the most efficient route is to cut my losses and have potentially dozen "null" fields for items that don't require data for a specific property
Again, that's what ds_maps are for.
 

GMWolf

aka fel666
I would store them using a list of arrays.

An array could represent an item by having the item type in index 0, and then whatever properties you want after that.
 
H

Homunculus

Guest
I would store them using a list of arrays.
An array could represent an item by having the item type in index 0, and then whatever properties you want after that.
The problem with that is how to get a specific property out of the array in a meaningful way. In a setup like this you'll probably want an enum for every item type representing the properties and their position in the array for that specific type.
 

NightFrost

Member
I've always used a ds grid or 2d array plus two enumerators (one for items, another for properties) for item definitions. Even if items require varying properties, leaving many of them unused on each definition. This makes is simple to query for properties as they're all on a single structure. Memory-wise, I would assume adding a few goodly-sized backgrounds to the game will eat more memory, unless your item database is truly massive. I guess ds map could also be used (or what in PHP would be called an associative array) and property enum is used selectively to create entries. It'll throw an error though if the game assumes a wrong item type and tries to read on a key that doesn't exist for that item definition.
 

GMWolf

aka fel666
The problem with that is how to get a specific property out of the array in a meaningful way. In a setup like this you'll probably want an enum for every item type representing the properties and their position in the array for that specific type.
Yes, it would be crazy to do it with just numbers.
The advantage over ds maps is garbage collection and performance.
I don't like the idea of having to hash and compare string for every member access
 
H

Homunculus

Guest
I don't like the idea of having to hash and compare string for every member access
I get what you mean but it really depends on the implementation. In the ds_grid i store the ds_map id of the item as well (so I don’t have to fetch it by the key on every access.
 

GMWolf

aka fel666
I get what you mean but it really depends on the implementation. In the ds_grid i store the ds_map id of the item as well (so I don’t have to fetch it by the key on every access.
I mean for accessing properties of the items.
A map with string keys will be quite a bit slower than an array with enum keys.
Also will use significantly more memory.

Depending one what you want to do with your inventory that could be a problem.

If you just want to look up one item at a time that's fine. But if you want to scan through your inventory for an item that has a specific action during some event, it can get expensive
 

Schwee

Member
So...I think I've found a pretty elegant solution for this:

* Create enums for item_list, item_types, item_props (generic)
* Create grid for all_items
*Create an enum and grid for each item type with its item specific properties
* Create a map for each item type that is build like key: x coord of item in all_items, value: x coord of item in the type specific grid (ie, the 'pistol' item has the "index" of 2 in all_items, but its the first ranged item in the list so it has the index of 0 in my "ranged_props" grid). This ds_map is the communication barrier between the two.


On another note...does anyone know how to set an enum on the global level? Is this even possible? Syntax I am trying that gives me errors:

Code:
enum global.x {
...
}

global enum x {
...
}

global.x = enum {
...
}
 
Top