• 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!

Legacy GM [Solved] Need help understanding error. Push :: Execution Error - Variable Index out of range

O

Obrez

Guest
Hi (again). I'm having trouble understanding this error I'm getting:

___________________________________________
############################################################################################
FATAL ERROR in
action number 4
of Step Event0
for object obj_camera:

Push :: Execution Error - Variable Index [2,0] out of range [2,-1] - -7.aa(100029,64000)
at gml_Script_scr_hitscan (line 82) - ds_grid_add(grid, 0, p, aa[p,0]);
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_scr_hitscan (line 82)
called from - gml_Object_obj_camera_StepNormalEvent_4 (line 4) - test = scr_hitscan(x,y,zto,facing,pitch,2048,obsticle,obsticle_shoot,parent_char,parent_ramp_LR_32,true,false);

So I read the manual and got this info:
"The variable being accessed is out with the established range for the runner."

And... I don't know what that's supposed to be telling me.

Does it mean that the place in the ds_grid I'm trying to place the variable value into is out of range or the variable itself is out of range? I'm guessing it's the former since there shouldn't be a -1, but I am not very good at reading error messages. Usually I can peek at the context and immediately know what I did wrong.

For some extra background info: it's for a 3D hitscan script I wrote. It works by detecting all objects of certain types on a collision line, getting the range to each, sorting them by range, and then checking with a "collision_point_z" script whether or not they are being "hit" based on their sprite for 2D and whether the current zpoint is both above the object's bottom z and below the top z. If there is not hit it goes to the next closest object until there is either a hit or the script gets to the end and returns 0. The script works and correctly returns the x,y,z coordinates of the impact, the object impacted, and the 2D range to the impact. I only get this error when I DON'T hit something and even then it's only occasionally. The hitscan script is run each time I mouseclick and it seems to happen when I click wildly while missing any object.

Here's the hitscan script. I apologize for the messy code, I need to clean it up a bit but I don't want to do so until I can get rid of this error since it does work correctly when I hit something and never gives me an error then. I know there are some extra steps taken with the arrays and conversion to the ds_grid; I'll be addressing that. I think I just need a second set of eyes catching something stupid I probably did.

(and yes, I know I spell obstacle incorrectly, it's a nostalgic thing from when I first learned)
Code:
/// scr_hitscan(x,y,z,dir,zdir,range,object1,object2,object3,object4,prec,notme)
//
//  Returns an array: [xhit,yhit,zhit,distance(2d),object]

var xx,yy,zz,dir,zdir,range,object1,object2,object3,object4,prec,notme,xd,yd,xs,ys,distance,xp,yp;
xx = argument0;
yy = argument1;
zz = argument2;
dir = argument3;
zdir = argument4;
range = argument5;
object1 = argument6; //obsticles
object2 = argument7; //ramps
object3 = argument8; //characters
object4 = argument9; //glass
prec = argument10;
notme = argument11;

//xs/ys = farthest point on line per "Range".
xs = lengthdir_x(range,dir);
ys = lengthdir_y(range,dir);
xd = xx + xs;
yd = yy + ys;

xp = xx;
yp = yy;

//create arrays containing all objects on the collision line per each object type searched for
var cnt1, cnt2, cnt3, cnt4;
cnt1 = scr_collision_line_array(xx,yy,xd,yd,object1,true,false);
cnt2 = scr_collision_line_array(xx,yy,xd,yd,object2,true,false);
cnt3 = scr_collision_line_array(xx,yy,xd,yd,object3,true,false);
cnt4 = scr_collision_line_array(xx,yy,xd,yd,object4,true,false);

//Get length of each object's array for loops below
var aa,al1,al2,al3,al4,alt,p;

alt = array_length_1d(cnt1) + array_length_1d(cnt2) + array_length_1d(cnt3) + array_length_1d(cnt4);

if alt = 0 then {return false; exit;}

al1 = array_length_1d(cnt1);
al2 = array_length_1d(cnt2);
al3 = array_length_1d(cnt3);
al4 = array_length_1d(cnt4);

//use loops based on size of each object's returned object array to create 2D array containing 2D range to that object
for (p = 0; p < al1; p += 1)
    {
    aa[p,0] = cnt1[p];
    aa[p,1] = scr_range_finder(xx,yy,dir,range,cnt1[p],prec,notme);
    }
for (p = 0; p < al2; p += 1)
    {
    aa[p + al1,0] = cnt2[p];
    aa[p + al1,1] = scr_range_finder(xx,yy,dir,range,cnt2[p],prec,notme);
    }
for (p = 0; p < al3; p += 1)
    {
    aa[p + al1 + al2,0] = cnt3[p];
    aa[p + al1 + al2,1] = scr_range_finder(xx,yy,dir,range,cnt3[p],prec,notme);
    }
for (p = 0; p < al3; p += 1)
    {
    aa[p + al1 + al2 + al3,0] = cnt4[p];
    aa[p + al1 + al2 + al3,1] = scr_range_finder(xx,yy,dir,range,cnt4[p],prec,notme);
    }

//Create a DS grid and convert array into it so it can be sorted
grid = ds_grid_create(2,array_height_2d(aa));
for (p = 0; p < alt; p += 1)
    {
    ds_grid_add(grid, 0, p, aa[p,0]);
    ds_grid_add(grid, 1, p, aa[p,1]);
    }

//sort the grid by range
ds_grid_sort(grid, 1, true);

//Do the thing
for (p = 0; p < alt; p += 1)
    {
    var xr, yr, zr, zh;
    var oby = ds_grid_get(grid, 0, p);
    var r = ds_grid_get(grid, 1, p);
    xr = xx + lengthdir_x(r+1,dir);
    yr = yy + lengthdir_y(r+1,dir);
    zr = point_distance(xx,yy,xr,yr);
    zh = zr * tan(degtorad(zdir)) + zz;
 
    //move to next hitscan pixel if not hitting
    while (collision_point(xr,yr,oby,prec,notme))
        {
        //if there is a zpoint collision then store data [xhit,yhit,zhit,object,distance(2d)] in array and return it
        if scr_collision_point_z(xr,yr,obsticle,prec,notme,floor(zh),ceil(zh+1)) = oby then
            {
            var o = instance_create(xr,yr,obj_marker_test);
            with (o) {z = zh;}
            var ret;
            ret[0] = xr + lengthdir_x(5,dir+180);
            ret[1] = yr + lengthdir_y(5,dir+180);
            ret[2] = zh;
            ret[3] = ds_grid_get(grid, 0, p);
            ret[4] = ds_grid_get(grid, 1, p);
            ds_grid_destroy(grid);
            return ret;
            exit;
            }
        else
            {
            xr = xr + lengthdir_x(1,dir);
            yr = yr + lengthdir_y(1,dir);
            //var o = instance_create(xr,yr,obj_marker_test);
            //with (o) {z = zh;}
            zr = point_distance(xx,yy,xr,yr);
            zh = zr * tan(degtorad(zdir)) + zz;
            }
        }
    }
//return no hit
ds_grid_destroy(grid);
return false;
 
Last edited by a moderator:

TheouAegis

Member
The error is saying aa[2,0] was never initialized.

When you initialize a 2D array, you must do so for all primary indexes. Initializing a subindex will init all subindexes below it, but only for the current main index.

for(var i=0; i<2; i++) aa[i,4]=0;
 
O

Obrez

Guest
Bingo!

Yep, for the array that was supposed to be checking for the 4th type of object, I was using the count of object type 3 (al3) instead of count for that object (al4) so when I hit objects of type 4 in 2D while flailing like a madman, it registered them as needing to be added but then failed to pass their info along correctly since the loop was closing early. It never happened when I hit objects because type 4 is currently a flat plane placebo that I only have in a few specific places. That's embarrassing.

I really appreciate the help.
 
Top