Only one smoothing iteration occurring in my cellular automata script

I have a game where the worlds generate by generating noise made up of random tiles, and then it smooths out those tiles using cellular automata. The way it does this is the cellularAutomata function detects the amount of neighbours of each kind for each tile and stores it in 2d int arrays and then the smoothTiles function accesses the count from the 2d arrays and changes what each tile should be based off of the number. In the start function the script runs the smoothTiles function the amount of times that the int smoothCycles is. In the editor I set smoothCycles to 5, but it only seems to do one smoothing iteration. Are there any problems with my script that any of you can see?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class worldGen : MonoBehaviour
{
    public int smoothCycles;

    public Tile water;
    public Tile ground;
    int[,] waterCount;
    int[,] groundCount;

    public Tilemap tilemap;
    public int width = 100;
    public int height = 100;

    public Tile[] tileTypes;

    void Start()
    {
        genRandomTiles();
        cellularAutomata();
        for (int i = 0; i < smoothCycles; i ++)
        {
            smoothTiles();
        }
    }

    void genRandomTiles()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                int rand = Random.Range(0, tileTypes.Length);
                Vector3Int pos = new Vector3Int(x, y, 0);
                tilemap.SetTile(pos, tileTypes[rand]);
            }
        }
    }
    void cellularAutomata()
    {
        waterCount = new int[width, height];
        groundCount = new int[width, height];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                List<TileBase> neighbours = new List<TileBase>();
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        int neighbour_x = x + i;
                        int neighbour_y = y + j;

                        if (i == 0 && j == 0)
                        {

                        }
                        else
                        {
                            Vector3Int pos = new Vector3Int(neighbour_x, neighbour_y, 0);
                            neighbours.Add(tilemap.GetTile(pos));
                        }
                    }
                }
                for (int i = 0; i < neighbours.Count; i++)
                {
                    if (neighbours[i] == water)
                    {
                        waterCount[x,y]++;
                    }
                    else if (neighbours[i] == ground)
                    {
                        groundCount[x,y]++;
                    }
                }
            }
        }
    }

    void smoothTiles()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                Vector3Int pos = new Vector3Int(x, y, 0);
                if(waterCount[x,y] > 4)
                {
                    tilemap.SetTile(pos, water);
                }
                else if (groundCount[x,y] > 4)
                {
                    tilemap.SetTile(pos, ground);
                }
            }
        }
    }
}

How are you verifying that smoothing is only running one time? Have you tried inserting a Debug.Log() statement inside the smoothTiles method to verify that it is only happening once?

If you did so, did you remember to disable the “Collapse” toggle in the console window to make sure Unity prints duplicate console messages?

1 Like

I verified it seemingly only being able to smooth once by setting pressing space to do the smoothTiles function instead of having it do a set amount of smoothing iterations, and it only worked the first time pressing the space key and not any of the times afterwards. I made sure to add debug.log() in the code detecting if space is being pressed and it did print a console message each time I pressed space, so I’m pretty sure it is either a problem with the smoothTiles function itself, or the neighbour detection system.

You’re beating around the bush. Add a Debug.Log to smoothTiles directly to see how many times it is being called.

1 Like

I did what you said and it printed 5 times, which is the number I set smoothCycles to.

Okay, I fixed it. I put the code for the neighbour detection system in smoothTiles.