irandom_range not working

G

Giammarco Agazzotti

Guest
Hi everyone.

I am working on a randomly generated platformer with Game Maker 2 and as long as we talk about map generation it is doing pretty well.

The problem comes when I have to spawn enemies around the map.

My logic is:
  • Create a list containing all the coordinates of empty spaces.
  • Then, for each enemy which will be spawned, extract a random coordinate (array containing x and y)
  • And create an instance there.

The bug when choosing a random value from the list containing all coordinates, because the value is still the same (I manually checked the list and I can say that it contains all different values). Here is the code:

Code:
// Add tiles
for (var yy = 0; yy < height; yy++) {
    for (var xx = 0; xx < width; xx++) {
        if (grid[# xx, yy] == FLOOR) {
           // Draw floor
           instance_create_depth(xx * CELL_WIDTH, yy * CELL_HEIGHT, 0, obj_Background);
      
          if (not created) {
              instance_create_layer(xx * CELL_WIDTH, yy * CELL_HEIGHT, layer_get_id("Instances"), obj_MagicStick);
              created = true;
          }
      
          // Add current empty space to a list, so we can randomly place wizards later
          couple[1] = xx;
          couple[2] = yy;
      
          empty_spaces = ds_list_add(empty_spaces, couple);
        } else if (grid[# xx, yy] == WALL)  {
           // Draw wall
           instance_create_depth(xx * CELL_WIDTH, yy * CELL_HEIGHT, 0, obj_Environment);
        }
    }
}

// Add wizards
for (var i = 0; i < wizards; i++) {
    // Extract random space
    pos = irandom_range(1, ds_list_size(empty_spaces));
 
    //show_debug_message("pos " + string(pos));
 
    //THE FOLLOWING LINE IS THE PROBLEM I THINK
    space = ds_list_find_value(empty_spaces, pos);
 
    show_debug_message("[" + string(space[1]) + ", " + string(space[2]) + "]");
 
    // Spawn wizard
    instance_create_layer(space[1] * CELL_WIDTH, space[2] * CELL_HEIGHT, layer_get_id("Instances"), obj_Wizard);
}
Some help would be appreciated.

Thank you all guys!

EDIT (Solved):
After googling I found the bug, and it is related to the list of arrays.

It appears that for some reasons it loses the reference and so copies it. The result is a list with every item equal to the last one added.

Here is the link to the thread: https://www.reddit.com/r/gamemaker/comments/3qr1qz/making_a_list_of_arrays_doesnt_store_the_arrays/

Thank as always for your support guys, hope this can help someone else too!
 
Last edited by a moderator:

Yal

🐧 *penguin noises*
GMC Elder
Weird, it looks like it SHOULD be working from looking through the code... there's a bunch of stuff you could optimize, but they shouldn't cause problems.
  • You're reassigning empty_spaces every time you add a value, but since it's list 0 and ds_list_add() doesn't return anything (aka default value 0 is used) nothing bad happens with this... YET. Change this or you WILL get problems later. ds_list_add() operates directly on the list, it doesn't return a modified list.
  • Arrays start at 0 in Game Maker, so you're wasting one slot in every small array.
  • You can use space = empty_spaces[|pos]; instead of using ds_list_find_value(), it is a bit easier to write IMO. Note that you need the | symbol, that's the accessor for ds_lists.
One thing you could try would be to always read the first entry of the list, then use ds_list_shuffle() to scramble it... it's a pretty fast operation, and if some bug causes the same number to be returned each time, this should make whatever data is stored at that point be different each time at least.
 
G

Giammarco Agazzotti

Guest
Weird, it looks like it SHOULD be working from looking through the code... there's a bunch of stuff you could optimize, but they shouldn't cause problems.
  • You're reassigning empty_spaces every time you add a value, but since it's list 0 and ds_list_add() doesn't return anything (aka default value 0 is used) nothing bad happens with this... YET. Change this or you WILL get problems later. ds_list_add() operates directly on the list, it doesn't return a modified list.
  • Arrays start at 0 in Game Maker, so you're wasting one slot in every small array.
  • You can use space = empty_spaces[|pos]; instead of using ds_list_find_value(), it is a bit easier to write IMO. Note that you need the | symbol, that's the accessor for ds_lists.
One thing you could try would be to always read the first entry of the list, then use ds_list_shuffle() to scramble it... it's a pretty fast operation, and if some bug causes the same number to be returned each time, this should make whatever data is stored at that point be different each time at least.
Yeah, everything you said is true (and I know it's wrong) but it's the result of desperate changes to the code (which turned sometimes into something strange like starting arrays from 1 instead of 0) trying to see things get better :D

Anyway thank you very much, I will try right now the list shuffle with fixed position.
 

Yal

🐧 *penguin noises*
GMC Elder
If all else fails, I guess you could store strings instead of arrays for the value pairs... strings have been a first-order citizen for MUCH longer than arrays, so they're a lot less buggy. Just convert the stuff to strings with some separation character, then split the string and use real() on the parts when reading from it.
 
G

Giammarco Agazzotti

Guest
If all else fails, I guess you could store strings instead of arrays for the value pairs... strings have been a first-order citizen for MUCH longer than arrays, so they're a lot less buggy. Just convert the stuff to strings with some separation character, then split the string and use real() on the parts when reading from it.
Yep, if I can't find a solution for this I will absolutely try working with strings! Thank you very much man
 
Top