Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Maze Chunk Generation System having problems

Discussion in 'Scripting' started by Minespeed1009, Oct 10, 2021.

  1. Minespeed1009

    Minespeed1009

    Joined:
    Apr 16, 2019
    Posts:
    7
    So, I have an enum for walls, simply called WallState, with the 4 cardinal direction as bitmasks. I also have a struct called Chunk, which simply has a Position (x and y struct) and a WallState[,]. I have Chunks handle a 5, 5 tiling of WallState's and the map is simply a 3x3 of chunks that generates as the player moves. When you go to the chunk to the right of the center, that chunk on the right becomes the center, all the chunks on the left get removed, and new chunks get generated on the right. It's meant to be an infinite maze that has no ending, but for some reason, whenever I move out of the original 3x3 of chunks that generate on startup, I have a chance that when moving to the left or the right (not up and down confusingly) I have a chance to bump into an invisible wall...

    upload_2021-10-11_9-58-10.png

    Above, I cannot move right, even though a wall doesn't exist there, it does somewhere in the code...

    Code (CSharp):
    1. public static Chunk[,] ShiftMaze(Chunk[,] maze, WallState direction, int width, int height) {
    2.         Chunk[] generatedChunks = new Chunk[3];
    3.         Chunk[,] tempNewMaze = new Chunk[5,5];
    4.         Chunk[,] newMaze = new Chunk[3,3];
    5.         if (direction.HasFlag(WallState.LEFT)) {
    6.             Chunk[,] newChunkTemp = GenerateMaze(15,5,Time.time.ToString());
    7.             for (int i = 0; i < 3; i ++) { generatedChunks[i] =  newChunkTemp[i,0]; }
    8.             for (int x = 0; x < 4; x ++) {
    9.                 for (int y = 0; y < 3; y ++) {
    10.                     if (x == 0) {
    11.                         tempNewMaze[x,y+1] = generatedChunks[y];
    12.                     } else {
    13.                         tempNewMaze[x,y+1] = maze[x-1,y];
    14.                     }
    15.                 }
    16.             }
    17.             for (int x = 0; x < 3; x ++) {
    18.                 for (int y = 0; y < 3; y ++) {
    19.                     newMaze[x,y] = tempNewMaze[x,y+1];
    20.                 }
    21.             }
    22.         }
    23.         if (direction.HasFlag(WallState.RIGHT)) {
    24.             Chunk[,] newChunkTemp = GenerateMaze(15,5,Time.time.ToString());
    25.             for (int i = 0; i < 3; i ++) { generatedChunks[i] = newChunkTemp[i,0]; }
    26.             for (int x = 0; x < 4; x ++) {
    27.                 for (int y = 0; y < 3; y ++) {
    28.                     if (x == 3) {
    29.                         tempNewMaze[x+1,y+1] = generatedChunks[y];
    30.                     } else {
    31.                         tempNewMaze[x+1,y+1] = maze[x,y];
    32.                     }
    33.                 }
    34.             }
    35.             for (int x = 0; x < 3; x ++) {
    36.                 for (int y = 0; y < 3; y ++) {
    37.                     newMaze[x,y] = tempNewMaze[x+2,y+1];
    38.                 }
    39.             }
    40.         }
    41.         if (direction.HasFlag(WallState.UP)) {
    42.             Chunk[,] newChunkTemp = GenerateMaze(5,15,Time.time.ToString());
    43.             for (int i = 0; i < 3; i ++) { generatedChunks[i] = newChunkTemp[0,i]; }
    44.             for (int x = 1; x < 4; x ++) {
    45.                 for (int y = 1; y < 4; y ++) {
    46.                     tempNewMaze[x,y] = maze[x-1,y-1];
    47.                 }
    48.             }
    49.             for (int i = 0; i < 3; i ++) { tempNewMaze[i+1,4] = generatedChunks[i]; }
    50.             for (int x = 0; x < 3; x ++) {
    51.                 for (int y = 0; y < 3; y ++) {
    52.                     newMaze[x,y] = tempNewMaze[x+1,y+2];
    53.                 }
    54.             }
    55.         }
    56.         if (direction.HasFlag(WallState.DOWN)) {
    57.             Chunk[,] newChunkTemp = GenerateMaze(5,15,Time.time.ToString());
    58.             for (int i = 0; i < 3; i ++) { generatedChunks[i] = newChunkTemp[0,i]; }
    59.             for (int x = 1; x < 4; x ++) {
    60.                 for (int y = 1; y < 4; y ++) {
    61.                     tempNewMaze[x,y] = maze[x-1,y-1];
    62.                 }
    63.             }
    64.             for (int i = 0; i < 3; i ++) { tempNewMaze[i+1,0] = generatedChunks[i]; }
    65.             for (int x = 0; x < 3; x ++) {
    66.                 for (int y = 0; y < 3; y ++) {
    67.                     newMaze[x,y] = tempNewMaze[x+1,y];
    68.                 }
    69.             }
    70.         }
    71.  
    72.         for (int j = 0; j < 4; j ++) {
    73.             for (int i = 0; i < 5; i ++) {
    74.                 if (j == 0) {
    75.                     if (maze[1,1].Walls[0,i].HasFlag(WallState.LEFT)) { maze[0,1].Walls[4,i] |= WallState.RIGHT; }
    76.                     else { maze[0,1].Walls[4,i] &= ~WallState.RIGHT; }
    77.                 }
    78.                 if (j == 1) {
    79.                     if (maze[1,1].Walls[i,4].HasFlag(WallState.UP)) { maze[1,2].Walls[i,0] |= WallState.DOWN; }
    80.                     else { maze[1,2].Walls[i,0] &= ~WallState.DOWN; }
    81.                 }
    82.                 if (j == 2) {
    83.                     if (maze[1,1].Walls[4,i].HasFlag(WallState.RIGHT)) { maze[2,1].Walls[0,i] |= WallState.LEFT; }
    84.                     else { maze[2,1].Walls[0,i] &= ~WallState.RIGHT; }
    85.                 }
    86.                 if (j == 3) {
    87.                     if (maze[1,1].Walls[i,0].HasFlag(WallState.DOWN)) { maze[1,0].Walls[i,4] |= WallState.UP; }
    88.                     else { maze[1,0].Walls[i,4] &= ~WallState.RIGHT; }
    89.                 }
    90.             }
    91.         }
    92.         return newMaze;
    93.     }
    All that GenerateMaze() does is takes in a size (x, y) and a seed, and then uses a recursive backtracker on the generated maze to add some paths.
    ShiftMaze() is only called whenever the player moves into a new chunk, and chunk[1,1] is the center.
    I added the last double for loop to try and check if the Chunk WallStates just aren't rendering correctly.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    Staring at sheets of code like this is unlikely to reveal the issue, especially with 2D looping like that and shifting.

    Instead you have to set it up to do the condition you mention, then see exactly how it fails at runtime, given the same known maze over and over again.

    From that you must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - you are off by one number in one direction or another (offset, or loop limit for example)
    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
  3. Minespeed1009

    Minespeed1009

    Joined:
    Apr 16, 2019
    Posts:
    7
    I used many different Debug.Log()'s to tell me whenever the maze is being shift, which way it's shifting, if it finds a fake wall that needs to be replaced and it's position, and I think I might have an idea of what the problem is, I just don't know how to solve it...

    I found out that it is most definitely finding said fake walls, but I think that it might not be either the PlayerController script not finding the wall OR the fake walls not being found. I understand that whenever I enter a chunk, it will check along the walls to find any fake walls that need to be replaced, but sometimes as soon as I enter an adjacent chunk, then it will fill in. Here's an example:

    upload_2021-10-12_10-40-40.png
    As shown, the player is at X: 5, Y: 3. After moving down two spaces into the green chunk, the fake walls (marked in blue), will then be generated. Note the shape of the red chunk and the green chunk.

    upload_2021-10-12_10-44-22.png

    This is the start of the maze. The green and red chunk have just been shifted down and to the left once to see the fake walls. As seen by the blue path, this will take us to the same position. But now...
    upload_2021-10-12_10-46-5.png

    It looks different... It seems the right chunk has a different layout. That's because of that seed being Time.time...
    But I still can't move through it. After exploring the original starting chunks I found that they don't have that glitch. So, the problem:

    The problem is obviously with the maze generation. I just don't know what's causing it.

    Here's a pastebin to the entire MazeGeneration.cs script: https://pastebin.com/08GPzLYx

    Sorry for the long comment...