SOLVED ds grid seemingly being read as another

PixelMochii

Member
Hello, I'm creating a sandbox simulation game where I am effectively trying to use cellular automata for things such as water spreading. I would appreciate some help on this bug I was getting:

The issue is that for some reason the ds grid "gridNext" is being recognised as "grid" by my code in the alarm event below, when there is seemingly no reason this should be happening. This is causing the if statement to continuously check the new water tile it is creating from the last event, even though the new water tile is being spawned in ds grid "gridNext" and it is only checking the ds grid called "grid".

there are 2 ds grids. "grid" is the current grid state that is being displayed, and "gridNext" which is where the next state is decided, and then once it has all been decided grid is set to gridNext and the cycle continues.

I am checking for a water tile every alarm interval, and if there is one found using the for loop, I spread the water using the function spread();
Alarm 0:

gridNext = grid;

///@desc Initiating next state
for (var i = 0; i < height; i++)
{
for (var j = 0; j < width; j++)
{
var _square = ds_grid_get(grid, j, i);
if (_square[0][0] == sprWater) script_execute(spread, j, i, sprWater, 0);
else ds_grid_set(gridNext, j, i, _square);
}
}
grid = gridNext;
alarm[0] = interval;


Here is the spread function I've created

function spread(_xx, _yy, _type, _layer)
{
var _box;

_box = ds_grid_get(gridNext, _xx, _yy-1)
_box[_layer][0] = _type;
ds_grid_set(gridNext, _xx, _yy-1, _box);

_box = ds_grid_get(gridNext, _xx+1, _yy)
_box[_layer][0] = _type;
ds_grid_set(gridNext, _xx+1, _yy, _box);

_box = ds_grid_get(gridNext, _xx, _yy+1)
_box[_layer][0] = _type;
ds_grid_set(gridNext, _xx, _yy+1, _box);

_box = ds_grid_get(gridNext, _xx-1, _yy)
_box[_layer][0] = _type;
ds_grid_set(gridNext, _xx-1, _yy, _box);

}


This is the result from one water tile, where it is infinitely checking the water tiles it is creating to the right and downwards, even though it should only be checking in the ds grid which I haven't modified by the water spreading
1638746744299.png
If anyone knows why this is happening then please message me! I've been stuck for a few days on this.
 

chamaeleon

Member
GML:
gridNext = grid;
gridNext and grid are now referencing the same grid. Are you working under the assumption there is some copy-on-write going on with data structures? Modifying the data in the grid does not care what variable holds the reference. Data structure references (as stored in variables like gridNext and grid) are just plain numbers without any special meaning.
 

PixelMochii

Member
You're absolutely right haha, I assumed that if I just set one to the other it would create two separate copies of the same data structure rather than just referencing it. Thank you so much you've just saved me a few weeks of struggling!

How would I make them separate data structures in that case? Am I able to just grab the data stored in one then move it over to the other in any way?
 

chamaeleon

Member
You can use ds_grid_copy(), assuming you have created two grids and stored them in grid and gridNext, respectively.
GML:
grid = ds_grid_create(...);
gridNext = ds_grid_create(...);
...
ds_grid_copy(gridNext, grid);
...
<update gridNext code>
...
ds_grid_copy(grid, gridNext);
Or to save a little bit of computation, one can perhaps just swap the two grid references (a single assignment won't do, since that would lose access to one of the grids).
GML:
ds_grid_copy(gridNext, grid);
<update gridNext>
var tmp = grid;
grid = gridNext;
gridNext = tmp;
 
Last edited:

PixelMochii

Member
You can use ds_grid_copy(), assuming you have created two grids and stored them in grid and gridNext, respectively.
GML:
grid = ds_grid_create(...);
gridNext = ds_grid_create(...);
...
ds_grid_copy(gridNext, grid);
...
<update gridNext code>
...
ds_grid_copy(grid, gridNext);
Or to save a little bit of computation, one can perhaps just swap the two grid references (a single assignment won't do, since that would lose access to one of the grids).
GML:
ds_grid_copy(gridNext, grid);
<update gridNext>
var tmp = grid;
grid = gridNext;
gridNext = tmp;
Thank you so much aaaaaaaaa, I just swapped out my statements of equal with the ds_grid_copy function and it started working

1638791060223.png
Thanks for the help!
 
Top