# Method for obtaining adjacent chunk positions

I'm currently in the process of making a 2D tile based game. This game has an "infinite" world that can be traversed and modified as needed. I am creating the chunks with a mesh and I apply a texture to them. The chunks texture updates every time I set a tile with a new Sprite.

Each time I set a new tile, the surrounding tiles from the same chunk recalculate based on their adjacent tiles and they set their sprite accordingly (Auto-tiling). This works perfectly fine and I have no issues, unless the tile is along the edge of the chunk.

If the tile is along the edge of the chunk, it updates the texture of the chunk perfectly but the adjacent chunk textures aren't updated. Now, I am using the below code to obtain the adjacent chunks based on the tiles position. This works, however it is extremely ugly and unreadable.

if (tileX == 0 || tileY == 0 || tileX == chunkSize - 1 || tileY == chunkSize - 1)
{
var chunksToUpdate = new List<Vector3Int> ();
var position = chunk.Position;

if (tileX == 0 && tileY == 0)
{
chunksToUpdate.Add (new Vector3Int (position.X - chunkSize, position.Y, position.Z)); //left
chunksToUpdate.Add (new Vector3Int (position.X, position.Y - chunkSize, position.Z)); //down
chunksToUpdate.Add (new Vector3Int (position.X - chunkSize, position.Y - chunkSize, position.Z)); //downleft

}
else if (tileX == 0 && tileY == chunkSize - 1)
{
chunksToUpdate.Add (new Vector3Int (position.X - chunkSize, position.Y, position.Z)); //left
chunksToUpdate.Add (new Vector3Int (position.X, position.Y + chunkSize, position.Z)); //up
chunksToUpdate.Add (new Vector3Int (position.X - chunkSize, position.Y + chunkSize, position.Z)); //upleft

}
else if (tileX == chunkSize - 1 && tileY == 0)
{
chunksToUpdate.Add (new Vector3Int (position.X + chunkSize, position.Y, position.Z)); //right
chunksToUpdate.Add (new Vector3Int (position.X, position.Y - chunkSize, position.Z)); //down
chunksToUpdate.Add (new Vector3Int (position.X + chunkSize, position.Y - chunkSize, position.Z)); //downright

}
else if (tileX == chunkSize - 1 && tileY == chunkSize - 1)
{
chunksToUpdate.Add (new Vector3Int (position.X, position.Y + chunkSize, position.Z)); //up
chunksToUpdate.Add (new Vector3Int (position.X + chunkSize, position.Y, position.Z)); //right
chunksToUpdate.Add (new Vector3Int (position.X + chunkSize, position.Y + chunkSize, position.Z)); //upright

}
else if (tileX == 0)
{
chunksToUpdate.Add (new Vector3Int (position.X, position.Y + chunkSize, position.Z)); //up

}
else if (tileX == chunkSize - 1)
{
chunksToUpdate.Add (new Vector3Int (position.X + chunkSize, position.Y, position.Z)); //right

}
else if (tileY == 0)
{
chunksToUpdate.Add (new Vector3Int (position.X, position.Y - chunkSize, position.Z)); //down

}
else if (tileY == chunkSize - 1)
{
chunksToUpdate.Add (new Vector3Int (position.X, position.Y + chunkSize, position.Z)); //up

}


Clarification: I am checking to see if tileX or tileY are along the edges of the chunk. If they are then I add a new Vector3Int to the list. I also only attempt to obtain the chunks that will be affected by the chunks texture update.

After this, I loop through all of the Vector3Int's in the chunksToUpdate list and update them like so.

foreach (var pos in chunksToUpdate)
{
MeshChunk updateChunk = GetChunk (pos);

if (updateChunk != null)
{
UpdateChunkTiles (updateChunk);
}
}


I'm not looking for any criticism about my naming conventions or formatting. I'm wondering if there is a more elegant way of handling this scenario? Can it be refactored to take up less space and its readability improved.

• No one has a more elegant solution? Or I've completed butchered my post and barely anyone understands it? Feb 2 '16 at 6:46
• your post is good :) I can't think of any way to improve it, that's how all my infinite world generation code looks too Feb 3 '16 at 18:53
• Jamal thanks for editing my post and cleaning it up. @KeithM Thanks but surely there is some genius out there that can come up with an algorithm to make it look cleaner :) Feb 4 '16 at 8:15

Well, I suggest next approach

        if (tileX != 0 && tileY != 0 && tileX != chunkSize - 1 && tileY != chunkSize - 1)
{
return;
}

var leftChunk = tileX == 0;
var rightChunk = tileX == chunkSize - 1;
var downChunk = tileY == 0;
var upChunk = tileY == chunkSize - 1;

if (leftChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X - chunkSize, position.Y, position.Z)); // Left
if (downChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X - chunkSize, position.Y - chunkSize, position.Z)); // DownLeft
}
else if (upChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X - chunkSize, position.Y + chunkSize, position.Z)); // UpLeft
}
}
else if (rightChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X + chunkSize, position.Y, position.Z)); // Right
if (upChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X + chunkSize, position.Y + chunkSize, position.Z)); // UpRight
}
else if (downChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X + chunkSize, position.Y - chunkSize, position.Z)); // DownRight
}
}
if (downChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X, position.Y - chunkSize, position.Z)); // Down
}
else if (upChunk)
{
chunksToUpdate.Add(new Vector3Int(position.X, position.Y + chunkSize, position.Z)); // Up
}


It makes code a little bit more readable by using bool named variables and also has less code lines and if else branching.

Moreover, it is often (almost every time) better to have less nesting via inverting if statement like I did. So basically I quit if it is not an edge tile.

• Thanks! That is much better and so much easier to read. I knew there would be someone out there who could come up with a more elegant way. Much appreciated :) Feb 8 '16 at 23:49