GMS 2.3+ Unexplainable Data structure with index does not exist

yira

Member
My first post hopefully of many. I'm very new to this, but have made good progress over 3 months or so, and with luck I hope to finish an ancient world-based Rimworld-like game, one day, and hopefully contribute to the community, as I think GMS is awesome (most of the time).

However I've begun to encounter errors that I search high and low, and for which I cannot find an explanation.

I've been staring at this for my whole Saturday:

My house/building objects (oCustomHouse) are built at beginning of game (3 of them for development's sake), and can be built by the player, like in an RTS.

They each have their own inventory, as a ds_grid made in the house's create step, indexed to instance variable (houseInventory) as they can contain food and other resources.

GML:
var rcsv = global.Resourcescsv;
houseInventory = ds_grid_create(ds_grid_width(rcsv),ds_grid_height(rcsv));

All fine, my peasants are happily moving resources to the houses, until I realise that for some reason, with the newly built houses, the houseInventory ds_grids seemingly disappear instantly on creation of the object. Or I lose their index, whichever way you look at it. This leads to 'Data structure with index does not exist' errors. I narrow it down, and the ds_grid_create is returning 0. The three built by the game will return 24, 25, 26, or 56,57,58 for example, it's different each playthrough. Then the custom built ones come with 0, 0, 0 recurring.

The strange thing is, and this echoes a couple of other weird errors I've had, I can force it to work by doing this:

GML:
var rcsv = global.Resourcescsv;
throwawaygrid1 = ds_grid_create(0,0);
houseInventory = ds_grid_create(ds_grid_width(rcsv),ds_grid_height(rcsv));
Now it's fine, and the returned indexes will come back as e.g. 32, 34, 36 and then, happily, 38, 40, etc.

But I definitely don't want to build this game on shaky foundations, so if anyone has encountered something like this, I'd love to know. Again, I've searched as hard as I can...

Thanks.
 

Roldy

Member
Hi,

the indices for data structures begin at zero. So ds_grid_create returning 0 is returning a valid indices. As well, indices for data structures are reused. So if you destroy a grid that had indices 10, then 10 may be returned when next calling ds_grid_create.

With that being said. What is the value of houseInventory right after creation?

GML:
var rcsv = global.Resourcescsv;
houseInventory = ds_grid_create(ds_grid_width(rcsv),ds_grid_height(rcsv));
show_debug_message(string(houseInventory)); // Print the index
If you create three and they all have the index zero, my first assumption is somewhere you keep destroying ds_grid with index zero. If your solution of making a throw away grid does indeed work then that would reinforce that assumption.

e.g.

  • The throw away grid gets index zero,
  • the real grid gets some other index
  • At some point index 0 is destroyed
  • so the next throw away grid gets index zero
  • etc..
Use Ctrl + Shift + F and search everywhere for ds_grid_destroy and put something like:

GML:
// Right before each ds_grid_destroy output some debug text
show_debug_message(debug_get_callstack(1)[0] + ":: calling grid destroy on index " + string(theIndexBeingDestroyed));

if (theIndexBeingDestroyed == 0) {
    var _breakHere = 1; // Put a break point in the debugger here so you can look through the call stack and start back tracking
}

ds_grid_destroy(theIndexBeingDestroyed);
See if that helps narrow it down at all.

Good luck.

P.S. Most likely you are erroneously destroying index 0. If you are using '0' to indicate a grid that has been destroyed, don't, instead use 'undefined'.

e.g.
GML:
ds_grid_destroy(myGridIndex);
myGridIndex = 0;  // Don't do this in place of null

ds_grid_destroy(myGridIndex);
myGridIndex = undefined; // Do this as it is analog with null
 
Last edited:
Top