0
\$\begingroup\$

As mentionned in the title, my GameMaker project works fine when targeting Windows.

However, when I build it for HTML5, I got those errors in the Chrome developer console:

Destructive Dark.js?VYNZB=1666826811:7 Uncaught TypeError: Cannot read property '_42' of undefined
    at _Qw1._M [as _L] (Destructive Dark.js?VYNZB=1666826811:7)
    at _Qw1._a4 (Destructive Dark.js?VYNZB=1666826811:1490)
    at _a72._a4 (Destructive Dark.js?VYNZB=1666826811:1380)
    at _lK1 (Destructive Dark.js?VYNZB=1666826811:1155)
    at _9v2 (Destructive Dark.js?VYNZB=1666826811:1742)
    at _Mu2 (Destructive Dark.js?VYNZB=1666826811:1748)
    at _Ju2 (Destructive Dark.js?VYNZB=1666826811:1733)

I suppose this error is not really useful since it seems to come from the obfuscated Javascript... However, I noticed that this error appears on the "Left mouse button released" event on one of my object. The code associated with this event is the following:

/// Select the square or switch its place with the current selected square

game_manager = instance_find(obj_game_manager, 1);

if (game_manager.lock_timer == 0) {   
    if (game_manager.selected_square == noone) {
        game_manager.selected_square = self;
        inst = instance_create(x, y, obj_selection);
        inst.depth = -100;
        inst.image_alpha = 0.6;
    }
    else if (game_manager.selected_square == self) {
        game_manager.selected_square = noone;

        with (obj_selection) {
            instance_destroy();
        }
    }
    else {
        // Lock interactions
        game_manager.lock_timer = 2;

        // Switch the array cells
        var x_temp = game_manager.selected_square.x_grid;
        var y_temp = game_manager.selected_square.y_grid;
        var color_temp = game_manager.selected_square.color;

        game_manager.grid_array[x_temp, y_temp] = color;
        game_manager.grid_array[x_grid, y_grid] = color_temp;

        game_manager.selected_square = noone;

        with (obj_selection) {
            instance_destroy();
        }

        with (game_manager) {
            event_perform(ev_alarm, 0);
        }
    }
}

Not much info sorry, but I have no ideas where this error came from.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

About code...

Use id instead self:

game_manager.selected_square = id;

Use var for temporary variables:

var inst = instance_create(x, y, obj_selection);
inst.depth = -100;
inst.image_alpha = 0.6;

(of course, if you knowingly use it as object variable, then it's ok)

Or even something like this:

with instance_create(x, y, obj_selection) {
    depth = -100;
    image_alpha = 0.6;
}

Don't use multiple dots without braces:

game_manager.selected_square.x_grid;   // no
(game_manager.selected_square).x_grid; // yes

Other way which can be useful there:

var square = game_manager.selected_square;
...
var x_temp = square.xgrid;
var y_temp = square.ygrid;
var color_temp = square.color;

It's shorter and, as a result, more comfortable for reading. (But keep in mind, that is usable for reading, but not for change original value, i.e. game_manager.selected_square = noone;, but not square = noone;).

When statement has only one command, you can omit curve braces:

    with (obj_selection) {
        instance_destroy();
    }

    with (obj_selection)
        instance_destroy();

or even

    with obj_selection
        instance_destroy();

(GMS highlights names of objects, so it's ok for reading). Same for if.

Now about your problem. Possible that problem is here

game_manager.selected_square.x_grid;

but if no, then not very hard to find where is it.

Write to debug console messages in key places of the code and you will know, where the error happens.

For example, firstly you can do it inside each if:

/// Select the square or switch its place with the current selected square

show_debug_message("script 1");

game_manager = instance_find(obj_game_manager, 1);

if (game_manager.lock_timer == 0) {   
    show_debug_message("1");
    if (game_manager.selected_square == noone) {
        show_debug_message("2");
        game_manager.selected_square = self;
        inst = instance_create(x, y, obj_selection);
        inst.depth = -100;
        inst.image_alpha = 0.6;
    }
    else if (game_manager.selected_square == self) {
        show_debug_message("3");
        game_manager.selected_square = noone;

        with (obj_selection) {
            instance_destroy();
        }
    }
    else {
        show_debug_message("4");
        // Lock interactions
        game_manager.lock_timer = 2;

        // Switch the array cells
        var x_temp = game_manager.selected_square.x_grid;
        var y_temp = game_manager.selected_square.y_grid;
        var color_temp = game_manager.selected_square.color;

        game_manager.grid_array[x_temp, y_temp] = color;
        game_manager.grid_array[x_grid, y_grid] = color_temp;

        game_manager.selected_square = noone;

        with (obj_selection) {
            instance_destroy();
        }

        with (game_manager) {
            event_perform(ev_alarm, 0);
        }
    }
}

show_debug_message("script 1 finished");

For example, you found that 4 is last message was printed. Then do same for each line of that block:

else {
    show_debug_message("4");
    // Lock interactions
    game_manager.lock_timer = 2;

    show_debug_message("4-1");

    // Switch the array cells
    var x_temp = game_manager.selected_square.x_grid;
    show_debug_message("4-2");
    var y_temp = game_manager.selected_square.y_grid;
    show_debug_message("4-3");
    var color_temp = game_manager.selected_square.color;

    show_debug_message("4-4");
    game_manager.grid_array[x_temp, y_temp] = color;
    show_debug_message("4-5");
    game_manager.grid_array[x_grid, y_grid] = color_temp;
    show_debug_message("4-6");

    game_manager.selected_square = noone;
    show_debug_message("4-7");

    with (obj_selection) {
        instance_destroy();
    }

    show_debug_message("4-8");

    with (game_manager) {
        event_perform(ev_alarm, 0);
    }
}

And see what message will be last. Next line will be your goal.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks a lot. Turns out the issue was game_manager = instance_find(obj_game_manager, 1); which was supposed to be game_manager = instance_find(obj_game_manager, 0);. I don't know why the first one worked on Windows though. \$\endgroup\$
    – user87553
    Mar 23, 2017 at 12:34
  • 1
    \$\begingroup\$ On Windows instance_find for wrong index returns id of last instance, but on HTML5 it returns noone. I guess the runner has no check of maximum correct index because performance optimizations, so developer must check it manually. \$\endgroup\$
    – Dmi7ry
    Mar 24, 2017 at 4:15

You must log in to answer this question.