Archive for January, 2014

Global Game Jam 2014 Postmortem

Monday, January 27th, 2014

Screen Shot 2014-01-26 at 3.44.41 PMThis year’s Global Game Jam is over, and from my perspective it was a raving success. I took part with the other IGDA Twin Cities folks, as part of a relatively large team focused on making a local multiplayer game using Xbox controllers. (Click the image to read more about the project I worked on.)

The weekend began on Friday night with everyone “pitching” at least one idea for a game in front of the group. As there were about 40 people there, this took quite a while. Then people started splintering off into groups. I went into this year’s Global Game Jam with several “agendas”. (Incidentally, I probably wouldn’t recommend this for beginners, but this was my third year taking part, and at least my sixth game jam, so I felt it was okay for me to have some goals.) Here is a list of those goals, in order of importance to me, and whether or not I felt they were achieved:

  • Use Unity – Before this year’s jam, I had really only dabbled in Unity development. I’d watched a few tutorials, installed it a number of times, played around in a couple of sample projects. I went into this year’s jam with the intent of glomming on to someone else’s project who “knows” unity, so I could learn from them and hopefully make some contributions. Status: Wildly successful! I now feel like I know my way around Unity, and can at the very least make sense of projects when opening them. (This was not true before, as I had no idea where to look for things.) I could now easily make a Unity game on my own, and have some plans to do so in the not-so-distant future. All the developers on my team were experienced Unity developers, and I learned quite a bit over each of their shoulders.
  • Make a game using controllers for input – This was a secondary goal, for sure, but it turned out to be not-so-hard to find a group who had this same agenda. I have big plans for this year and multiplayer games, so I needed to have a better sense of what is easy or difficult about using controllers. Status: Definite success! I not only got a sense of how to “manually” implement controller input in Unity (watching on Friday night over Ryan Schaefer‘s shoulder), but then spent an hour or so mucking around with Patrick Hogan’s InControl project, and pretty easily got that working also. (We ended up not using it, because I had some problems initially, but I think they were local to my machine/setup.)
  • Make a “Candy Jam” game – If you haven’t heard of the Candy Jam, essentially, this is a game jam protest of King.com’s attempt to trademark the words “Candy” and “Saga”. There is a lot more information if you follow the Candy Jam link, but if anything, I think the case is not stated strongly enough. The problem is not just with King.com, the problem is with the system of trademarking as it applies to games in general. Similar to the way patents are given for too general concepts in the tech industry, trademarks on single-words are also far too general, and allowing them hurts the industry in my opinion. Anyway, I wanted to join this protest and contribute a game to the jam. Status: My teammates easily agreed, and this was a success also. (Note that we have not yet submitted the game “officially” to the Candy Jam, but that will happen soon!)
  • Design an “action” game rather than turn-based game – Designing a game definitely took a back-seat to my first two objectives for the weekend. I pitched a game idea I had on Friday, but it was pretty simple, and I’m not terribly surprised nobody seemed super excited about it. Then during the after-pitch process, I had a lot of design ideas for another “asymmetrical” multiplayer game. (4-players each with their own objectives for scoring.) I actually still think that idea has a lot of potential, but it was fairly complex. We ended up sorta waffling on what idea we were going to make, deciding we should all just get started, and work on independent “scenes” in unity. None of the games I helped make were my design, so I can’t really say this was successful. Status: Definitely thought about it, but ultimately did not achieve this.

As I mentioned, Friday night was pretty “unfocused”, but I still felt like it was worth it, because I got to learn a lot about controller input in Unity, and thus, also a lot about Unity in general. I was also instrumental in setting up version control for the project on Friday night, but I’m not sure that was a “success” really. I’ll say more about that in a bit. When I left around 4 AM on Saturday morning, there were somewhere between three and five independent “ideas” getting floated around our group, but only one (Bird Drop) had anything appearing on the screen. When I showed up again on Saturday, Bird Drop was playable, and quite fun! I spent a few hours implementing the score display, as well as the system that triggered the game over screen and restarted the game after about 10 seconds or so. Eventually, I also worked on the over-arching menu system, as well as implementing sound effects.

In addition to my personal goals, here are some bullet points about “What went right” from our team’s perspective (although this is all still “in my opinion”, I’m not speaking for the team here or anything):

  • We made a game! – Not only a game, we made (more or less) 3.5 games. There was even art for a 5th one that never got much past an empty scene in Unity. Probably more impressive, we made a menu and stuff. It really helped that Bird Drop was playable (and super fun) on Saturday, and that game got a lot of polish.
  • Bird Drop is awesome! – I think everyone, even those who never worked on it directly, can take some amount of credit for how great it was. Although of course Ryan and Bill (programmer and artist respectfully) are the ones who deserve the most accolades, as the game was truly “theirs” from the start.
  • teamwork! – I truly think we worked well as a team on this, with everyone contributing whatever they could (and often whatever was asked of them) to the overall team effort. This was a lot of people, certainly the largest group I’ve ever “jammed” with, and it was surprisingly painless. Certainly nobody tried to take over the project or had overactive egos or anything like that. A lot of credit should go to Zach, (who also organized the Jam, and runs the local IGDA chapter). He was probably the “glue” that kept the group together.

This would not be a true postmortem without some bullet points about what went wrong over the weekend:

  • Git woes – I was one of maybe two or three of us who had used Git previously, and vocally advocated for using it over SVN for version control. I set up a repository on my bitbucket account, and initially it was marked “private”, which meant that I could only invite some small number of people to it. This limitation showed up in a couple of different ways, and eventually we resolved some of the problems with it by just marking the repo as public (which I should have done from the getgo). In retrospect, one of the other git advocates had only used Github before, and I didn’t want to use that because it’s not free, but of course it is free for public repositories, so we should probably have just used that, which would have allowed him to continue using the github app (and let some of the other devs use it too). Two of our most experienced Unity devs had never used Git before, and we wasted quite a lot of time getting tortoisegit working for them. I would NOT recommend tortoisegit in general, as I still don’t know how to view “git status” using it. Totally non-intuitive to those of us who basically only use the command-line git.
  • Too much polishing on Bird Drop – This is definitely my own opinion, but I felt like we maybe spent too much time adding “juice” to Bird Drop when we could have been helping out finish up the other game modes instead. Bird Drop even ended up a bit more buggy at the end of the jam than it was on Saturday as a result. The final build we uploaded has several bugs that were introduced toward the end of the project.
  • Not enough attention to the other game modes – None of the other game modes were really playable until Sunday, and subsequently were single-developer affairs until that point. As one of two “swing” developers I should personally have made more of an effort to help those other projects get finished faster, so we could have done more iteration on them.
  • No focus on Friday – We basically didn’t even start coding until midnight on Friday.
  • Too much time spent on infrastructure – While we were unfocused on Friday, I think we spent a lot of time talking about what code each of the game modes would share, and where that code would live. One of our developers spent a lot of time on that code, and it ended up only used by one of the games. That particular developer was WIPED by the end of the project, and it’s really only because he is an absolute rockstar that he even finished that game mode.

Overall, it was a great weekend, and I had a blast. Thanks to everyone on my team, and to everyone who participated at our location!

NSNumber+XYCoordinates

Tuesday, January 21st, 2014

So I occasionally have the problem where I want to store a bunch of x,y coordinates. I have solved this a number of ways in the past, but most recently had the idea of writing a category on NSNumber that simply stores two 16 bit integers, bitshifted together. So without further ado, here’s the github project for NSNumber+XYCoordinates.

My first version of this I couldn’t get negative numbers to work, but after some patient binary math explaining today at the coffee shop from my friend Matt, I finally got it to support numbers between -32767 and 32767.

Essentially, my category just adds the following methods:

NSNumber *xyNum = [NSNumber numberWithX:10 andY:10];
int x = [xyNum xValue];
int y = [xyNum yValue];

This seems to work pretty great, and is way less annoying than my previous favorite technique, which was to convert between NSString and CGPoint all the time.

So I got to thinking tonight… this should be fast, right? But I have no idea how fast, really, or how to compare it. So I wrote some test cases. Each of them assigns and then reads back out again some number of sequential integers using various techniques that I’ve used in the past. I compiled the following lists for different numbers of values:

100 Values
CGPointToNSString – size of 100 string objects in multidimensional array is 2263 (0.002 seconds).
NSDictionary – size of 100 objects in NSDictionary is 2413 (0.001 seconds).
NSSet – size of 100 objects in set is 1545 (0.004 seconds).
NSNumber+XYCoordinates – size of 100 objects in multi-dimensional array is 2033 (0.001 seconds).

10,000 Values
CGPointToNSString – size of 10000 string objects in multidimensional array is 241803 (0.162 seconds).
NSDictionary – size of 10000 objects in NSDictionary is 289593 (0.076 seconds).
NSSet – size of 10000 objects in set is 199798 (0.044 seconds).
NSNumber+XYCoordinates – size of 10000 objects in multi-dimensional array is 203503 (0.046 seconds).

1,000,000 Values
CGPointToNSString – size of 1000000 string objects in multidimensional array is 31702088 (10.187 seconds).
NSDictionary – size of 1000000 objects in NSDictionary is 38735561 (121.886 seconds).
NSSet – size of 1000000 objects in set is 25866828 (118.003 seconds).
NSNumber+XYCoordinates – size of 1000000 objects in multi-dimensional array is 25919832 (114.918 seconds).

You see that the technique compares favorably against CGPointToNSString, at 100 and 10,000 values, but somehow, the CGPointToNSString technique just blows it out of the water in terms of speed when we get to a million objects. (Still much smaller though.) I don’t fully understand this, but I guess maybe the C API is faster at high volumes? Let me know if you think you might have some insight!

ActionGo – Quick and Dirty

Saturday, January 18th, 2014

I’m still trying to finish up Catchup, the board game conversion that I’ve been working on for literally about a year now. (Obviously not full-time.) But I decided the week before last to take a quick break from it and update DrawCade to support the new MFi controllers. That took me all of about three days, (the second update, version 2.1 that fixes some issues from the 2.0 update is now live, yay!) But most importantly, what I got out of those days was a wrapper that supports iCade style controllers (pretending to be bluetooth keyboards), as well as the new GCController style controllers. (The Moga Ace Power and Logitech Power Shell are the only two available at the time of this blog post, but the first Bluetooth one has also been announced, but is not yet available.)

Anyway, I promptly decided I MUST create a game that would use the new controllers. The obvious choice is to port Go Tetris to iOS. This has been on my TODO for a long time, calling it Action Go to match Action Chess, but the big holdup was that I have never been satisfied with touchscreen controls for Tetris. It can be done okay, but not great. I’ll of course have some “okay” controls in there, but now that there are some viable controller options, I’m super excited to get it playable, and decided it was worth putting Catchup off for a few weeks to do so.

I started the project a little over a week ago, and promptly spent a day getting some cool menu animations (using AGGeometryKit) in there. I made the following video:

Then I spent three days preparing some changes to my GDC speaker proposal. (Which still hasn’t been accepted, but also hasn’t — yet — been rejected.)

If we were counting today, this would be the 5th day I’ve worked on it. I’ve got the tetris aspects pretty much done, but the piece capturing and two-eye breaking aspects are not yet complete. That is the bulk of the code that needs to be “ported”, and consists of about 800 lines of ActionScript. I’m maybe an 8th of the way there. Ironically, I’ve got the touch-screen controls finished, but still need to shoehorn my shiny new controller class in there. I decided I wanted it to be playable first. I’m guessing it’ll be another week or so of work.