How can I improved this loop?

Hiya guys,

Just looking for a bit of general advice. I have a large open world map in my game that draws from a set of ds_grids. I have this loop which deletes any tiles outside of the players view (view_range) and then draws any inside of it.

Can you think of anyway to improve this? It seems rather performance heavy and I am curious if there is anyway to make it faster?

Here is what I am working with -

Code:
ds_grid_set_disk(delete_track,x_view[0],y_view[0],draw_range+1,1);
ds_grid_set_disk(delete_track,x_view[0],y_view[0],draw_range,0);

if (ds_grid_value_disk_exists(tile_track,x_view[0],y_view[0],draw_range,0)) {
    while (ds_grid_value_disk_exists(tile_track,x_view[0],y_view[0],draw_range,0)) {

        xx = ds_grid_value_disk_x(tile_track,x_view[0],y_view[0],draw_range,0);
        yy = ds_grid_value_disk_y(tile_track,x_view[0],y_view[0],draw_range,0);
        
     //   show_debug_message(string(xx) + "_" + string(yy));
        
        if (xx >= 0 and xx < w and yy >= 0 and yy < h) {   
        
                ds_grid_set(tile_track,xx,yy,1);
                grid = ds_grid_get(global.terrain_grid,xx,yy);
                    
                    if (instance_exists(obj_minimap)) {
                        with (obj_minimap) {
                            ds_list_add(update_list,string(xx)+"|"+string(yy)+"|"+string(grid));
                        }
                    }
                
                    if (draw_tiles >= 1) {
                        if (grid >= 0) {
                            var temp_id = auto_tile(grid,xx,yy,xx,yy,global.terrain_grid,true);
                            ds_grid_set(tile_array,xx,yy,temp_id);
                        }
                    }
                    
                    for (i=0;i<=1;i+=1) {
                        switch (i) {
                          case 0 : { active_grid = global.resource_layer_0; break; }
                          case 1 : { active_grid = global.resource_layer_1; break; }
                        }
                        
                        if (xx > 0 and xx < ds_grid_width(active_grid) and yy > 0 and yy < ds_grid_height(active_grid)) {         
                            var temp_data = ds_grid_get(active_grid,xx,yy);
                            if (is_array(temp_data)) {
                                if (!instance_exists(temp_data[2])) {
                                    ds_grid_set(active_grid,xx,yy,scr_add_resource(xx*tile_size,yy*tile_size,temp_data,active_grid));
                                }
                            } else if (temp_data != noone and temp_data >= 1) {
                                instance_create(xx*tile_size,yy*tile_size,temp_data);
                            }
                        }
                  }
            }                       
      }
}

tile_tick ++;

if (tile_tick >= room_speed/8) {
    while (ds_grid_value_disk_exists(delete_track,x_view[0],y_view[0],draw_range+1,1)) {
        xx = ds_grid_value_disk_x(delete_track,x_view[0],y_view[0],draw_range+1,1);
        yy = ds_grid_value_disk_y(delete_track,x_view[0],y_view[0],draw_range+1,1);
        
        if (xx >= 0 and xx < w and yy >= 0 and yy < h) and (ds_grid_get(tile_array,xx,yy) != 0) {   
            var tmp_tile = ds_grid_get(tile_array,xx,yy);
            layer_tile_destroy(tmp_tile[0]);
            layer_tile_destroy(tmp_tile[1]);
            ds_grid_set(tile_array,xx,yy,0);
        }
        
        ds_grid_set(delete_track,xx,yy,0);
        ds_grid_set(tile_track,xx,yy,0);
    }
    
    tile_tick = 0;
}

Any suggestions are welcome!

Many thanks!
 

Simon Gust

Member
Does anyone have any suggestions?

Thanks!
You can improve this loop by further explaining what stuff does.
I can see 5 different ds_grids, what are they for? Are they necessary?
I can see script functions, but what do they do?
What are you trying to achieve using these ds_grid_set_disk functions? Is it for an effect or performance improvement?
 

Yal

šŸ§ *penguin noises*
GMC Elder
instance_exists() and instance_create() are both pretty expensive calls [since they may need to traverse the entire list of existing objects in the worst case], and the "if the minimap exists" value shouldn't change between loop iterations... a good first step would be to move that out of the loop. The context switch of a with(){} loop also is a bit expensive, and it's kinda redundant to do both an if instance_exists and a with (since a with
won't do anything if there's no instance it applies to).

The second, while loop also looks a bit weird... what is it doing? It looks like it could potentially waste a lot of time just incrementing its counter.
 
instance_exists() and instance_create() are both pretty expensive calls [since they may need to traverse the entire list of existing objects in the worst case], and the "if the minimap exists" value shouldn't change between loop iterations... a good first step would be to move that out of the loop. The context switch of a with(){} loop also is a bit expensive, and it's kinda redundant to do both an if instance_exists and a with (since a with
won't do anything if there's no instance it applies to).

The second, while loop also looks a bit weird... what is it doing? It looks like it could potentially waste a lot of time just incrementing its counter.
Hiya Yal,

Thanks for the tip on the minimap, that slipped by me. I have taken the check out of the loop. This functional essentially renders out all the tiles and resources from a set of grids in a large open world test I am doing, so it is quite intensive but quite literally the core of the game right now so I am looking to improve. Any other suggestions guys please let me know.

Many thanks!
 
Top