Inventory items using 2 grids

Discussion in 'Programming' started by Schwee, Sep 13, 2019.

  1. Schwee

    Schwee Member

    Joined:
    Jul 6, 2016
    Posts:
    166
    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!
     
  2. Catan

    Catan Member

    Joined:
    Jun 20, 2016
    Posts:
    700
    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.
     
  3. Schwee

    Schwee Member

    Joined:
    Jul 6, 2016
    Posts:
    166
    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: Sep 13, 2019
  4. Catan

    Catan Member

    Joined:
    Jun 20, 2016
    Posts:
    700
    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.

    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.

    This is generally where I see others go for a ds_grid, but it's just one way to do it.

    Again, that's what ds_maps are for.
     
  5. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,398
    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.
     
  6. Catan

    Catan Member

    Joined:
    Jun 20, 2016
    Posts:
    700
    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.
     
  7. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,926
    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.
     
  8. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,398
    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
     
  9. Catan

    Catan Member

    Joined:
    Jun 20, 2016
    Posts:
    700
    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.
     
  10. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,398
    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
     
    Catan likes this.
  11. Schwee

    Schwee Member

    Joined:
    Jul 6, 2016
    Posts:
    166
    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 {
    ...
    }
    
    
     
  12. Schwee

    Schwee Member

    Joined:
    Jul 6, 2016
    Posts:
    166
    Nvm...enums are implicitly global in case anyone else didn't know.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice