Tuesday, June 29, 2010

Fortune Updates and Headaches

Today was a fairly productive day. We got a few tickets tackled, had a couple great discussions, and found a few major problems with the Fortune Engine.

First task of the day was to update the Game Engine's timer api (ticket 30) to simplify it as well as make it more consistent with the rest of the engine. Before this api change, the developer would need to set a timer (between zero and eight) and set the time between fires. After that they would have to listen for a pygame.USEREVENT + id in the event loop and then handle the event as they wanted. The problem with this is they have nine timers that they have to keep track of, making sure they don't reuse a timer between different elements of their code. The new api now takes in a function and a time delay. When the timer fires, it calls the function directly. When the user wants to remove the function, they simply pass in the callback function they wish to remove. The developer no longer needs to worry about what timer they are using, as long as they don't need more then the nine given to them.

In the process of testing the new timer system, I found the cause of the long standing Search Exiting Early bug (ticket 16). This was a bug that when the player was trying to search a room for hidden items using the amulet search method, it seemed to abort early with no reason. Well the cause of this bug was the pyconsole set the repeat character option that was interfering with the game timers when it sent repeat events. I don't like having the console changing the behavior of pygame. While it is useful for the backspace key, it is less then idea to have the console changing global behavior. So my change was to simply remove that from the pyconsole.

While changing the pyconsole I found that the new threading system was causing problems with console input, so I had to make a commit changing pyconsole so that it's process method acts more like the rest of my input handling.

One major problem with the game engine we found was when user's code crashes in one of their callbacks, the game engine would crash causing the window to freeze due to the draw or event loop getting the exception. The problem is, if one of the loops crash, the game should exit all threads and close. The solution was to catch the exception, print its stack trace and then call the stop_event_loop function (ticket 33). This is only one of the major problems we found. Another problem that I haven't solved yet is when their code goes into an infinite loop that doesn't return control to the game engine. This could be solved with a watchdog thread that will kill the loop if it hangs, but that gets messy. Another solution could be to spawn user callbacks in their own threads, but the overhead and thread maintenance would be another headache on its own. At the moment I haven't decided on a solution or whether I shouldn't worry about it at all.

I have also added a few tickets today for a later date. Some of them include adding a profiling system that can be turned on in engine for debugging and optimizing tools it could provide (ticket 31). We also need to modify the draw API so that it can give access to the time elapsed argument to the animation system (ticket 34). The art team and the engine team had a nice long talk about the best way to get animation into the game and we found that giving them all a time difference seemed to be the preferable method. Luckily the pygame click.tick method not only controls our frame rate, but adds the ability to give us the time elapsed since the last frame. A third ticket we made was to incorporate a dirty draw technique to increase our frame rate by reducing the amount of processing we need to do on each draw (ticket 35).

Well with that said I leave you this, Threading is a wonderful thing, but creates a lot of headaches and problems.

No comments:

Post a Comment