Legacy GM Checking if space is empty to add mp_grid_cell

B

Bogan666

Guest
Hello. I have code which spawns a world with islands basically then an ocean between everything where the ocean is just the backgroud layer to save on resources being generated.
I'm also using mp_grids for my npcs to walk around in and want to fill all the "ocean" empty spaces into the mp grid so the npcs can't walk on nothing.

Any assistance on how I could go about this would be greatly appreciated.

Is this possibly not a thing that can be done?
 
You can manually set cells to be active, but it will take knowing what is an island and what is the ocean. Usually an mp grid will be filled by entering instances into it, which can't happen here as you're using a background layer for the ocean.

You could use mp_grid_set_rectangle and do the entire grid as active (now set as the ocean, and off limits), then loop through a stored list of island coordinates and set those cells as free.
 
B

Bogan666

Guest
You can manually set cells to be active, but it will take knowing what is an island and what is the ocean. Usually an mp grid will be filled by entering instances into it, which can't happen here as you're using a background layer for the ocean.

You could use mp_grid_set_rectangle and do the entire grid as active (now set as the ocean, and off limits), then loop through a stored list of island coordinates and set those cells as free.
okay yes, I'm liking that method to give the whole world an active grid.

Would because of the way I'm generating the world (its made up of many 32x32 blocks of land), what would be a good method to have each bit of land clear the cell it is at.
 
If the islands are instances with a sprite, then you can just add them in with mp_grid_add_instances. If you were using something like tiles, i.e not a "physical" graphical property within the world (at least as far as an mp grid recognizes), then you can use mp_grid_add_cell.

Basically you have a couple of different ways you can manually or automatically set cells, and which of those you use will depend on how your game is set up. Without knowing how you are making your game I can only point you in the direction of those options. As an example: if you were just drawing the islands as tiles - you could loop through the tiles, find their x / y position and convert that into a grid coordinate. Then you would manually add that into the grid using mp_grid_add_cell.

In my experience mp_grid_add_rectangle is better than mp_grid_add_instances for performance. The latter is simplest to do with it being automatically handled by GMS, whereas the former requires a small amount of your involvement - such as using the bounding box dimensions, or sprite_get_width / sprite_get_xoffset etc, to get where the rectangle begins and ends.

EDIT:
How they work:
mp_grid_add_instances: all processes are handled automatically, does not require defining a cell coordinate
mp_grid_add_rectangle: does not require defining a cell coordinate
mp_grid_add_cell: requires defining an actual cell coordinate, such as mp_grid_add_cell(grid, x div 32, y div 32) would take the x / y positions and return what they are divided by 32 (if 32 was the width / height of the grid cells)
 
Last edited:
B

Bogan666

Guest
If the islands are instances with a sprite, then you can just add them in with mp_grid_add_instances. If you were using something like tiles, i.e not a "physical" graphical property within the world (at least as far as an mp grid recognizes), then you can use mp_grid_add_cell.

Basically you have a couple of different ways you can manually or automatically set cells, and which of those you use will depend on how your game is set up. Without knowing how you are making your game I can only point you in the direction of those options. As an example: if you were just drawing the islands as tiles - you could loop through the tiles, find their x / y position and convert that into a grid coordinate. Then you would manually add that into the grid using mp_grid_add_cell.

In my experience mp_grid_add_rectangle is better than mp_grid_add_instances for performance. The latter is simplest to do with it being automatically handled by GMS, whereas the former requires a small amount of your involvement - such as using the bounding box dimensions, or sprite_get_width / sprite_get_xoffset etc, to get where the rectangle begins and ends.

EDIT:
How they work:
mp_grid_add_instances: all processes are handled automatically, does not require defining a cell coordinate
mp_grid_add_rectangle: does not require defining a cell coordinate
mp_grid_add_cell: requires defining an actual cell coordinate, such as mp_grid_add_cell(grid, x div 32, y div 32) would take the x / y positions and return what they are divided by 32 (if 32 was the width / height of the grid cells)
https://forum.yoyogames.com/index.php?attachments/capture-png.24948/

The above link is a picture of how my world will look after my generation is done. originally I had the grid spawn after the creation but I just changed it to before. Using your idea of of covering the size of the room with cells to indicate that it can't be used for the motion planning.

The issue is .. nothing.. I just looked at how you wrote one part of that, mp_grid_add_cell(grid, x div 32, y div 32) .
the x div 32, y div 32 part made it work.
Thank you very much!

EDIT : Maybe not working. all the grass cells cleared with "mp_grid_clear_cell(obj_gen.grid,x div 32,y div 32);" but the sand and stone haven't worked yet.
Edit 2: no, it appears that its working now.
 
Last edited by a moderator:

GMWolf

aka fel666
I really would recommend you use tilemaps for this.
Spawning instance for every land tile is quite expensive.
Tilemaps are practically free.

The great advantage of tilemaps in this situation is that they can map 1 to 1 with your mp grid.
Just loop over every tile. If there is no land tile, then make that tile on the mp grid.
 
B

Bogan666

Guest
I really would recommend you use tilemaps for this.
Spawning instance for every land tile is quite expensive.
Tilemaps are practically free.

The great advantage of tilemaps in this situation is that they can map 1 to 1 with your mp grid.
Just loop over every tile. If there is no land tile, then make that tile on the mp grid.
is that a GMS2 thing?
regardless if it is or not though, I don't know what they are/how they work. if it can create the world the same as how I have it now I could be interested.
 

GMWolf

aka fel666
is that a GMS2 thing?
regardless if it is or not though, I don't know what they are/how they work. if it can create the world the same as how I have it now I could be interested.
It is a GMS2 thing . And yes, it will let you create a world like the one you have now.
 
GMWolf is better equipped to walk you through this than me (but not apparently notice which version of GMS you use ;) ), so I will just post this and hopefully they will answer any further questions.

Whichever way you do it there is the issue of knowing what can be reached by NPC' and what can't. I suggested doing all of the grid as "full" to begin with, because it's simplest (to me, at least) to figure out what can be used than what can't.

If you use tiles, and have those that can be traversed as a separate tile layer (? or are stored in a list, or whatever), then you only need to loop through one particular piece of data to reset the cells as free.

You are using backgrounds for your water - GMWolf may suggest using tiles instead as they are cheaper (?)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
You could also create a DS grid and have all the land tiles set in that and simply loop through the grid to draw them. This would then be easy to convert into an MP grid too. I'd create macro constants for each land type, then add them into the grid, then draw the correct tile based on the constant used. If this sounds like something you'd like to try, then I'll post some code as an example.
 
B

Bogan666

Guest
You could also create a DS grid and have all the land tiles set in that and simply loop through the grid to draw them. This would then be easy to convert into an MP grid too. I'd create macro constants for each land type, then add them into the grid, then draw the correct tile based on the constant used. If this sounds like something you'd like to try, then I'll post some code as an example.
would that mean Id have to restructure how I've got my world gen? because its random each time what tiles are where, would this method work?
I could be interested in it depending on what it'd do to my world gen
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Well, it depends how you're generating the world, but IN GENERAL, instead of doing "instance_create_layer()" in a loop, you'd do "ds_grid_set()". It would also depend on how "interactive" you want the world layer to be. I mean, you can still change the grid values, but if you require tiles in the world to overlap then it's more complicated.

So, the core of the idea is this:
  • You create a ds_grid the width and height of the room (so if your tiles are 32x32 it would be (room_width / 32 x room_height / 32 cells in size)
  • You then generate the tiles and instead of creating instances, simply set the DS grid to the appropriate value that symbolises the given tile
  • In the draw event, have two "for" loops that go through the grid row by row and draw the tiles.
 
B

Bogan666

Guest
Well, it depends how you're generating the world, but IN GENERAL, instead of doing "instance_create_layer()" in a loop, you'd do "ds_grid_set()". It would also depend on how "interactive" you want the world layer to be. I mean, you can still change the grid values, but if you require tiles in the world to overlap then it's more complicated.

So, the core of the idea is this:
  • You create a ds_grid the width and height of the room (so if your tiles are 32x32 it would be (room_width / 32 x room_height / 32 cells in size)
  • You then generate the tiles and instead of creating instances, simply set the DS grid to the appropriate value that symbolises the given tile
  • In the draw event, have two "for" loops that go through the grid row by row and draw the tiles.
I'm using GMS1.4 just as a heads up, so I don't have instance_create_layer(), but the world is generated by an object which I've set up to run scripts to pick a random empty spot on the map to say create 6 instances of a dirt block, scattered around the map. Those dirt blocks then each will check a random direction up to twice and make a new block, up to a maximum. probably not a super efficient way to do something like this, but it works with what I want the world to be, which is every block be intractable with. Would a ds_grid() function work in a case like this?
 
Top