• 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 Object Index Error

C

Carbiner

Guest
I am getting an error that references object index, and I don't have any code that does that anymore. Its happening when my controller object tries to assign a destination to its units, in this code:

Code:
for(i=0;i<units_per_target;i+=1)
    {
    inst = ds_priority_delete_min(redone_list);
    inst.inv_x = ats.x;
    inst.inv_y = ats.y;
The ds_priority has the id's of the units it can use prioritized by their distance to the target, which in this script is represented by the variable ats. ats is determined by another script that calls this one.

Code:
for(i=0;i<number_targets;i+=1)
            {
            units_adjusted = units_per_target; // Reset the average
            units_adjusted += adjustment;
            ats2 = ds_priority_delete_max(ats_priority);
            scr_ai_unit_control(ats2,units_adjusted);
            iv -= 1;
The target (ats) is set in the second script like this:

Code:
for(i=0;i<instance_number(obj_base);i+=1)
        {
        ats = instance_find(obj_base,i);
        p1 = scr_ai_base_strength(ats);
        p2 = scr_ai_base_distance(ats);
        p3 = scr_ai_base_color(ats,p1);
        p4 = scr_ai_base_stability(ats);
        pt = p1+p2+p3+p4;
        if(pt > 0)
            {
            ds_priority_add(ats_priority,ats,pt);
            }
These are the screenshots of the error message and debugger:

Screenshot (14) - Copy.png Screenshot (14).png

The thing is, the object index its referencing, (object mapper_base) is destroyed at the beginning of the level, replacing itself with obj_base. The game seems to progress normally until the very end of the level where this error occasionally pops up. This makes it frustrating to debug and hard to pinpoint. I have checked all the scripts that it calls and never once do they mention object_index. They used to, as I used that as a way of fixing my improperly made for loops, but I have fixed those loops and removed all of those checks.

I don't know what to do, so help would be appreciated.
 
A

Azure Spectre

Guest
So I was able to recreate that error message with
Code:
var testa=1000;
var testx=testa.x;
I don't think the problem is with the object index at all, I think you have a 0 getting entered into your queue somewhere, and GMS assumes it's an object index.

Could you post "scr_ai_target_control"?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Indeed, while your screenshot of debugger happens to have that out of view in "local variables" area, the issue is most likely that "inst" is equal to 0, which results in instance lookup for object 0, which fails due there not being any instances of that object, as you have pointed out. May want to ensure that there are any entries before you get the next item from priority queue.
 
C

Carbiner

Guest
Here is target control in all of its 259 lines of glory:
Code:
///scr_ai_target_control();
if(a_1 = true)
    {
    var ats_priority = ds_priority_create();
    var ats; // The base it sends units against in turn
    var usable_units; // Total usable units
    var percent_units; // Percent of those its willing to use
    var total_units; // Total amount of units being sent
    var number_targets; // How many targets
    var units_per_target; // How many units per target
    var cont = true;
    if(ibase > 0)
        {
        switch(type2)
            {
            case 0:
            switch(ia)
                {
                case -1:
                a = 1;
                ia += 1;
                alarm[1] += 40;
                case 0:
                a = 1;
                ia += 1;
                alarm[1] += 40;
                break;
                case 1:
                a = 0.65;
                ia += 1;
                alarm[1] += 10;
                break;
                case 2:
                a = 0.6;
                ia += 1;
                alarm[1] += 10;
                break;
                case 3:
                a = 0.5;
                ia = 0;
                alarm[1] += 35;
                break;
                }
            switch(type3)
                {
                case 0:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.45*sqrt(ibase)+(0.010*sqr(ibase)-0.4)));
                units_per_target = total_units div number_targets;
                alarm[1] += 120;
                break;
                case 1:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.65*sqrt(ibase)+(0.015*sqr(ibase)-0.5)));
                units_per_target = total_units div number_targets;
                alarm[1] += 120;
                break;
                case 2:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.85*sqrt(ibase)+(0.02*sqr(ibase)-0.7)));
                units_per_target = total_units div number_targets;
                alarm[1] += 120;
                break;
                }
            break;
            case 1:
            switch(ia)
                {
                case -1:
                a = 1;
                ia += 1;
                alarm[1] += 40;
                case 0:
                a = 1;
                ia += 1;
                alarm[1] += 30;
                break;
                case 1:
                a = 0.8;
                ia += 1;
                alarm[1] += 20;
                break;
                case 2:
                a = 0.75;
                ia += 1;
                alarm[1] += 20;
                break;
                case 3:
                a = 0.7;
                ia = 0;
                alarm[1] += 30;
                break;
                }
            switch(type3)
                {
                case 0:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.45*sqrt(ibase)+(0.010*sqr(ibase)-0.4)));
                units_per_target = total_units div number_targets;
                alarm[1] += 140;
                break;
                case 1:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.65*sqrt(ibase)+(0.015*sqr(ibase)-0.5)));
                units_per_target = total_units div number_targets;
                alarm[1] += 140;
                break;
                case 2:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.85*sqrt(ibase)+(0.02*sqr(ibase)-0.7)));
                units_per_target = total_units div number_targets;
                alarm[1] += 140;
                break;
                }
            break;
            case 2:
            switch(ia)
                {
                case -1:
                a = 1;
                ia += 1;
                alarm[1] += 40;
                case 0:
                a = 1;
                ia += 1;
                alarm[1] += 35;
                break;
                case 1:
                a = 0.85;
                ia += 1;
                alarm[1] += 25;
                break;
                case 2:
                a = 0.85;
                ia += 1;
                alarm[1] += 25;
                break;
                case 3:
                a = 0.75;
                ia = 0;
                alarm[1] += 35;
                break;
                }
            switch(type3)
                {
                case 0:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets =  floor (1+(0.45*sqrt(ibase)+(0.010*sqr(ibase)-0.4)));
                units_per_target = total_units div number_targets;
                alarm[1] += 180;
                break;
                case 1:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.65*sqrt(ibase)+(0.015*sqr(ibase)-0.5)));
                units_per_target = total_units div number_targets;
                alarm[1] += 180;
                break;
                case 2:
                usable_units = ds_priority_size(usable_list);
                percent_units = a;
                total_units = floor (usable_units*percent_units);
                number_targets = floor (1+(0.85*sqrt(ibase)+(0.02*sqr(ibase)-0.7)));
                units_per_target = total_units div number_targets;
                alarm[1] += 180;
                break;
                }
            break;
            }
        }
    if(ibase = 0)
        {
        usable_units = ds_priority_size(usable_list);
        percent_units = 1;
        total_units = usable_units;
        number_targets = 1;
        units_per_target = total_units div number_targets;
        alarm[1] += 180;
        }
    var i; // The loop to end all loops
    var p1,p2,p3,p4,pt; //Priorities for each segment
    var ats2;
    for(i=0;i<instance_number(obj_base);i+=1)
        {
        ats = instance_find(obj_base,i);
        p1 = scr_ai_base_strength(ats);
        p2 = scr_ai_base_distance(ats);
        p3 = scr_ai_base_color(ats,p1);
        p4 = scr_ai_base_stability(ats);
        pt = p1+p2+p3+p4;
        if(pt > 0)
            {
            ds_priority_add(ats_priority,ats,pt);
            }
        }
    if(ds_priority_size(ats_priority) < number_targets)
        {
        var zz = number_targets - ds_priority_size(ats_priority);
        for(i=0;i<zz;i+=1)
            {
            number_targets -= 1;
            if(number_targets = 0)
                {
                number_targets = 1;
                }
            units_per_target = total_units div number_targets;
            if(ds_priority_size(ats_priority) = number_targets)
                {
                break;
                }
            }
        }
    if(ds_priority_size(ats_priority) = 0)
        {
        cont = false;
        }
    if(cont = true)
        {
        var units_adjusted = units_per_target;
        var iv = floor (number_targets/2);
        var adjustment = number_targets;
        for(i=0;i<number_targets;i+=1)
            {
            units_adjusted = units_per_target; // Reset the average
            units_adjusted += adjustment;
            ats2 = ds_priority_delete_max(ats_priority);
            scr_ai_unit_control(ats2,units_adjusted);
            iv -= 1;
            if(adjustment = 0)
                {
                adjustment = 1;
                }
            if(iv >= 0)
                {
                adjustment = floor(adjustment/(2*number_targets));
                }
            if(iv <= 0) // They are both equall to beacuse it needs to subtract units
                {
                adjustment = floor(adjustment*(-2*number_targets))
                }
            }
        }
    ds_priority_destroy(ats_priority);
    }
Ok as for the the debugger var inst: You are correct. inst does = 0
Screenshot (16).png
Ok, so that's wrong, that's what is causing the error, but if we take a look at the full unit control script:

Code:
///scr_ai_unit_control(target,total # of units per base);
var copied_list = ds_priority_create();
var redone_list = ds_priority_create();
ds_priority_copy(copied_list,usable_list);
var i;
var inst;
var distance;
var ats = argument0;
var units_per_target = argument1;
var timer = 0;
var timer2 = 0;
var ii = ds_priority_size(copied_list);
for(i=0;i<ii;i+=1)
    {
    inst = ds_priority_delete_max(copied_list);
    distance = point_distance(inst.x,inst.y,ats.x,ats.y);
    ds_priority_add(redone_list,inst,distance);
    }
for(i=0;i<units_per_target;i+=1)
    {
    inst = ds_priority_delete_min(redone_list);
    inst.inv_x = ats.x;
    inst.inv_y = ats.y;
    inst.ai_us = false;
    timer2 += 0.45;
    timer = ceil (point_distance(inst.x,inst.y,ats.x,ats.y))
    inst.alarm[2] = timer;
    if(ds_priority_size(redone_list) = 0)
        {
        break;
        }
    }
ii = ds_priority_size(redone_list);
for(i=0;i<ii;i+=1)
    {
    inst = ds_priority_delete_max(redone_list);
    ds_priority_add(copied_list,inst,id);
    }
ds_priority_copy(usable_list,copied_list);
ds_priority_destroy(copied_list);
ds_priority_destroy(redone_list);
alarm[1] += 10+timer2;
a_2 = true;
a_1 = false;
The script had to previously find the distance between the target and instance to order them in to the ds_priority redone_list. Why did finding the x and y values of 0 work there to find the distance, if "0" is not an instance in the room, because the script only choked when it had to assign values to those variables.

Anyways, Thank you for the accurate and quick response, and my number 1 question now is how do I prevent this from happening? I can deal with it but putting in a conditional like "if(inst = 0) {break;}" but that's not ideal.

EDIT: I do check the size of ds_priority redone_list at the unit control script's second loop, where the error message comes up.
 
Last edited by a moderator:
Top