Posted August 12, 2023 by Kuma-Gee
#devlog #match-3
So now let's talk about how to create a simple match 3 game. I started with absolutely no idea on how to tackle this except using a 2D array for the data. So I obviously looked up some tutorials and found a pretty good one that was exactly what I needed, so most of the credit goes to him:
But like most tutorials, they don't exactly write the best code, just something that works for the simple game they are doing. I decided to do it a little bit different but the concept is the same how everything works under the hood. I just didn't like the idea that the data and the UI were really closely coupled which would make it almost impossible to write test which I've noticed is quite rare in game development but it did same me a lot of time debugging for problems since I did not have to start the game every time and hope I can reproduce it.
So let's go into the detail on how I actually implemented it. I will release the source code in the future, but currently it's easier for me to keep it private. Some things also be Godot specific, especially things concerning the UI. But let's start with the things I did differently than the tutorial or things that bothered me.
He did not use any UI elements
Godot has all these UI elements that would make some things a lot easier. The GridContainer can automatically align the items in a grid and Control nodes in general have an easier way of handling mouse inputs. So that's what I did first, but there was already a problem. The items inside the grid are fixed and cannot really be moved, so I could not do swaps or any kind of movement. After many trial and errors I found a way that worked good enough. I used fixed slots inside the grid which did not move, but these slots can capture and move Node2D elements around. I was inspired by this post about an inventory system:
https://medium.com/@thrivevolt/making-a-grid-inventory-system-with-godot-727efed...
He combined UI and the data
This might not bother everyone, but I prefer clear boundaries between them if possible. This also makes it easier to read and understand the code since you don't have to deal with UI stuff when working with the data. It might not be clear what I mean with data, but it's basically the 2D array part. You just work with the data, check for matches, collapse the columns etc, all without the UI. This is in my opinion much easier to read and especially easier for writing tests, which has probably saved me a huge amount of time after I had to do a major refactor because of a wrong design decision. So let's continue with the next problems and the stupid solution I came up with.
I saw in the tutorial that he was using timers to wait for the actions. So I tried a similar approach where the UI is the one calling the actions to the data. This made it more consistent and easier to work with.