Tiles in a certain area of the map randomly chosen automatically

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By BlackFenix06

Hi, I have a question, hoping for your help. I didn’t find much looking for, but maybe I missed something.

I am building the game world map and it is made up of different areas where the terrain is made of different materials (for example, areas of dirt, rock, grass, water, etc.) In practice, what I would like is that each zone is made up of its own tiles chosen randomly. Or to better explain, if I create an area of grass in building the map, for example, I want the tiles in that area to be chosen randomly from the group used for that area.

This question arises from the fact that the map I’m creating is very huge, and having to manually randomize the tiles in a certain area becomes very long. If instead there is the possibility to say for example, in that area I put a dirt zone and the tiles are randomly chosen from the group of dirt tiles, it would make the job much easier and faster. Also, since the aforementioned areas are background only (so there is no contact or interaction between the tiles and the player), every time you restart the game, the landscape changes every time.


I tried playing with gdscript, looking around. I created this script to try, and almost everything works, except it doesn’t change the tile to the one chosen randomly.

extends TileMap

func _ready():
	for array in get_used_cells_by_id(484):
		var water_0_group_tile = [484, 543, 544, 545]
		var randomft = randi()%100+0
		if randomft <= 40:
			var randomsd = randi()%100+0
			if randomsd <= 20:
				var randomth = randi()%3+0
				var size = get_cell_size()
				var tile = Vector2(array[0]*size[0], array[1]*size[1])
				set_cell(tile.x, tile.y, choose_tile_id[randomth])

How do you generate the areas? In the past, I’ve generated areas by filling grids with numbers, and substituting tiles for those numbers. Each tile can be selected from a random array of tiles (the array could contain a reference to the tile number in a tile set). Some of the code could look like this:

  # Some arrays of random tiles. You do the shuffling in the _ready() function.
  # These make matching the numbers in the grid easier.
  const var STONE = 2
  const var ROAD = 3
  for tile in tile_grid:
        if tile == STONE:
             var stone_tile = stone_grid.pop_front()

This is just some boilerplate code, but I hope it points you in the right direction.

Ertain | 2021-02-01 00:50

I added a new part to my question

BlackFenix06 | 2021-02-01 08:24

:bust_in_silhouette: Reply From: CharlesMerriam

Let me see if I understand your problem:

  1. You have a lower resolution game map, e.g., ‘this 40 by 40 region is some sort of grass’.

  2. You want a higher resolution player map, e.g., ‘in the region, this square is grass3, this one is grass2’ and so on.

  3. You don’t care about repeatability among grass3, grass2, etc.

Traditional answers include:

  1. Wait. Only create a region when it actually going to be used. That is, don’t populate your entire world. You are probably doing this already.

  2. Cheat. Make a few region maps for each type of tile. When you need a region, pick one at random, optionally giving it a vertical flip (if your map allows it). Alternately, you can up the number of possible region maps by making one “too large” map, e.g., 50 by 50 for your 20 by 20 region size. When you want a random region map, pick a starting tile corner and crop to 20 by 20. It looks random with a low space and computation overhead.

  3. Seed. If you want reproducibility, meaning ‘region 34 grass is the same each time’, use the region number as a seed for creating the random number just before getting the region map. Then whatever random numbers you get will be the same for that region. That is, if you code asks get_region(region_number), it will call rand_seed(region_number), and the next random numbers requested, e.g., start_x = randi_range(0, max_x) will always be the same for that region number, and so the generated region will always be the same.

I hope this helps; its not very Godot specific.

Hi, I’m answering on my mobile because I’m at work at the moment and can’t use my computer to edit my question. I realize that I have not been able to make myself understood well, thanks to the fact that I am using Google translate. To put it in a nutshell, I’m recreating Zelda’s Breath Of The Wild Hyrule map. It is made up of areas of rock, grass, etc. Always using the same tile to create for example a patch of grass, it makes everything monotonous. That’s why I have several tiles such as grass. But manually placing each different grass tile becomes too long. What I would like is that if I manually go to create a grass area with the tile “grass_0_0”, for example, it is replaced by any tile chosen randomly from the same group (so that a tile between “grass_0_0” is chosen, “grass_0_1”, “grass_0_2” etc). Also there does not have to be a save of it, in this way, every read that you restart the game, the aforementioned areas are always different.

BlackFenix06 | 2021-02-01 08:23

Ok. Yes.

Are you using GDScript? Are you using sprites or a texture map. Can you just preload the texture maps-nd substitute them in _ready()?

CharlesMerriam | 2021-02-05 05:29

I added a new part to my question.

BlackFenix06 | 2021-02-07 00:09