Legacy GM <Solved> Console "out of bounds" error

The error:
Code:
Grid 0, index out of bounds writing [-1,0] - size is [4,4]
Now this implies that I am trying to write to a grid in a position that doesn't exist. I used the debugger and set many break points, going one step at a time until I found the culprit.

Code:
  // Left side
            if (bx-1 > -1)
                {
                if (ds_grid_get(ds_map_find_value(chunk[#argument0,argument1],argument2),bx-1,by) == AIR) v_sideleft = true;
                }
                else
                {
                if (chunk[#argument0-1,argument1] > 0) // this line causes the message
                    {
                    if (ds_grid_get(ds_map_find_value(chunk[#argument0-1,argument1],argument2),15,by) == AIR) v_sideleft = true;
                    }
                }
(for context, chunk[#] holds ds_map id's)

Now as you can see, there is no writing taking place here. So the error message doesn't make sense. However, something is going wrong as the script is failing to do it's job. Previously, the script was working just fine until I decided I had to change a 2d array to a grid. ("chunk[#]" was originally "chunk[]")

So the problem started after I made that change. Oddly enough, this grid is accessed this way in all of the scripts in the game, and it's only a problem here. I've spent a lot of time debugging this and it took way too long to track it down and now that I finally have, I'm completely stumped as I can't make sense of the error.

Thinking deeply on it, if it were trying to access a position that didn't exist, a 0 would be returned, so this whole script would continue to execute (which is why it doesn't crash I suppose) it would just be doing a lot of things incorrectly resulting in the chaos that is going on in the game.

Is there something I am misunderstanding about how to use accessors? Or is the error message just incorrectly saying "writing" when it should be saying "reading"? Any tips or ideas would be greatly appreciated.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Throw some show_debug_message calls in there to show the values returned, ie:

Code:
if (bx-1 > -1)
               {
               if (ds_grid_get(ds_map_find_value(chunk[#argument0,argument1],argument2),bx-1,by) == AIR) v_sideleft = true;
               }
               else
               {
               show_debug_message("ARGUMENT0 - 1 = " + string(argument0 - 1));
               show_debug_message("ARGUMENT1 = " + string(argument1));
               show_debug_message("ACCESSOR VALUE = " + string(chunk[#argument0 - 1,argument1]));
               if (chunk[#argument0-1,argument1] > 0) // this line causes the message
                   {
                   if (ds_grid_get(ds_map_find_value(chunk[#argument0-1,argument1],argument2),15,by) == AIR) v_sideleft = true;
                   }
               }
Then check the values shown in the console. Also note that an out-of-bounds call to the ds_grid_get function (which is what the # accessor really calls) will return undefined and not 0.
 
P

ParodyKnaveBob

Guest
Howdy, deathzero, and welcome to the GMC. $:^ J
(Ninja'd! I'll keep writing, though.)
Two things:

1. Since you're using accessors anyway, why not .. use them all the way? $:^ ]

Code:
if (ds_grid_get(ds_map_find_value(chunk[# argument0, argument1], argument2), bx-1, by) . . .
can be rewritten

Code:
my_map = chunk[# argument0, argument1];
my_grid = my_map[? argument2];
if (my_grid[# bx-1, by] . . .
(with better temporary variable names for the map and grid, of course, for easier code reading and maintenance. By the way, you might want temporary variables to store your arguments, too).

2. To get closer to actually solving your problem: what is argument0? Apparently, it can be 0, despite however you get bx's value. But yep, like Nocturne said, it works wonders to show_debug_message() -- or for that matter, watching the values in the debugger while stepping through the code running the game in debug mode.

I hope this helps, $:^ J
 
Throw some show_debug_message calls in there to show the values returned, ie:

Code:
if (bx-1 > -1)
               {
               if (ds_grid_get(ds_map_find_value(chunk[#argument0,argument1],argument2),bx-1,by) == AIR) v_sideleft = true;
               }
               else
               {
               show_debug_message("ARGUMENT0 - 1 = " + string(argument0 - 1));
               show_debug_message("ARGUMENT1 = " + string(argument1));
               show_debug_message("ACCESSOR VALUE = " + string(chunk[#argument0 - 1,argument1]));
               if (chunk[#argument0-1,argument1] > 0) // this line causes the message
                   {
                   if (ds_grid_get(ds_map_find_value(chunk[#argument0-1,argument1],argument2),15,by) == AIR) v_sideleft = true;
                   }
               }
Then check the values shown in the console. Also note that an out-of-bounds call to the ds_grid_get function (which is what the # accessor really calls) will return undefined and not 0.
says in the documentation on ds_grid_get()
This function can be used to get the value (either a real number or a string) from any cell within the given ds_grid. If you pass invalid grid coordinates to the function, then the value returned will be 0.
So it's returning 0, otherwise I would be getting a crash trying to compare two different data types or something along those lines I assume.

Well the point of the script is that yes argument0 will be equal to -1, it's supposed to be, what i'm really trying to do with that if statement, is prevent it from trying to grab a value that doesn't exist. So when chunk[# argument0-1, argument1] returns 0 due to it being out of bounds, it doesn't perform the action below. Which appears to be working correctly despite the console messages.

Honestly the only reason I made this post was to question the console message, saying "writing" instead of reading, which made me think that maybe I'm not understanding accessors properly? That perhaps the issues I'm having is stemming from misusing them or something like that.

...

ARGUMENT0 - 1 = -1
ARGUMENT1 = 0
Grid 0, index out of bounds writing [-1,0] - size is [4,4]
ACCESSOR VALUE = undefined
Okay so apparently you were right and the docs are wrong, it does return undefined... Well that is probably a big issue than haha. It's very questionable now what happens in all of these functions and compares when it may be returning undefined instead of 0. Gonna have to think about this one.
 
Haha I didn't know that. Looks like GMS2 has the correct information than. In GMSv1.4 it says it will return 0. Well I have no idea what my original intention was when I made this script but I changed it to this:
Code:
// Left side
            if (bx-1 > -1)
                {
                if (ds_grid_get(ds_map_find_value(chunk[#argument0,argument1],argument2),bx-1,by) == AIR) v_sideleft = true;
                }
                else
                {
                if (argument0-1 != -1)
                    {
                    if (ds_grid_get(ds_map_find_value(chunk[#argument0-1,argument1],argument2),15,by) == AIR) v_sideleft = true;
                    }
                }
Which is what an older version of the code basically was anyway. Not sure why I changed it later but this still works and avoids the error message. Doesn't fix the problems I have with the game though haha but I will have to spend more time searching for the real problem, since whatever is going wrong has no error messages of any kind.

Consider this thread solved I guess
 

FrostyCat

Redemption Seeker
You wrote the docs, not the runner. That's the disconnect right there. The issue of out-of-bound data structure positions returning values other than the documented undefined has recurred several times throughout GMS 1.x and GMS 2's history. Are you aware of this?

Also, since the original poster uses GMS 1.4, let's look at the equivalent entry for ds_grid_get() in GMS 1.4's Manual:
This function can be used to get the value (either a real number or a string) from any cell within the given ds_grid. If you pass invalid grid coordinates to the function, then the value returned will be 0.
Is the underlined part a whoopsie on your part or actual intended behaviour?
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
Is the underlined part a whoopsie on your part or actual intended behaviour?
Lol! Okay, I confess that I didn't notice this was tagged as 1.4 only... And the 1.4 manual is apparently wrong. After checking it seems that the one of the last updates to 1.4 included the change to the runner to return undefined and I wasn't aware of it so it never made it into the manual.

Sorry all for any confusion caused!
 
Top