When I was at a friends house last weekend working on an iPhone project, I had a big computer security scare. We'd reached a point where I wanted to transfer a build over him so he could play around with it, so I put the build in my network share folder. When he browsed to my computer though, instead of just seeing my read-only drop box, he saw my entire programming directory with ~10 projects in it...and he had read/write access to it! Let me say that again, my main development folder had read/write access privs set for everyone, essentially it was a shared public folder
Now this is a pretty stupid thing to set, and what makes me kick myself even more is I'd set this many many times, not knowing the implications of what I was doing. I'd exposed my precious data to anyone to read or even modify. This was especially scary because I like working at coffee shops, so I was very lucky some bored, tech-savvy person didn't go and delete the projects I'd spent hours or days on.
In case you're wondering why I'd set public read/write privs on a folder that's so important, the answer is it was a workflow I was using for development. I had to share symlinks between my OS X and WinXP installations (I run WinXP through a virtual machine). There are some nuances regarding sharing symlinks between these two OS's (I don't recall the exact issue), but a workaround I found was to, among other things, publically share my dev folder. What really kills me though, is I found a better workflow several months ago that didn't require symlinks at all.
Moral of the story, make sure your important data directories aren't set to be shared publicly :)
I'm the co-founder and programmer of Nakai Entertainment (www.NakaiEntertainment.com), a small mobile games company in Raleigh, NC. I talk a lot about programming, game development and design, and games engines like Unity3d and Unreal.
Saturday, February 27, 2010
Thursday, February 11, 2010
GDI leak hunting season
In addition to my create an installer task, the past several days I've been tasked with finding an extremely nasty bug in our project. The game would run fine for several minutes, however inevitably it would begin to exhibit some strange behavior, such as random text strings no longer rendering or the entire game window, or even monitor display, flickering wildly. Obviously QA would never allow us to ship a product in such a condition, so I had to dive in and figure out what was going on.
To start off, I've previously never delved very deeply into the Windows API. The beautiful thing about working with an existing game engine is most of the low-level OS interactions are abstracted away, so you only need to worry about implementing new, cool features on top of that layer. Unfortunately for this project, we needed to do some very low level interaction with the Windows API in order to fulfill a feature request by our client. In this case, we were interacting with the Windows Graphics Device Interface API to handle some custom font rendering. We made some good initial progress on the feature implementation, however the programmer working on it had to suddenly take some personal leave time for family reasons. This left us in a lurch because the feature implementation, while working as a prototype, wasn't fully completed, cleaned-up and optimized yet. One of the nasty caveats with Windows GDI Object handles is there are a limit number of handles you can have active (~10000 on my XP system). Once you reach that number, the OS appears to start doing some very odd things, which causes things to disappear and applications to start flickering.
I'll save you the boredom of describing my late nights looking over code and reading GDI documentation, but suffice to say it was a late couple nights :). Thinking back now, I could kick myself for not doing some obvious things until today. My breakthrough today came when I finally looked up online some additional resources about GDI memory leaks and how to find them. There are some interesting articles and techniques for finding GDI leaks, however I felt they were all overkill for our particular situation. Most of those techniques were for finding a leak *somewhere*, however in our case I knew we had a leak in a very specific area of our code (about 400 lines altogether). The real breakthrough came when I found out you can add a 'GDI Object' column in the Windows Task Manager (View->Select Columns), and watch in real time as the count goes up and down for a particular application. On the surface this doesn't appear incredibly useful finding a leak *somewhere*, however as I said above, I knew the leak was happening in a very specific area. So I fired up the trusty debugger and began stepping through the suspect code line-by-line while watching the GDI Object count; and after several minutes I found the offending item. A CreateSolidBrush() call hidden deep within an if block was allocating a new handle, but never deleting it. After I fixed the leaking object I ran the game again and confirmed our GDI Object count was now steady.
Victory!
To start off, I've previously never delved very deeply into the Windows API. The beautiful thing about working with an existing game engine is most of the low-level OS interactions are abstracted away, so you only need to worry about implementing new, cool features on top of that layer. Unfortunately for this project, we needed to do some very low level interaction with the Windows API in order to fulfill a feature request by our client. In this case, we were interacting with the Windows Graphics Device Interface API to handle some custom font rendering. We made some good initial progress on the feature implementation, however the programmer working on it had to suddenly take some personal leave time for family reasons. This left us in a lurch because the feature implementation, while working as a prototype, wasn't fully completed, cleaned-up and optimized yet. One of the nasty caveats with Windows GDI Object handles is there are a limit number of handles you can have active (~10000 on my XP system). Once you reach that number, the OS appears to start doing some very odd things, which causes things to disappear and applications to start flickering.
I'll save you the boredom of describing my late nights looking over code and reading GDI documentation, but suffice to say it was a late couple nights :). Thinking back now, I could kick myself for not doing some obvious things until today. My breakthrough today came when I finally looked up online some additional resources about GDI memory leaks and how to find them. There are some interesting articles and techniques for finding GDI leaks, however I felt they were all overkill for our particular situation. Most of those techniques were for finding a leak *somewhere*, however in our case I knew we had a leak in a very specific area of our code (about 400 lines altogether). The real breakthrough came when I found out you can add a 'GDI Object' column in the Windows Task Manager (View->Select Columns), and watch in real time as the count goes up and down for a particular application. On the surface this doesn't appear incredibly useful finding a leak *somewhere*, however as I said above, I knew the leak was happening in a very specific area. So I fired up the trusty debugger and began stepping through the suspect code line-by-line while watching the GDI Object count; and after several minutes I found the offending item. A CreateSolidBrush() call hidden deep within an if block was allocating a new handle, but never deleting it. After I fixed the leaking object I ran the game again and confirmed our GDI Object count was now steady.
Victory!
Wednesday, February 10, 2010
Installer purgatory
I spent most of the day yesterday creating an installer for one of our projects. Unfortunately, I wasn't told we needed an installer until pretty late in the project, so I had to drop everything and make that my number 1 priority. And by pretty late in the project, I mean I had about one-and-a-half days to make it.
Installers. They've become one of my arch-enemy tasks at work. That part of my job is a poster-child for why you shouldn't volunteer to learn something, because you instantly become the person who always does it. Scott Adams occasionally points this out in his dilbert cartoon strip...if only Scott's warning had reached me sooner!
The biggest reason I hate working on installers is they're generally very tedious and time-consuming to create and test. An installer is the user's first impression of your game, and if it fails to work properly, they will have a negative impression of your product before they even get a chance to play it. Consequently, installers must be rock-solid and bug free on all your supported OS's, otherwise you could face some real nightmare scenarios, such as this or this.
Installers. They've become one of my arch-enemy tasks at work. That part of my job is a poster-child for why you shouldn't volunteer to learn something, because you instantly become the person who always does it. Scott Adams occasionally points this out in his dilbert cartoon strip...if only Scott's warning had reached me sooner!
The biggest reason I hate working on installers is they're generally very tedious and time-consuming to create and test. An installer is the user's first impression of your game, and if it fails to work properly, they will have a negative impression of your product before they even get a chance to play it. Consequently, installers must be rock-solid and bug free on all your supported OS's, otherwise you could face some real nightmare scenarios, such as this or this.
Tuesday, February 2, 2010
Snowed in with Mass Effect 2
Big snow storm hit the East Coast this weekend, so I stayed in the entire weekend playing Mass Effect 2.
Let me say I loved that game, I ended up putting in ~40 hours on my first run through as a Sentinel. Overall I enjoyed the Sentinel gameplay, it gave a good mix of tech and biotic powers that allowed a lot of flexibility when faced with a wide variety of foes. Because I was able to deal with organics, mechs and shield/armor based foes myself, I had a good amount of latitude in my teammate choices. One thing I hate is feeling forced into using certain people just because you have to cover a hole in your offensive capabilities.
I'm probably gonna play through again as a Soldier to get a feel for the game in a different play style, although I'm also pondering playing as a Vanguard. One of my co-workers played as a Vanguard and wasn't as happy with it because he felt it was a one-trick pony with biotic charge. Once you charged, you were left in the middle of a group of enemies without any cover and gimped weapons (he didn't think the shotgun was very powerful, even fully upgraded).
From a game developer point of view, I was very impressed with the game. I saw a number of small bugs, like the camera not focusing correctly or characters not appearing in the camera's view; plus a couple of show-stopper bugs like getting stuck on invisible walls. I had 2 instances where I was forced to restart the current mission because I was stuck on a wall and couldn't move. The wide variety of possible endings was another thing I found very cool. Talking to my co-workers today, the four of us who finished the game over the weekend all experienced slightly different endings. Providing the player with the ability to influence the ending like that was a very very cool move on Bioware's part, and it would be interesting to see that in more games.
Let me say I loved that game, I ended up putting in ~40 hours on my first run through as a Sentinel. Overall I enjoyed the Sentinel gameplay, it gave a good mix of tech and biotic powers that allowed a lot of flexibility when faced with a wide variety of foes. Because I was able to deal with organics, mechs and shield/armor based foes myself, I had a good amount of latitude in my teammate choices. One thing I hate is feeling forced into using certain people just because you have to cover a hole in your offensive capabilities.
I'm probably gonna play through again as a Soldier to get a feel for the game in a different play style, although I'm also pondering playing as a Vanguard. One of my co-workers played as a Vanguard and wasn't as happy with it because he felt it was a one-trick pony with biotic charge. Once you charged, you were left in the middle of a group of enemies without any cover and gimped weapons (he didn't think the shotgun was very powerful, even fully upgraded).
From a game developer point of view, I was very impressed with the game. I saw a number of small bugs, like the camera not focusing correctly or characters not appearing in the camera's view; plus a couple of show-stopper bugs like getting stuck on invisible walls. I had 2 instances where I was forced to restart the current mission because I was stuck on a wall and couldn't move. The wide variety of possible endings was another thing I found very cool. Talking to my co-workers today, the four of us who finished the game over the weekend all experienced slightly different endings. Providing the player with the ability to influence the ending like that was a very very cool move on Bioware's part, and it would be interesting to see that in more games.
Subscribe to:
Posts (Atom)