• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Diablo Like Items

T

TheMatrixHasMe

Guest
I'm wondering how to do a system with items that have varying stats and when these items are owned the stats that they generated are saved, like diablo for example. Particularly, what's the easiest way to do a system like that when you have to move the object in and out of different ds_lists and shuffle these lists as well. How do you keep track of the object or more importantly how do you keep the object paired/married to its stored stat information?

Thanks!
 

TheouAegis

Member
You can try searching the old forums. There was a guy doing a Diablo loot system; I dont' remember if he ever shared his code, though (I think he posted in the Q&A forum as well as the Advanced Programming forum).

Or try googling the algorithm. I'm sure someone's cracked it by now.
 
C

CaffeineJunky

Guest
What have you tried so far for the solution? It's generally easier to describe the type of system that you want into smaller problems to solve.

I would probably break this into a few problems:

1.) I would design the notion of an item template, which is used to describe the possible range of items of various stats that can appear on an item.
2.) I would then design items as being created from item templates, and create a function to generate a item with random values from that template.
3.) I would then design a system of item classes, which is just a list of templates and probability weights, in addition to the 'no drop' which will also have a probability associated to it.
4.) When I killed a monster, opened a chest, etc, I would randomly choose an item template from the item class randomly according to the probabilities, and then use the function defined in 2.) to create an item from that randomly selected template.

What I'm illustrating here is breaking the problem down into sub-problems that, at a high level that will solve a single part of the problem, each of which should be easy to solve. Then, when I need to solve one, I would break that down into further requirements.

For 1.), I might do the following to start with and adapt the design later if I need to:

An item template should contain:
1.) The name of the item
2.) A list of properties that the item could randomly pick from (or multiple lists, depending on how I want the affix generation to occur)
2.a) Each affix can be weighted equally or according to another probability
2.b) Each affix can have additional data about them, such as a starting number and an ending number
3.) The graphic of the item.

Now I would have to adapt this list of requirements into some kind of GML code. I would use a ds_map to represent a data template, and the keys of the map to represent the information about the template. It might look something like this:

Code:
var giantAxeTemplate;

giantAxeTemplate = ds_map_create();
giantAxeTemplate[?"itemName"] = "Giant's Axe"
giantAxeTemplate[?"graphic"] = spr_giants_axe
var properties;
properties = ds_list_create();
giantAxeTemplate[?"properties"] = properties;

//I would define the properties elsewhere and reference them, if there is a common pool of them
var property;
property = ds_map_create();
properties[|0] = property;
property[?"name"] = "Strength Bonus";
property[?"relativeProbability"] = 4;
property[?"startingValue"] = 10;
property[?"endingValue"] = 15;
I hope this can help you get started on creating a complex system of randomly dropped items. Give it a go and see how far you can get.
 
T

TheMatrixHasMe

Guest
@TheouAegis && @CaffeineJunky
I don't really need help with a loot generating system, that should be relatively easy. My issue really revolves more around the storage aspect. Right now I have fixed items with fixed stats. Now, if you could store an id and then create, rather than an object, this would be a piece of cake right? Like, you would generate the item, give it its random stats, then save the id in the ini file or what have you then instance_create(x,y,id) and boom the item with its specific qualities. However, we all know you can't do that. Instead, you store object_index or the object name in the ini file and instance_create(x,y,object_index) or asset_get_index("object name here"); etc. Because of this, unless you have a ridiculous number of items for each variance in each stat attribute, you can't recreate specific item variance. So, you likely have to store the object but ALSO (separately) the stats to go with each attribute and then when you create the object, you change the variables to match the file information stored right? Which is of course complicated if you want to say shuffle the items around like a deck of cards, or have multiples of the same item shuffled around in a list such as obj_health_potion,obj_mana_potion,obj_health_potion, etc. So, this is more of a storage and tracking question? or am I thining of it in the wrong way?

Perhaps a system that runs everything in parallel, keeping track of a list of objects and then a list of stored attributes, perhaps an array, attribute[0],attribute[1], etc. This seems pretty complex when you get into it.
 
Last edited by a moderator:
Z

zendraw

Guest
ive just red the diablo wiki and from what ive understood, theyr method of generating items is procedural, like from what the item will be overall gold/armor/weapon, to what type of the item, what affixes it will hold, etc. and these all depend on the type of monster, difficulty, etc.

imagine it like this. whenyou kill somthing you have 2 choises
drop a fruit or a machine
then you chose what type of fruit depending on somthing banana or apple or grapes
then you chose the sort of the apple green red yellow
then you choose its stats like ripe, ok, nasty, special etc
then you choose somthing else. i think you get the point
 
W

whale_cancer

Guest
@TheouAegis && @CaffeineJunky
I don't really need help with a loot generating system, that should be relatively easy. My issue really revolves more around the storage aspect. Right now I have fixed items with fixed stats. Now, if you could store an id and then create, rather than an object, this would be a piece of cake right? Like, you would generate the item, give it its random stats, then save the id in the ini file or what have you then instance_create(x,y,id) and boom the item with its specific qualities. However, we all know you can't do that. Instead, you store object_index or the object name in the ini file and instance_create(x,y,object_index) or asset_get_index("object name here"); etc. Because of this, unless you have a ridiculous number of items for each variance in each stat attribute, you can't recreate specific item variance. So, you likely have to store the object but ALSO (separately) the stats to go with each attribute and then when you create the object, you change the variables to match the file information stored right? Which is of course complicated if you want to say shuffle the items around like a deck of cards, or have multiples of the same item shuffled around in a list such as obj_health_potion,obj_mana_potion,obj_health_potion, etc. So, this is more of a storage and tracking question? or am I thining of it in the wrong way?

Perhaps a system that runs everything in parallel, keeping track of a list of objects and then a list of stored attributes, perhaps an array, attribute[0],attribute[1], etc. This seems pretty complex when you get into it.
You are overthinking this, I think.

When I made a similar system, I just procedurally generated items and stored them in a ds_map with all their information. These ds_maps were then stored in a ds_list I could access when needed. For saving, you just write the list to a file.
 
T

TheMatrixHasMe

Guest
You are overthinking this, I think.

When I made a similar system, I just procedurally generated items and stored them in a ds_map with all their information. These ds_maps were then stored in a ds_list I could access when needed. For saving, you just write the list to a file.
I think this answer makes a lot of sense. I've worked with ds_lists a lot and ds_grids as well but maps not so much which is probably why I haven't put this one together yet. But you seem to be implying something in the spirit of:
ds_map_add(id,name,object_get_name(object_index));
ds_map_add(id,attribute[0],data);
ds_map_add(id,attribute[1],data);
etcetera,
then some kind of var inst = instance_create(x,y,ds_map_find_value(id,name));
inst.attribute[0] = ds_map_find_value(id,attribute[0]);
etc.?
Basically combine that with CaffeineJunky's system?
 
C

CaffeineJunky

Guest
@TheMatrixHasMe

I agree with @whale_cancer in that you are overthinking it. The items will be stored in memory throughout the context of the game. Any dropped item object will simply need to reference the map that is created, and this will hydrate the item object with the necessary information. If you need to persist the items outside of the game, you can use convert the data structure to a JSON object as part of your normal save file. Depending on your needs (such as saving items on the ground that are not picked up between game sessions), you should think through your entire save system to accommodate this.

I would recommend an approach where your objects are driven by a data store in some common location, such as a controller object. But I wouldn't store anything about the actual object implementation in that data store, just the data.
 
W

whale_cancer

Guest
I think this answer makes a lot of sense. I've worked with ds_lists a lot and ds_grids as well but maps not so much which is probably why I haven't put this one together yet. But you seem to be implying something in the spirit of:
ds_map_add(id,name,object_get_name(object_index));
ds_map_add(id,attribute[0],data);
ds_map_add(id,attribute[1],data);
etcetera,
then some kind of var inst = instance_create(x,y,ds_map_find_value(id,name));
inst.attribute[0] = ds_map_find_value(id,attribute[0]);
etc.?
Basically combine that with CaffeineJunky's system?
The specifics depend entirely on how you are actually using your inventory items in your game. For me, I use(d) them in a JRPG like item inventory, so they are just pieces of code handled by a couple of objects. If they were, for instance, pickups in an action title; I would create a generic pickup object that read the appropriate ds_map and set its own attributes accordingly.

Re:
Code:
[...]
ds_map_add(id,attribute[0],data);
ds_map_add(id,attribute[1],data);
[...]
Should be more like

Code:
ds_map_add(inventory, "item type", 7);
ds_map_add(inventory, "value", 18);
ds_map_add(inventory, "weight", 4);
then some kind of var inst = instance_create(x,y,ds_map_find_value(id,name));
inst.attribute[0] = ds_map_find_value(id,attribute[0]);
etc.?
Not that I am aware of. I wrote my own code to handle loading variables from ds_maps.
 
T

TheMatrixHasMe

Guest
@whale_cancer and anyone else it concerns, for context I have been designing a card collection game and have been considering more of diablo style generation for the card stats rather than having them fixed. So there wouldn't be any drops, but more of a random generation from card packs, etc. So say a character card could have varying hit points, attack, armor, etc. I store the cards in ds_lists and sometimes have to copy from one list to another and/or shuffle the lists, moving the cards around. Also, there obviously multiples of the same types of cards just like a person can have multiple same type weapons or armor in a diablo inventory. So if each item in your diablo inventory were instead a card, how would you do that?
 
W

whale_cancer

Guest
@whale_cancer and anyone else it concerns, for context I have been designing a card collection game and have been considering more of diablo style generation for the card stats rather than having them fixed. So there wouldn't be any drops, but more of a random generation from card packs, etc. So say a character card could have varying hit points, attack, armor, etc. I store the cards in ds_lists and sometimes have to copy from one list to another and/or shuffle the lists, moving the cards around. Also, there obviously multiples of the same types of cards just like a person can have multiple same type weapons or armor in a diablo inventory. So if each item in your diablo inventory were instead a card, how would you do that?
Sorry to have to give basically the same answer, but it depends on how you are implementing them.

The way I would design such a system in such a game would be to have code that generates cards depending on the arguments supplied to a script (like the level of the card to generate, the rarity, etc.,). Run that script and copy the generated ds_map to a ds_list associated with your player (this could be a global ds_list or one specific to the player object, depending on various factors; though, generally speaking, the global list is simpler).

You would then have code to handle the cards in a given situation. Say you have a room that you use for the player to browse their collection. Well, you would just run through the player's list and and generate objects that allow the player to interact with the cards in the ds_list (for instance, you could right click to throw away a card, deleting the object and the ds_list entry it was generated from; or you could left click to equip the card, and either copy it to a list of equipped cards or have a ds_list that just points to the player's master ds_list of cards, applying stat modifiers as appropriate).
 
T

TheMatrixHasMe

Guest
Sorry to have to give basically the same answer, but it depends on how you are implementing them.

The way I would design such a system in such a game would be to have code that generates cards depending on the arguments supplied to a script (like the level of the card to generate, the rarity, etc.,). Run that script and copy the generated ds_map to a ds_list associated with your player (this could be a global ds_list or one specific to the player object, depending on various factors; though, generally speaking, the global list is simpler).

You would then have code to handle the cards in a given situation. Say you have a room that you use for the player to browse their collection. Well, you would just run through the player's list and and generate objects that allow the player to interact with the cards in the ds_list (for instance, you could right click to throw away a card, deleting the object and the ds_list entry it was generated from; or you could left click to equip the card, and either copy it to a list of equipped cards or have a ds_list that just points to the player's master ds_list of cards, applying stat modifiers as appropriate).
That's basically what I do for the most part. There are different lists, such as global.cards and global.deck where deck are the chosen cards for battle and cards are the complete collection of all the players cards outside of the deck. Right now the information is fixed to the object, basically the variables that are initialized in the create event. But I just need to add the ds_map system on top of what I'm already doing it seems. I'll play with it and see how well it works out. Thanks for all the help guys. I really do appreciate everyone taking the time to think about my question and respond.
 
Top