GML Flexible Inventory System

So if I understand correctly, you have a ds_grid for the crafting slots. Say we have two crafting slots:
Code:
global.crafting_slots = ds_grid_create(2, 2);
The recipe grid, if I follow you, will be the total number of recipes wide, and since we have 2 crafting slots, 4 elements tall. So:
Code:
global.recipes = ds_grid_create(recipe.total, 4);
The underlying logic of checking the correct item and quantity and outputting the right item shouldn't be too difficult.

Is the basic implementation I described as intended?

Thanks.
That is exactly right. Good luck! Just loop through your recipe grid and check if it matches each item. Not too hard if you're familiar with grids and loops.
 
N

Nabil Kabour

Guest
I know this is outside the scope of this tutorial. You said that you do not claim this to be the most memory efficient method of having an inventory. Out of interest I wanted to ask what would be a memory efficient method of having an inventory, but I just did a quick test and found that 100,000 items in the item index only uses 30 mb of memory. Still, I find it rather unappealing to have the item index and crafting recipes always in memory. Practically this won't have any adverse effects as shown by the test, but just for curiosity's sake. I understand if you would rather not comment on this. Thanks.
 
The statement about not being the most efficient memory solution was only to clarify that I did not take particular time optimizing the system. I prioritized ease of use and simplicity in concept over anything else. For all I know, it IS the most memory efficient.

I don't actually know of a more memory efficient method, at least, not one that has the same features and ease of use as this solution. Maybe you could delete and reinitialize the item index in between moments of using it, but to be honest, it's not really worth the effort and might cause unwanted side effects. If your tests don't show any adverse effects for your game (and my uses of the same system in my own games prove functional as well), the don't worry about it. Premature optimization is something to avoid.
 
N

Nabil Kabour

Guest
I'm trying to make an inventory system with upgradable items and crafting. I currently have upgradable items by storing all of the items properties (including item_id) in one of the rows of the item index grid, and when adding an item to the inventory I copy the entire item_stat column. I can then upgrade items by modifying the values of item_stat of the inventory. I want the item index to contain the base stats of each item (stats when it is purchased from the shop), and the maximum stats it can be upgraded to have. The best way I can think of is to have a 3d ds_grid, with the first element being the item_id, second stat_type (base or max), and third item_stat. Obviously 3d grids don't exist so I need to use another method. A point to make is I think that hat having the item_id as a grid element while having the item_id stored in the stats is redundant, but I cant think of another way to get the item_stats out of the grid based on the item_id. What do you think?

Edit: I just realized I could have 2 grids, one for base and one for max stats. Doesn't feel like a good approach though.
 
Last edited by a moderator:
Instead, just have two stats. Like, stat.armor, and stat.armor_max. When you copy from the item index you should probably only copy the base stats, and use the item index to look up the map stats when you need them. (They'll already be the same for each instance of the item, so you don't need that part stores individually).

You can do that by making all of the max stat data stored at the end of the grid, and you copy the left half only.

But also, two grids is probably a pretty good approach. Maybe better than I just described. It takes the same amount of memory and it's easier to manage. The other thing I'd consider is making the range of variation in modified items mathematically related. For example: say the maximum damage is always 25% more than the base damage. This can let you store less information, and gives you a way to mathematically compare how powerful certain items are. But that may not serve your purpose.
 
Last edited:
N

Nabil Kabour

Guest
Instead, just have two stats. Like, stat.armor, and stat.armor_max. When you copy from the item index you should probably only copy the base stats, and use the item index to look up the map stats when you need them. (They'll already be the same for each instance of the item, so you don't need that part stores individually).

You can do that by making all of the max stat data stored at the end of the grid, and you copy the left half only.

But also, two grids is probably a pretty good approach. Maybe better than I just described. It takes the same amount of memory and it's easier to manage. The other thing I'd consider is making the range of variation in modified items mathematically related. For example: say the maximum damage is always 25% more than the base damage. This can let you store less information, and gives you a way to mathematically compare how powerful certain items are. But that may not serve your purpose.
Yeah having a relation between base and max stats seems the most reasonable. Saves the hassle of defining every max stat for each item.
 
N

Nabil Kabour

Guest
I am unsure about the current inventory system though. Like I said I am copying the entire item_stat column into the inventory. It seems rather redundant since some stats are not modified. I would say my item_index rows should be called item_info instead of item_stat. It is currently very easy to work with in the current setup, but it is possible to accidentally change the value of a stat that shouldn't be modified.
 
N

Nabil Kabour

Guest
And also, for crafting not only do you need to store the ingredients, but also the output item, correct?
 
I am unsure about the current inventory system though. Like I said I am copying the entire item_stat column into the inventory. It seems rather redundant since some stats are not modified. I would say my item_index rows should be called item_info instead of item_stat. It is currently very easy to work with in the current setup, but it is possible to accidentally change the value of a stat that shouldn't be modified.
If you can think of a way that works better for your system, by all means do that. The tutorial is not meant to force you to do it a particular way, just give you a good idea (also it's not meant for modifyable items, though many principles still carry through). I don't think that accidentally modifying the value of a stat you don't want to change should be all that easy to do. You'd have to have a logic error that you caused yourself which would cause problems no matter if those extra values where there or not. Of course, another system would be to do something and store only the values that are pertinent for a particular item, like Minecraft which uses json modifiers for individual items (that's when an item says +NBT). That's probably a better system to be honest, but it's very different than this tutorial so I can't help you much there.

And also, for crafting not only do you need to store the ingredients, but also the output item, correct?
Yes.
 
Hi this is my first time on the gamemaker forum so I hope this works!
I have a question regarding stack limits. The demo works fine when I move items around the inventory but cant figure put how to make the automatic item adding function check that there is room in the slot.
Thanks in advance for any suggestions!
 
Hi this is my first time on the gamemaker forum so I hope this works!
I have a question regarding stack limits. The demo works fine when I move items around the inventory but cant figure put how to make the automatic item adding function check that there is room in the slot.
Thanks in advance for any suggestions!
I can explain it logically at least:

You want to iterate through the slots of the inventory, taking the item id of the item you want to add and the quantity of items. (Assuming that number of items being added is less than the stack limit for that item).

On any given slot, you have a few cases:
- The item id is different than the one you are adding: Move to the next slot (you can't put the item there)
- The slot is empty: Put the item and the appropriate quantity in that slot and exit
- The item id matches: Place as many items as you can into that slot and then repeat. If the space left in that slot is enough to fit all of them, exit. Otherwise set that slot to the stack limit (totally filled up) and subtract the number of items needed to fill it from the items you are planning to add, so you can put the rest of the items somewhere else.
- Finally, there are no slots left: you'll want some sort of exit case for this, like leaving the remaining items on the floor, or prompting the player to choose some items to discard.
 
I can explain it logically at least:

You want to iterate through the slots of the inventory, taking the item id of the item you want to add and the quantity of items. (Assuming that number of items being added is less than the stack limit for that item).

On any given slot, you have a few cases:
- The item id is different than the one you are adding: Move to the next slot (you can't put the item there)
- The slot is empty: Put the item and the appropriate quantity in that slot and exit
- The item id matches: Place as many items as you can into that slot and then repeat. If the space left in that slot is enough to fit all of them, exit. Otherwise set that slot to the stack limit (totally filled up) and subtract the number of items needed to fill it from the items you are planning to add, so you can put the rest of the items somewhere else.
- Finally, there are no slots left: you'll want some sort of exit case for this, like leaving the remaining items on the floor, or prompting the player to choose some items to discard.
Thanks this is exactly the sort of thing I was looking for!
I was thinking another way could be to use a loop and add 1 item at a time until there are none left to add.
Thanks for you help!
 
So i'm still working on adding stack limits when new items are added to the inventory and I think I'm on the right track but for some reason(its probably really obvious) my code sets every inventory slot to the id with an amount of 0. (this is in GM8 by the way, hence the ds_grid_add functions and i replaced enumerators with a list system. I know these functions work properly because they do everywhere else.)
Here is the code:
//this script will search for an available slot and add the input item into the inventory
var iid,amount,slot,inv_width,items;

iid = argument0;
amount = argument1;
slot = 0;
items = amount;
inv_width = ds_grid_width(global.inventory)

{
while(slot < inv_width)
{
//if the slot is either empty or contains a matching id
if (ds_grid_get(global.inventory,slot,0) == iid) or (ds_grid_get(global.inventory,slot,0) == item('Empty'))
{
ds_grid_set(global.inventory,slot,0,iid);
while(items >0 and ds_grid_get(global.inventory,slot,1)<item_get_stacklimit(iid))
{
ds_grid_add(global.inventory,slot,1,1);
items-=1;
//check items
if items <=0
{
return true;
exit;
}
}
}
slot +=1;
}
}
return false;
 
What exactly happene instead of the intended behavior? On first inspection this code seems A-Okay. I need more information (and I'll look into it with more depth in a few hours when I have time).
 
What exactly happene instead of the intended behavior? On first inspection this code seems A-Okay. I need more information (and I'll look into it with more depth in a few hours when I have time).
Yes I thought it looked ok but what it does is sets every slot to the input id then sets them all to an amount of 0. I'm not sure why?

If you can have a better way to achieve the result I'm looking for that would be much appreciated because this one has stumped me a bit...
 
Yes I thought it looked ok but what it does is sets every slot to the input id then sets them all to an amount of 0. I'm not sure why?

If you can have a better way to achieve the result I'm looking for that would be much appreciated because this one has stumped me a bit...
I looked in more detail and I honestly cannot figure out what the issue is. I'd check to make sure there's no other code that's overriding that code (or something like running the gain item multiple times). I can't say honesty.

My code actually works a little differently: namely, the code I used (I just checked because I haven't looked at it for over a year), checks for matching slots first (looping through and adding as many items as possible to a matching slot) and then looks for empty slots to put the rest. This is nice because if there's an empty slot before a matching slot, it'll still put it in the matching slot. So, perhaps you might consider rewriting it, either the same, or a different way such as I described and see what happens?

I'll update the tutorial to include my solution so you can look at that for reference. Maybe you'll notice something I didn't that results in your code not working?

EDIT: Updated the tutorial with two more variations of an item gain function, you can see my solution for stack limits under the stack limit section. (Not gonna lie, this tutorial is getting so complicated, it's very hard to do updates without getting confused, can't promise that code would work copy/paste, at least for anyone else using GMS1/2, obviously 8 would need modifications anyways).
 
Last edited:
I looked in more detail and I honestly cannot figure out what the issue is. I'd check to make sure there's no other code that's overriding that code (or something like running the gain item multiple times). I can't say honesty.

My code actually works a little differently: namely, the code I used (I just checked because I haven't looked at it for over a year), checks for matching slots first (looping through and adding as many items as possible to a matching slot) and then looks for empty slots to put the rest. This is nice because if there's an empty slot before a matching slot, it'll still put it in the matching slot. So, perhaps you might consider rewriting it, either the same, or a different way such as I described and see what happens?

I'll update the tutorial to include my solution so you can look at that for reference. Maybe you'll notice something I didn't that results in your code not working?

EDIT: Updated the tutorial with two more variations of an item gain function, you can see my solution for stack limits under the stack limit section. (Not gonna lie, this tutorial is getting so complicated, it's very hard to do updates without getting confused, can't promise that code would work copy/paste, at least for anyone else using GMS1/2, obviously 8 would need modifications anyways).
Thanks so much for your help. I will take a look at your updated tutorial. I appreciate all the work you did to help.
 
G

Gustavo Miler

Guest
hi, i got a problem with the global.item_index = ds_grid_create(item.total, item_stat.total);

it get an error while opening the game, it says that "enum reference 'total' does not exist in 'item'" and "enum reference 'total' does not exist in 'item_stat'"

any idea why?

Game Maker 1.4.1
 
hi, i got a problem with the global.item_index = ds_grid_create(item.total, item_stat.total);

it get an error while opening the game, it says that "enum reference 'total' does not exist in 'item'" and "enum reference 'total' does not exist in 'item_stat'"

any idea why?

Game Maker 1.4.1
It probably means either: you did not define your enumerators (See - Setting Up Items / Item IDs) or you did define those enumerators, but the enumerators within do not have the matching reference names (like 'total'). Check that first section to make sure everything is defined properly.
 

simes007us

Member
Hi everyone,

This is an amazing tutorial I easily modified the code to give myself more than 1 row of storage space by using a couple of for loops.

However, I am having some trouble with getting the standard initialized objects in the inventory to only show up in 1 slot. They show up in every row. It looks like this:



Any ideas on how to fix this?

for (slot =0; slot < ds_grid_width(global.inventory); slot++)
{
for (i=0; i<ds_grid_height(global.inventory); i++)
{
var inst = instance_create_layer(x+8+(64*slot), (y+8)+(64*i), "Instances", obj_slot);
inst.var_slot = slot;
}
}
 
Hi everyone,

This is an amazing tutorial I easily modified the code to give myself more than 1 row of storage space by using a couple of for loops.

However, I am having some trouble with getting the standard initialized objects in the inventory to only show up in 1 slot. They show up in every row. It looks like this:



Any ideas on how to fix this?

for (slot =0; slot < ds_grid_width(global.inventory); slot++)
{
for (i=0; i<ds_grid_height(global.inventory); i++)
{
var inst = instance_create_layer(x+8+(64*slot), (y+8)+(64*i), "Instances", obj_slot);
inst.var_slot = slot;
}
}
Yeah, so you're close. The mistake you made is with how the grid is actually set up. The inventory grid itself only has one dimension really: the first position in the grid shows you which slot you're referring too. The other is for item_id/item_quantity (so you can store more information in each inventory slot). You need two new variables for the xx and yy position you want to create slots at, and an incrementing variable for each slot.

The inventory is by default structured like this, one dimension:


You want to modify the position of your slots so it's like this. But the inventory is still one dimensional.


What you've done is more like...



... etcetera.

This is explained in more detail on the fourth post on the thread.
 

simes007us

Member
Yeah, so you're close. The mistake you made is with how the grid is actually set up. The inventory grid itself only has one dimension really: the first position in the grid shows you which slot you're referring too. The other is for item_id/item_quantity (so you can store more information in each inventory slot). You need two new variables for the xx and yy position you want to create slots at, and an incrementing variable for each slot.

The inventory is by default structured like this, one dimension:


You want to modify the position of your slots so it's like this. But the inventory is still one dimensional.


What you've done is more like...



... etcetera.

This is explained in more detail on the fourth post on the thread.
Thanks for the quick reply! I actually re-read the post and it dawned on me how to fix this. I now have the slots working correctly. I am now working on moving the inventory around with the view which is proving more difficult than I thought it would be :D If you move the control object around in the room editor it works but you can't move it in a step event.
 
If you move the control object around in the room editor it works but you can't move it in a step event.
You need to move the obj_slot around, not just the controller object. Alternatively (and better), you can use Draw GUI on the slots to make it draw everything based on the view, and not actually move any objects.
 

simes007us

Member
Hello, it's me again! I'm still loving the inventory I've added a bunch of stuff to it like item rank.
Would you happen to know how to lock out specific slots for specific items? I've been struggling with how to do this for a couple days now. Essentially, I have used the first 8 slots of the inventory for the slots in my spaceship and I want to stop the player being able to put a shield in an engine slot for example. I have already forced the item collection into slot 9.

Best,
Simon
 
Hello, it's me again! I'm still loving the inventory I've added a bunch of stuff to it like item rank.
Would you happen to know how to lock out specific slots for specific items? I've been struggling with how to do this for a couple days now. Essentially, I have used the first 8 slots of the inventory for the slots in my spaceship and I want to stop the player being able to put a shield in an engine slot for example. I have already forced the item collection into slot 9.

Best,
Simon
Yeah, so that's not too hard, but you do need to program it manually.

So basically, each of those item groups (like, shields) need to have their own item type as defined in the item_index and the item_type enumerator. Then in your item gain and item moving scripts you need to check for each case. Like: if the slot is 4 and the item type is shield, then put the item in there. Otherwise don't. Then something else for slot 5 or 6 or whatever. And the gain script for picking up items will need to skip any slots that the picked up item's type is not compatible for. Or if you have a general inventory and a specific slot to equip things, you can just add items to the inventory starting at slot 9 and later to skip any manual equip slots.

Another way which might be easier depending, is having a separate inventory for some of those things. Just another grid set up the same way. Check the advanced section for chests to get an idea. The above is easier but it might take more code than setting up other inventories.
 

simes007us

Member
I finally figured out how to lock out slots and specific items. Is it glamorous, nope but it works!

Code:
    var iid = global.inventory[# var_slot, 0];   
    var amount = global.inventory[# var_slot, 1];
    var rank = global.inventory[# var_slot, 2];
    var stack = global.inventory[# var_slot, 3];
    var mouse_iid = global.mouse_slot[# 0, 0];
    var mouse_amount = global.mouse_slot[# 0, 1];
    var mouse_rank = global.mouse_slot[# 0, 2];
    var mouse_stack = global.mouse_slot[# 0, 3];
       
    if ((iid > 0)) //picking up
    {
        //Switch the slots
        global.inventory[# var_slot, 0] = mouse_iid;
        global.inventory[# var_slot, 1] = mouse_amount;
        global.inventory[# var_slot, 2] = mouse_rank;
        global.inventory[# var_slot, 3] = mouse_stack;
        global.mouse_slot[# 0, 0] = iid;
        global.mouse_slot[# 0, 1] = amount;
        global.mouse_slot[# 0, 2] = rank;
        global.mouse_slot[# 0, 3] = stack;   
    }
    if ((mouse_iid > 0)) //putting down
    {
        {
        //locking engine slot
        if (mouse_iid =8 and var_slot =1 || var_slot >8)
            {
            global.inventory[# var_slot, 0] = mouse_iid;
            global.inventory[# var_slot, 1] = mouse_amount;
            global.inventory[# var_slot, 2] = mouse_rank;
            global.inventory[# var_slot, 3] = mouse_stack;
            global.mouse_slot[# 0, 0] = iid;
            global.mouse_slot[# 0, 1] = amount;
            global.mouse_slot[# 0, 2] = rank;
            global.mouse_slot[# 0, 3] = stack;   
            }
            //locking sensor slots
        if (mouse_iid =13 and var_slot =8 || var_slot >8)
            {
            global.inventory[# var_slot, 0] = mouse_iid;
            global.inventory[# var_slot, 1] = mouse_amount;
            global.inventory[# var_slot, 2] = mouse_rank;
            global.inventory[# var_slot, 3] = mouse_stack;
            global.mouse_slot[# 0, 0] = iid;
            global.mouse_slot[# 0, 1] = amount;
            global.mouse_slot[# 0, 2] = rank;
            global.mouse_slot[# 0, 3] = stack;   
            }
            //locking weapon slots
        if ((mouse_iid =9 || mouse_iid =10 || mouse_iid =11 || mouse_iid=12)  and (var_slot =3 || var_slot =4) || var_slot >8)
            {
            global.inventory[# var_slot, 0] = mouse_iid;
            global.inventory[# var_slot, 1] = mouse_amount;
            global.inventory[# var_slot, 2] = mouse_rank;
            global.inventory[# var_slot, 3] = mouse_stack;
            global.mouse_slot[# 0, 0] = iid;
            global.mouse_slot[# 0, 1] = amount;
            global.mouse_slot[# 0, 2] = rank;
            global.mouse_slot[# 0, 3] = stack;   
            }
            //locking shield slots
        if (mouse_iid =1 and var_slot =2 || var_slot >8)
            {
            global.inventory[# var_slot, 0] = mouse_iid;
            global.inventory[# var_slot, 1] = mouse_amount;
            global.inventory[# var_slot, 2] = mouse_rank;
            global.inventory[# var_slot, 3] = mouse_stack;
            global.mouse_slot[# 0, 0] = iid;
            global.mouse_slot[# 0, 1] = amount;
            global.mouse_slot[# 0, 2] = rank;
            global.mouse_slot[# 0, 3] = stack;   
            }
            //locking thruster slots
        if (mouse_iid =14 and (var_slot =5 ||var_slot=6) || var_slot >8)
            {
            global.inventory[# var_slot, 0] = mouse_iid;
            global.inventory[# var_slot, 1] = mouse_amount;
            global.inventory[# var_slot, 2] = mouse_rank;
            global.inventory[# var_slot, 3] = mouse_stack;
            global.mouse_slot[# 0, 0] = iid;
            global.mouse_slot[# 0, 1] = amount;
            global.mouse_slot[# 0, 2] = rank;
            global.mouse_slot[# 0, 3] = stack;   
            }
       
        }
    }     
    exit;
 
Last edited:
S

soundgarden134

Guest
Hello, first of all, thanks for this huge tutorial! It's helped me a lot in my first game :). Now to the issue, my game has a camera, so even though the sprites do follow the player object, the "slots" don't. I've tried modifying the script "scr_create_inventory", but modifying the coordinates to put them relative to the view just puts the slots in the "right" place once, when the script is executed (img 1). I tried using the same script in a draw GUI event and the issue with that is that the grid would just draw itself over and over while I was moving, like in img 2. Any idea how to solve this?
upload_2019-1-12_1-52-4.png
upload_2019-1-12_1-49-9.png
 
Hello, first of all, thanks for this huge tutorial! It's helped me a lot in my first game :). Now to the issue, my game has a camera, so even though the sprites do follow the player object, the "slots" don't. I've tried modifying the script "scr_create_inventory", but modifying the coordinates to put them relative to the view just puts the slots in the "right" place once, when the script is executed (img 1). I tried using the same script in a draw GUI event and the issue with that is that the grid would just draw itself over and over while I was moving, like in img 2. Any idea how to solve this?
The scr_create_inventory script should only be executed once to initially create the slots. I think what you've done is accidentally recreate the inventory every step so you have tons of copies of it (that is probably what caused the second screenshot). Instead, you want to run the create script once, and then use a separate script in the step event to realign the slot objects to the camera.

For example:
Code:
x = camerax + (slot * 64);
y = cameray + 64;
Then in the draw event you draw relative to the same coordinates, OR you can use the draw GUI event and make them draw raw view coordinates instead of relative to the camera. (Look up how that event works to understand).
 
S

soundgarden134

Guest
The scr_create_inventory script should only be executed once to initially create the slots. I think what you've done is accidentally recreate the inventory every step so you have tons of copies of it (that is probably what caused the second screenshot). Instead, you want to run the create script once, and then use a separate script in the step event to realign the slot objects to the camera.

For example:
Code:
x = camerax + (slot * 64);
y = cameray + 64;
Then in the draw event you draw relative to the same coordinates, OR you can use the draw GUI event and make them draw raw view coordinates instead of relative to the camera. (Look up how that event works to understand).
Thank you! It's working now :)
 
L

Lancers_Bucket

Guest
Quick question, when I was following your tutorial, I got up to Part 2: The Inventory, and Displaying The Inventory, but when I tested the code I got this error
############################################################################################
FATAL ERROR in
action number 1
of Draw Event
for object oSlot:

Variable oSlot.var_slot(100053, -2147483648) not set before reading it.
at gml_Object_oSlot_Draw_64 (line 2) - var iid = global.inventory[# var_slot, 0];
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_oSlot_Draw_64 (line 2)
Is there any thing you can do to help?

Thanks in advance
 
Quick question, when I was following your tutorial, I got up to Part 2: The Inventory, and Displaying The Inventory, but when I tested the code I got this error


Is there any thing you can do to help?

Thanks in advance
Yeah! That means you didn't set var_slot for the slot objects before trying to draw the inventory. Check the code where you're creating then and make sure to define that variable.
 
L

Lancers_Bucket

Guest
Hey, sorry to bother you again but, for interacting with the inventory, I left click, the item slots move one to the right, and the right most item goes into the "mouse item" is this suposed to happen? If so, would there be anyway around this allowing you to click on an item and that goes into the "mouse item"
Thanks again
 
Hey, sorry to bother you again but, for interacting with the inventory, I left click, the item slots move one to the right, and the right most item goes into the "mouse item" is this suposed to happen? If so, would there be anyway around this allowing you to click on an item and that goes into the "mouse item"
Thanks again
No, this is not supposed to happen. I would go check the part in the tutorial about interacting with slots and make sure you didn't mix up a value somewhere.
 
L

Lancers_Bucket

Guest
Hello! (I promise this is the last time) I was able to get the inventory working, but I came across the problem that when I tried moving my player around with the camera, the inventory stayed in the same place in the room. Is there any way of drawing the inventory so that it would be locked to the GUI not the place in the room? Thanks
 
Hello! (I promise this is the last time) I was able to get the inventory working, but I came across the problem that when I tried moving my player around with the camera, the inventory stayed in the same place in the room. Is there any way of drawing the inventory so that it would be locked to the GUI not the place in the room? Thanks
Hi! I believe this question is covered in the tutorial as a footnote. (Someone asked it a while ago). Check under The Inventory/Displaying the Inventory/How do I make it work with views/cameras? That gives a conceptual answer, hopefully, from that, you can figure out how to implement it in code. Good luck!
 
E

Eugene Yap Yew Juen

Guest
How can I make it so the slots stick to GUI layer?

x = display_get_gui_width() / 2;
y = display_get_gui_height() / 2;

var _slot = 0;
while (_slot < ds_grid_width(global.inventory)) {
var _inst = instance_create_layer(x+(32*_slot), y, "Instances", o_slot);
_inst.var_slot_ = _slot;
_slot ++;
}

The result of this are the slot remain on the same position, it will not follow wherever the player go.
 
How can I make it so the slots stick to GUI layer?

x = display_get_gui_width() / 2;
y = display_get_gui_height() / 2;

var _slot = 0;
while (_slot < ds_grid_width(global.inventory)) {
var _inst = instance_create_layer(x+(32*_slot), y, "Instances", o_slot);
_inst.var_slot_ = _slot;
_slot ++;
}

The result of this are the slot remain on the same position, it will not follow wherever the player go.
Coordinates are only relative to the GUI if it is in the Draw GUI events. Outside of that, (x, y) are still absolute coordinates in the room. To fix your code, you need to update the position of the inventory slots relative to the current camera location and their starting location.

Step Event:

Code:
x = camerax + xstart;
y = cameray + ystart;
Use whatever values are your camera position. I used camerax and cameray.

There's another explanation in the tutorial under "Part 2 > Displaying the Inventory > How Do I Make It Work With Views/Cameras".
 
Last edited:

woods

Member
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Create Event
for object obj_inventory_control_2:

global variable name 'inventory' index (100003) not set before reading it.
at gml_Object_obj_inventory_control_2_CreateEvent_1 (line 4) - while (slot < ds_grid_width(global.inventory))
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_obj_inventory_control_2_CreateEvent_1 (line 4)



something went wrong...

is kinda difficult to figure out what goes where.. anybody feel like walking me thru this super step by step? ;o)
 
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Create Event
for object obj_inventory_control_2:

global variable name 'inventory' index (100003) not set before reading it.
at gml_Object_obj_inventory_control_2_CreateEvent_1 (line 4) - while (slot < ds_grid_width(global.inventory))
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_obj_inventory_control_2_CreateEvent_1 (line 4)



something went wrong...

is kinda difficult to figure out what goes where.. anybody feel like walking me thru this super step by step? ;o)
That particular error means you didn't initialize the ds_grid before you used it. It's the first bit of code under "Part 2: The Inventory > Storing Items and Quantities".

In many cases, this tutorial is going to throw errors if you try to compile it before most of the main systems are implemented. Once you think you're finished and you're still running into errors, focus on one at a time, addressing the problem as it is described in the error report.

Considering you ran into trouble with an undeclared variable error, even if you have experience with other kinds of coding, you might consider following some more beginner oriented tutorials so that you can learn the basics of GML before attempting to create an inventory system with many interlocking systems.
 
X

Xiang WayYi

Guest
thank for sharing this tutorial. Can you make more this tutorial about expand inventory such as: make the chests to store items?
 
thank for sharing this tutorial. Can you make more this tutorial about expand inventory such as: make the chests to store items?
Glad you liked it. There's a bit about how to do chests under part 3. However doing all those extra things in detail would take ages, so beyond a bit of something to get started you're on your own, sorry. ;)

But, it's as simple as repeating the same process for other instances to have inventories, then creating different slot objects to transfer items between.
 
H

Hans66

Guest
Hello thanks for the tutorial. Im new to gamemaker and gamemaker language (i have only used C and c#)so forgive me if i ask dumb questions. I have gotten the items to show up and i can add items that show up on screen and i can create new items. But when i try to move items with the mouse it does not work. i cant click on anything andi cant move anything. I havent created a menu room i only have the items show up in game to test the functionality first. This is my game creation object that controls the game :

create_game.PNG




and i have created an object called mouse transfer and in its draw event i have the draw sprite and draw text code and in its create event i have created the global mouse slot:mouse__transfer.PNG Maybe im doing something wrong with that? any help would be much appreciated. Im sorry if its a stupid question.
 
The clicking to pick up items part of code should be contained in obj_slot. On that object, you should have a mouse pressed event to detect that the particular slot is clicked on, and swap the item_id and amount values of the slot and the mouse slot. The stuff you've shown me seems correct on the surface. If you have the obj_slot mouse press, and it still isn't working, try showing me that and we can take a look.

(A note on that, don't forget to move the obj_slot instances to keep themselves in the right position within the room if you are using a view/camera).
 
H

Hans66

Guest
Sorry for late answer i have had a lot on my plate. Thank you for taking the time to reply this is my slot_left_pressed :SLOT_LEFTPRESS.PNG
and this is my slot draw GUI:SLOT_DRAWGUI.PNG
my create is just to play around with the depth to see if it caused any issue but i cannot click on anything regardless of depth. im at a loss have thought about this for a while now. Thank you again for taking your time. Any suggestions at all would be much appreciated
 
So the code looks all good. I suspect the reason you're having issue is something causing the mouse pressed event to not actually trigger. I have a few ideas but I can't say for sure so you'll need to investigate this. Here are some suggestions:
- The slot objects are not in the correct place, if you have a moving view. (Unlikely since your drawing works).
- The slot objects need a mask assigned to detect if they are being clicked on. Make sure of that, and make the mask the same size as the item sprite itself.
- If you'd rather not assign a mask that way, you can also check for the mouse press by using a global mouse left pressed event instead, and checking if the mouse_x and mouse_y is overlapping with the desired area of the slot.
- Also try adding a show_debug_message to the left press event to make sure it isn't running, to verify my theory and ensure it isn't another issue.
 
Top