Wednesday, January 10, 2024

Bug Hunting

A restless night, running over in my head the possibilities and plan of attack for combatting this new bug. I have an array of techniques for finding a bug, but this one was unusual in that it had a specific result - a freeze after about 1 second of running, and only about 20 or 25% of the time. The main program seemed to keep running in the background, so it was primarily a display problem.

First I found old copies of my engine and tested those. Again the same problem; so this wasn't caused by recent changes. Then I set up a key-press to play a sound. This proved that when the graphics were frozen the main game loop was indeed running, but at a crawl of about one frame per second. By this stage, I'd ruled out it being a timer problem, and by flagging off various lines, had ruled out it being pretty much anything to do with my code, it must be a system problem.

I tested Gunstorm 1 & 2 last night on Deb's computer and it worked fine. Then, today, I tested it on various resolutions. They all worked apart from when selecting the desktop resolution. The start-up was different too; the screen paused and went notably black for about half a second when starting normally, but when the desktop resolution was chosen, it jumped straight in to the game, and then the bug appeared: About 25% of the time, it would visually freeze. Curiouser and curiouser.

I tried switching screenmode in the program while it was frozen (blessed that the main loop kept running, so the keys would respond). This worked, it re-awakened the program. Then I tried resetting the screen device, and this too fixed things, actually restoring the program in the correct resolution - so I had a fix. But a fix like that would be no comfort to a player. Having to press a key to wake up a dead game isn't a feasible solution, even if it's a rare event.

So, I wondered if I could start in a different resolution, then switch to the desktop one. I made it start in 640x480 (still a standard for graphics cards, but nobody would have a Windows Desktop of that size), then switch to the final one. This worked! The screen went black for half a second as though resetting, then everything started and seemed (seems!) stable. So, the bug is either a fault in the DirectX9 implementation on Windows 11, or a driver fault. Resetting the display fixes it, so it appears that 'changing' to the current resolution doesn't act correctly, doesn't reset or flush data or something like that.

Now, its not ideal to change resolution twice every time, it's two screenmode changes in quick succession, and graphics cards or monitors might not like this, but there's no easy way to avoid it. I can test if the user selects desktop resolution, but can't test if the 'best' (or any other) screenmode is the desktop resolution because a screenmode is only confirmed as valid by actually trying it, and by then it would be too late.

So the best option is indeed to do this every time, but I've added a new option, 'robustinit', which can be switched off to use the old behaviour of a single jump into the correct mode.

So, 24 frantic and full hours spent on this bug. Now I can continue with the game updates proper.