History of Minesweeper SBGG so far


So here comes the announced "little" talk about the challenges and decision changes during development. As just the release post was already long, get ready for another novel.

Let us start many years ago. I started programming because I wanted to create some games. When I entered C#, I came in touch with the XNA-Framework, which was used for Windows and Xbox games. I started many games with it, but none reached a release state. I always got lost in something, be it making it highly configurable or some technical challenges. So some had really playable levels and some were still stuck in the level editor phase. At that time, I collected much knowledge about programming a game.

Time went by, and I abandoned the hobby of creating games, as I had not the time for it or was already programming enough on work. But the programming on the side never completely stopped. I still created small programs to support me in some way. But it was not with the XNA-Framework anymore as it was not games but simple tools. Therefore, I collected much experience with the .Net Framework.

Further years went by and my enjoyment of games started to disappear. I bought games which I didn't play much, and the money felt wasted. So I reached a point where it was very hard for me to get a good guess if a game is worth its money or not. It frustrated me, so I tried different genres to maybe find a new gold mine. At that time, I came across a video, where they said that you don't get a burn-out if you do too much at once as long as you do it voluntary and are motivated to do it. I disagreed with that statement, but thought to myself, let's give it a shot because why not. So I started to think about what I was looking forward to. Finding the type of game I like. Well, buying many games seems a waste of money, but what about creating core games to check what it is, I still enjoy?

Therefore, I picked up my very old hobby to program games. The first one was: Minesweeper. I played it much some years ago, and it was kind of a constant in my long gaming history. I even once created a 3D Minesweeper in Unity in voxel style, as I liked it so much. I wanted just a small and quick test, nothing serious. So I picked my mainly used .Net Framework and created a Minesweeper there. Took less than a week. It was fun, but I wanted to test more, so I also created a laser puzzle game, a memory game and a puzzle panic (the one where you have to toggle tiles to match a pattern).

I liked the challenges I encountered there and even picked up the Minesweeper once more to do a further challenge: Optimizing it as far as possible. Which I got very far. It also contained features that SBGG has not, Walls. This is the reason there are hovered fields, as I needed a help to see which fields are connected and which are not.

With all that programming, my brain aimed for bigger games. As I mentioned previously, Minesweeper is a constant in my history, so of course it was included. So one day I thought to myself, let's see how big I can make Minesweeper and therefore see, what kind of game I can put on top. The previous optimizations were for the classic small levels, let's say 100x100 maximal. That meant it was no use, as I required a different approach. This is true to this day BTW, the old implementation is for smaller levels more efficient than what I have in SBGG. So a new project folder was created and I implemented the other approach. As I needed to reimplement the basics I removed everything and therefore the walls are not an included feature anymore.

The implementation succeeded, and I could create bigger level with still acceptable RAM sizes. But as I couldn't see the complete level on screen anymore, I needed a mini map. Say no more, a new window will solve that, then I can place it anywhere I want to. What is that? The program is not responding anymore? I was drawing on the CPU and both windows used the same UI-Thread, which was not an issue, if I had just one screen full. But with both my screens drawing, my CPU reached its limit and couldn't react fast to any input.  Well, if one UI-Thread is not enough, let's take two. Some said it is not possible, but I got it working for me.

Great, I have two windows, all fine. But wait, what use is a mini map, if I can't use it to move around the camera. Yet with another input, I would have to sync back to the main UI thread which again could cause my original issue, that the CPU time is getting too big. Well, all good things are three. Let me create a third thread (non UI) to take care of the logic part. It will then just interrupt the UI thread when it wants to draw something.

The levels might be big now, and the mini map worked, but somehow it is a bit boring. I needed some extra motivation. Well, I had done a small research before to figure out what makes a game enjoyable, and one point was exploration or visual discovery. Occasionally, I'm on deviant art scrolling through their images and thought to myself, how about letting the user discover an image up close by revealing it field for field. The Image mode was born.

A bit of motivation was now as well in the game and with all the testing, I made up my mind. This is not the true end game I wanted, but it is good enough for an early release. I will just call it a tech demo and will use it as the training area in the bigger game. But the thing is, have you ever seen a programmer only used UI? It works for sure, but it is not user-friendly as the aim was functionality. So I needed to add translation quite late to the game, which was a pain. And also I have not so good memory of creating the design configuration UI. Probably need to rework that part some day. All worked smoothly, until I wanted to show it to somebody on my dying laptop. He is kind of slow and therefore some clicks did not land where I wanted to as I moved the mouse before the input was processed. How can you solve that issue? Input queues, here we come. The three threads stayed, but instead of the input events calling the logic more or less directly, they were filled into the input queue of the logic thread. The logic thread would process them at the upcoming fps tick.

Ok, we have already made a multi thread game with an input queue, what else could be there to do? What is that? If I resize the mini map too fast, my background image gets somehow destroyed and when I measure the time from begin to end of a frame I get way too high numbers. The first thing is a bug (not on my side but the core library), you could say it's caused by the too often redraw of the game. The second one is a bit more tricky. I first measured the draw time, which was in my goal of 60 FPS with my non gaming pc. So my first conclusion was, that the interruption of UI-thread takes too long. Later I found out, that it was not the Interruption but the creation of the draw object. Both issues caused me to really try hard to figure out how to move from CPU to GPU draw, as I was quite sure, that this would solve my issues.

The first library I found did the job on my main pc, but didn't work on my dying laptop. It also kind of blow up the project file size and something else that I forgot. So it was a nice entry to get an understanding, how GPU drawing works, but was not good enough. Therefore, my own implementation of the OpenCL library was created, which is, of course, tailored to my needs and had much lower impact on the project than the other library had. I did a lot of testing to figure out, what the fastest way is, to get the frame drawn on the screen. It took me at least one month with all the research and moving the implementation. Because keep in mind, before the logic and UI thread were synced during drawing. But now the GPU had no clue, what the values on the RAM were, so I needed to truly separate logic and drawing. So, instead of the UI asking the logic what the values were, the logic sends the UI thread a redraw request and provides all the needed information. With that, the drawing was moved from the CPU to the GPU and also every thread now had its own input queue.

Now, with the GPU part done, I was coming close to the release. Time to do some research. I checked the steam reviews of Minesweeper or alike games and used that feedback to create more quality of life improvements. The position and size saving of the windows or the indication when holding the discovery click are one of those changes. So thank you to everyone who writes reviews, it does not only help the creator of that game but also others.

Fine, I have a big level size with few RAM requirements, multi threads, highly configurable by the user, input queue, implemented things from the little market research and even have GPU draw. Can I rest now? Well, actually I don't play big games, as I think I will only play some minutes but end up playing an hour at least. You might want to move the save function from version 2 to version 1. Fair, so this feature, which was not planned for the first version, got moved. This is the reason everything works without the disk. It would make sense not to hold the whole level in your RAM, but just load the needed parts. But since I didn't expect to implement saving so early, I thought I had no choice.

Furthermore, we came from an optimized starting point, and therefore I did some optimizations again and again for each bigger step. With the GPU step, I also wanted to change the way the mini map was calculated, as in the old version it caused the first hard size border of 16'124x16'124. I did this as well already in version 1 so you can enjoy the 32'000x32'000 which, unlike the old limit, is not a true limit, you could go even higher. But for real, who needs an even bigger level? I already spent multiple hours in my 1'000x1'000 level and still have less than 10% solved.

So you may remember that I said, that I restarted programming games as someone told me I can do it as long as I'm motivated and want to do it? Guess what happened after all these months implementing it and taking care, that other can configure it to their liking? I wanted to do something else already. So I rushed the whole project at the end a bit. Don't get me wrong, it should be quite solid as a game, but if I would had more energy left, it might have gotten one or two quality of live improvements more.

Now you know, the history of Minesweeper SBGG and why i don't use a Game Engine and in fact a framework which is not designed for games but for tools. It started as a small research project and ended up as something i wanted to release. Of course, should i start the next game, i can skip some big time intensive parts as i can recycle the code from this project. But for now i will switch to something else that currently motivates me more. At least for a bit. And yes, one day i might build the game i have in my mind on top of Minesweeper SBGG but this will be an extra project and a long way. The plan there also changed, that it will get its own project, as someone who is looking to play minesweeper might not want the other interferences.

So was the statement true, that the amount of work doesn't matter but if you are doing it voluntary and being motivated to do it? Well, after that journey, i can't say no anymore. You win this one. But please take care not to overshoot, always keep an eye on your health!

I wish all of you the best and please stay healthy.

Get Minesweeper SBGG

Leave a comment

Log in with itch.io to leave a comment.