Friday, August 12, 2011

Online Session Code for Big Objects (Plus a Warning)

In Chapter 9 of More iPhone Development, we wrote a set of classes that mimicked the behavior of GameKit's peer-to-peer connectivity, but for regular network connections (GameKit's only works with BlueTooth and local network connections). Basically, we wrote a class that lets you send and receive anything that can be packaged into an instance of NSData. Since it's relatively trivial to implement NSCoding for most classes, this means passing objects between two iOS apps (or an iOS and a Mac app) becomes pretty easy. You don't have to poll for the data, or worry about chunking out the data. You just make a method call and pass an NSData instance to send data, and then implement a delegate method for receiving data back from the other end. Life is good, right?

Hmm...

Maybe not. There's a pretty big limitation in the book's implementation. That implementation, designed for passing tiny packets of data (TicTacToe game moves), kept everything in memory. If you try to send a good size image to the other connection, likely you'd run out of memory fairly quickly.

A while back, I faced exactly that situation. For a kiosk app that MartianCraft was writing for a client, I needed to send large images shot with a DSLR camera from a Mac Cocoa program to an iPad program and also needed to send pictures taken with the iPad's camera back to the Mac Cocoa app. These images, compressed, ranged from about one to about five megs. I grabbed the OnlineSession class from More, figuring I had the network code basically done, and watched my application go down in a blaze of… well… not glory, that's for sure. Not only did the iPad run out of memory, it ran out of memory FAST… much faster than I expected. Even sending the smaller iPad camera images often caused low-memory crashes.

There were two basic problems with the OnlineSession class when you try to use it for sending larger volumes of data. First, as I said, was that it relied only on physical memory. Given that the physical limitations of the original iPad, this was problematic. But there was another, much bigger problem.

The second issue was that during the process of chunking up the data to send, the code kept making unnecessary copies of the data. Put simply, I made a n00b mistake. The mistake didn't impact the TicTacToe application because the game moves would easily fit into the send buffer, but it's a mistake I've made before and definitely should've known better.

So, what, specifically, was this mistake, you ask?

Using NSData's regular convenience constructor dataWithBytes:length: when creating the new NSData instance to store the portion of the image that won't fit into the send buffer. If you read the description of dataWithBytes:length:, it very clearly says that it makes a copy of the data you provide. So, every time a packet was sent, the code would create a new NSData instance to hold the remainder that wouldn't fit in the buffer, and it would copy all the remaining unsent data for every packet. Ouch.

So, as a simple example, if we were sending a 5 meg image, and the send buffer was set to 128k, the code would make a 4.825 meg copy after the first packet was sent, then a 4.75 meg copy after the second packet was sent, a 4.265 meg copy after the third packet, and so on. After every packet, another slightly smaller copy of the data was made. A descending progression that would eat up memory fast.

After a lot of swearing at myself, I made some modifications to the class to do two things.

First, I switched to using NSData's dataWithBytes:NoCopy:length:, which uses the provided data in place without making a copy. This kept the memory footprint a lot smaller. In some instances, because the DSLR images were so large and our app needed to send so many, I still hit memory problems. So, the second thing I did was to add filesystem caching of the outbound queue so that all the encoded objects waiting to be sent didn't have to fit in memory for the application to function properly.

The new version of the class functions exactly as the one from the book, so you should be able to just drop-in replace the OnlineSession from Chapter 9 with this one without making any changes to your application code.

You can download the new version right here.

Tuesday, July 26, 2011

Working for MartianCraft

In case you missed my tweets earlier this week, MartianCraft is looking to add a few developers. We're looking for a couple of experienced developers, and are also thinking about bringing in one or two entry-level devs without significant experience to be trained up.

Initially, the work would be project-based contracting and would start in late August. Conversion to full-time employment is a possibility, but not right away.

If you're interested in being considered, send an e-mail with relevant work experience and/or résumé/CV to work@martiancraft.com.

Thursday, July 14, 2011

Auto-Incrementing Build Numbers for Release Builds in Xcode

I use the wonderful Test Flight to distribute builds. One thing that Test Flight is a little picky about is build numbers. When you upload a build, it uses the build number to see if you're uploading a replacement or a new build. It will let you create a new build even if you don't remember to increment the build number, but it's an extra manual step, and then you end up with two builds with the same build number.

Because I'm forgetful, I wanted to automated this process. Basically, I wanted to increment the version short string any time we do an Archive and increment the bundle build ID any time we do a Release configuration build, but leave the version numbers alone on Debug builds.

Unfortunately, several of our projects are ones that we inherited or took over, so not every project uses the same version numbering scheme. How we increment 1.0b5 is different from how we increment 1.0.12, or a simple build number like 1058.

The way I deal with this is a Run Script Build Phase in my application's executable target that runs the following Ruby script (make sure you set the "shell" field to /usr/bin/ruby, and make sure the script is the last build phase in the application). Feel free to use this script if you wish and modify it to meet your needs. If you improve it, I'd be glad to incorporate improvements back into it. One item of note: the way that I differentiate between Archive builds and other Release configuration builds might be a bit fragile since I'm relying on an undocumented naming pattern in an environment variable.

Note: I'm aware of agvtool. I avoided it for two reasons. First, I wanted more control over the numbering schemes, and second, I tried using agvtool in a build script a few years back, but at that time, there were issues when you bumped the version numbers of a project that was currently open. Those issues may have been resolved, but I didn't want to fight that battle again.

def get_file_as_string(filename)
data = ''
f = File.open(filename, "r")
f.each_line do |line|
data += line
end
return data
end


def handle_alpha_beta(old_value, letter, infoplist, start_of_value, end_of_value)
parts = old_value.split(letter)
version_num = parts[0]
alpha_num = parts[1].to_i

alpha_num = alpha_num + 1
new_version = version_num.to_s + letter + alpha_num.to_s
print "Assigning new version: " + new_version + "\n"
new_key = "<string>#{new_version}</string>"

part_1 = infoplist[0, start_of_value - '<string>'.length];
part_2 = new_key
part_3 = infoplist[end_of_value + "</string>".length, infoplist.length - (end_of_value - start_of_value + (new_key.length - 1))]

new_info_plist = part_1 + part_2 + part_3
new_info_plist
end

def find_and_increment_version_number_with_key(key, infoplist)

start_of_key = infoplist.index(key)
start_of_value = infoplist.index("<string>", start_of_key) + "<string>".length
end_of_value = infoplist.index("</string>", start_of_value)
old_value = infoplist[start_of_value, end_of_value - start_of_value]

print "Old version for " + key + ": " + old_value + "\n"
print old_value.class.to_s + "\n"
old_value_int = old_value.to_i
print old_value_int.class.to_s + "\n"
if (old_value.index("a") != nil) # alpha
infoplist = handle_alpha_beta(old_value, "a", infoplist, start_of_value, end_of_value)
elsif (old_value.index("b") != nil) # beta
infoplist = handle_alpha_beta(old_value, "b", infoplist, start_of_value, end_of_value)
elsif (old_value.index(".") != nil) # release dot version
parts = old_value.split(".")
last_part = parts.last.to_i
last_part = last_part + 1
parts.delete(parts.last)

new_version = ""
first = true
parts.each do |one_part|
if (first)
first = false
else
new_version = new_version + "."
end
new_version = new_version + one_part
end
new_version = new_version.to_s + "." + last_part.to_s
print "New version: " + new_version.to_s + "\n"
new_key = "<string>#{new_version}</string>"
infoplist = "#{infoplist[0, start_of_value - '<string>'.length]}#{new_key}#{infoplist[end_of_value + '</string>'.length, infoplist.length - (end_of_value+1)]}"
elsif (old_value.to_i != nil) # straight integer build number
new_version = old_value.to_i + 1
print "New version: " + new_version.to_s + "\n"
new_key = "<string>#{new_version}</string>"

part_1 = infoplist[0, start_of_value - '<string>'.length]
part_2 = new_key
part_3 = infoplist[end_of_value + "</string>".length, infoplist.length - (end_of_value+1)]
infoplist = part_1 + part_2 + part_3
end
infoplist
end



config = ENV['CONFIGURATION'].upcase
config_build_dir = ENV['CONFIGURATION_BUILD_DIR']

archive_action = false
if (config_build_dir.include?("ArchiveIntermediates"))
archive_action = true
end

print "Archive: " + archive_action.to_s + "\n"


print config

if (config == "RELEASE")
print " incrementing build numbers\n"
project_dir = ENV['PROJECT_DIR']
infoplist_file = ENV['INFOPLIST_FILE']
plist_filename = "#{project_dir}/#{infoplist_file}"

infoplist = get_file_as_string(plist_filename)
infoplist = find_and_increment_version_number_with_key("CFBundleVersion", infoplist)
if (archive_action)
infoplist = find_and_increment_version_number_with_key("CFBundleShortVersionString", infoplist)
end
File.open(plist_filename, 'w') {|f| f.write(infoplist) }
else
print " not incrementing build numbers"
end

Thursday, July 7, 2011

Happenings and Prospects

I apologize for the relative dearth of posts here since WWDC. That week in San Francisco always tends to backlog me pretty badly (I returned from WWDC at inbox 1138 - and that's after spending the return flight answering e-mails), so I've been pretty much heads down on work-related stuff ever since. I've also, at the same time, been consciously trying to back away from the 12-15 hour days, 7 days a week schedule that I'd fallen into trying to help get MartianCraft off the ground. Those two have conspired to give me very little time for writing lately, but I think things are under control now.

I've got my semi-mythical OpenGL ES from the Ground Up 10th installment on skeletal animation nearly finished and hope to have it posted within the next couple of weeks, and it's bit of a doozy. My goal with this post is to make one of the more intimidating topics in graphics programming approachable. Fingers crossed, it's been a challenge making this topic approachable, but I think I'm getting there.

A few other bits of news.

First, work has officially started on Beginning iPhone 5 Development. Yes, I know it probably should be called Beginning iOS 5 Development, but as of right now, we're sticking with the naming sequence Apress established with the first book. Dave, Jack, and I have already started updating the book for Xcode 4, ARC, Storyboards, and all the other cool new stuff and are hoping to have the book ready to go to press when the GM version of iOS 5 ships this fall.

Second, I purchased a new domain today. There's nothing there yet, but OpenGLESBook.com is now mine, and I have big plans for it. Once Beginning iPhone 5 Development is in the can, I'm going to revisit my partially written OpenGL ES 2.0 book. I plan to revise it to use GLKit and to add material about the very cool new OpenGL ES tools we're getting with iOS 5.

As of right now, my plan is to self-publish. I'm still researching the exact process, tools, and services that I'll use, but my plan is to sell the book without DRM and at a reasonable price. I'd like to have an early access program, however since a lot of the material I'll be covering will be under NDA until iOS 5 goes GM, I can't promise that at this time.

Update on UpdateConf

Just wanted to let you know that I'm speaking at another conference. I'll be speaking at the inaugural UpdateConf in Brighton, UK on September 5th.

As part of the conference, I'm also giving a two-day intensive workshop on OpenGL ES. The workshop assumes no prior experience with graphics program, but will be fairly fast-paced and will cover a lot of ground because there's a lot of new ground to cover. I'll be going over the new GLKit and the incredible new OpenGL debugger as well as the updated OpenGL ES Instruments templates.

 Not interested in OpenGL ES? There are four other two-day workshops going on with some really awesome instructors. Marcus Zarra is doing a two-day workshop on Core Data, Drew McCormack is doing a workshop on Core Animation, Sarah Parmenter is doing one on iOS UI design, and Remy Sharp is doing one on HTML5 for mobile. The worst thing about giving this workshop is that doing so will prevent me from going to one of the other great workshops.

The conference proper has a number of speakers, including the workshop instructors and it's really shaping up to to be quite a conference, and also quite a steal at £99 for early bird tickets to the conference (the workshops are extra). You can sign up for the conference on EventBrite.

 Hope to see you there!

Saturday, June 4, 2011

On Being Excellent to Each Other

Marcus Zarra has a somewhat depressing post today on the excellent Cocoa is My Girlfriend blog. It's about the release of The Daily. Because of all the secrecy around The Daily prior to its official launch, I think not a lot of people knew Marcus was not just involved with it, but was actually leading much of the development effort.

I knew.

I wasn't on the main development team for The Daily, but I did most of implementation work on a single component (the 360° panorama). I wasn't in NYC every day the way Marcus was, but I went down there enough to know the conditions under which the application was written. I saw the endless late nights (actually, it was usually early mornings) and the stress and difficulties under which the app was written.

A personal stake always makes it harder to watch negative publicity. The Daily's launch was especially hard because I was in a position where I couldn't really come to Marcus' team's defense, since my involvement with the project wasn't yet public knowledge. If it had been, I would have been written off as biased.

So, I had to just sit back and watch it the way you'd watch a trainwreck. It was painful watching the snark. It was painful watching Loren Brichter, a well-respected member of our community put together a carousel demo in a complete vacuum and post a video of it as if it proved something about performance in an incredibly large and complex application. It was even more painful seeing John Gruber link to that video, spreading a false impression to a far wider audience.

They both enough about software development that they should have known better. There's almost no part of The Daily that can't be re-implemented in a few hours as a standalone application using static data and with great performance.

Doing the same thing as part of a large development application developed by a large team, working with a larger management team and a huge content and production teams under an unreasonable deadline and constant pressure? That takes more than being a competent developer. A lot more. It takes patience and diplomacy and a very high tolerance for frustration. I don't think I would've survived in Marcus' shoes all those months. I would've walked out or been escorted out long before the launch ever happened. It was honestly that tough.

I'm not sure that our community is getting quite as bad as it appears to Marcus at the moment, but there is no doubt that we are capable of producing our share of snark. And let's be honest… I am capable of producing more than my individual share. I don't think we think about being mean when we fire off a smug comment. I think it's usually just a side effect of expressing a myopic, partially informed opinion. I'm sure Loren honestly believes he could have done better with the carousel had he been working on The Daily. But he's wrong. He just doesn't know enough about the situation to realize it.

But it's not my intention to point fingers here. I'm been just as guilty at times. Last year, during the WWDC keynote, I was extraordinarily snarky about the Farmville demo, completely forgetting that I know people who worked on it. I wasn't intending to shit on their work, but I did, and I'm sincerely sorry about it. There have been other examples. I hope there won't be more in the future, but only time will tell.

I think Marcus' post should be read and taken to heart by all of us. I think it should serve as a reminder that real people — very often our friends and colleagues — are behind the software and hardware that we express opinions on. We should keep in mind that a lot of work went into it. We should also keep in mind that in most cases, we have no idea the circumstances under which the application was written.

Being critical is not only fine, but a necessary part of driving each other to be better developers. But we should try and avoid being a dick about it. It can be done respectfully, and should be.

I promise to try if you will.

Friday, June 3, 2011

Thoughts on Unity3D

As I stated in my previous post on 3D engines, I'm going to do four blog posts giving my thoughts on each of the four engines that I looked into using for a project recently. Those four engines are Unity3D, Sio2, Ogre3D, and Cocos3D. I'm starting with Unity3D, which we selected for one of our recent projects.

Now, let me state up front, that all four of these are competent engines and I could see situations where I would recommend three of the four engines for client projects and could easily imagine situations where all four of them would be good choices.These four do not make an exhaustive list; there are other engines out there, including some really good ones, but these were the four that we looked at for this specific project. As much as I like the UDK, for example, I don't like it enough to spend quality time in Windows, so that one is off the table for me until the fine folks at Epic decide to port their dev and content tools to the Mac.

Unity Overview

Unity3D actually predates the iPhone, and of the four engines, it's the one that feels the most mature and has the most robust developer tools. It also has one of the most active developer communities. Unity3D is a closed-source commercial product that you must pay for, which might be a turn-off for some, but it is worth every penny of the license fee.

Unity Pros

Unity is actually fairly easy to learn, yet has a feature set that is compares favorably to most other engines. Unity's asset pipeline is really robust and their tools give you the ability to very quickly make changes and test those changes.

One of the best things about Unity3D is the fact that it supports both Windows and Mac OS equally as development platforms. Regardless of which platform you develop on, you can generate games that runs on every platform Unity supports (assuming you're licensed for it). You can even have part of your team developing on Macs and the other part on Windows with no problems.

At the time I'm writing this, it is possible to generate games from Unity that run on Mac OS X and Windows (both native apps as well as games playable through a web plug-in), iOS, Android, Wii, Xbox 360, and PS3. The Unity folks are also actively working on adding Linux support. Console licenses are negotiated on an individual basis and are likely quite expensive, but it's nice to have the option to take a successful game to so many platforms without having to do a full port each time.

Having had to port OpenGL ES apps from iOS to Android more than once (which is no fun), I can honestly state that the Android support should be a huge selling point you're giving any thought to supporting both iOS and Android.

Unity Cons

The downsides to Unity3D are relatively few, actually.It is the most expensive of the engines I looked at, and the costs are completely front-loaded. You pay a flat per-developer license per platform up front, but then you can create as many games as you want for the platforms you're licensed for. For the basic iOS license, it's $400 per seat (one developer using up to two machines), for the Pro license, you're looking at $3,000 (because the $1,500 iOS Pro requires the $1,500 Unity Pro), which might sound like a lot of money, but it's really a pittance compared to the amount of development time it can save you. The "Basic" version of Unity, which allows you to generate Mac, Windows, and Web games (though excludes some of the more advanced features) is available completely free of charge.

The other potential downside in some situations is that the underlying C++ source code is not available. You work primarily in either JavaScript or C# (MonoScript) and at a higher level of abstraction. Unity supports a few other languages besides Javascript and C#, but only those two languages work for mobile development.

After about two weeks of spending my evenings with Unity, I actually came to the conclusion that not having access to the source isn't really much of a drawback, and for many developers, working this way will be better than working in C++. The engine takes care of almost all the low-level stuff you'd need to do, but even if it doesn't, Unity has a shader language that lets you write code that runs on the GPU and anything that needs to run on the CPU can be done by scripting inside Unity.

Although the programming in Unity3D is done with scripting languages, the scripts you write are actually compiled, so there's not a huge performance overhead to using them. In the exceedingly rare situation where C# or Javascript isn't sufficient, it is possible to send messages into and out of Unity from your application's C or Objective-C code.

Learning Curve

I found Unity surprisingly easy to learn. There are some really good resources out there, including lots of tutorials and instructional videos. I actually had a game functioning after about two hours of playing. It was ugly and the game mechanics were simple, but it was playable. Unity also has a fairly active developer community forum where you can go and get help when you get stuck.

If you don't already know something about graphics programming, you still don't need to be too scared or intimidated. Most of the gnarly stuff is squirreled away where you won't see it until you need it, and you can do a surprising amount by just configuring things in the development GUI. You can create, for example, a fairly full-featured physics simulations without ever writing a line of code. Want to stack up a bunch of crates and roll a ball into them and watch them all fall? You can do it without ever opening a text editor. Heck, you can even do that without opening a 3D program.

Complexity

I was scared of one thing going into learning Unity: I was concerned that because it was so easy (at least I had heard it was), that it was going to be a dumbed down game maker that sacrificed more advanced features for the sake of lowering the obstacles to entry. My fears were completely misplaced, though. That's not the case at all. The Unity folks have done a really great job of making their tools easy to use while still giving you the ability to do most anything you'd ever need to do. It's even possible (though the process is a bit convoluted) to integrate UIKit and Unity3D within the same application.

Asset Pipeline

The thing that actually impressed me most about Unity is what they call their "asset pipeline", which is the process by which you get 3d models, textures, and other assets into your game. If you've ever developed a game or game mod for the UDK, a Valve Source game, or other commercial engine, usually there's kind of a convoluted process you have to go through to get your game assets including characters, textures, props, and environments, into the game. You usually have to use separate applications to specify shaders and physics options, sometimes write a compile script or other text document to define certain trains, and then compile the object and package it all up into some kind of bundle or package. While developing a single mod, you typically iterate through this process many, many times. It can be a bit tedious and hard to learn and usually requires the use of multiple tools and lots of trial and error.

Unity bypasses almost all of this tedium. When you save your assets from your 3D program or Photoshop, you simply save them in your Unity project's Assets folder. When you launch Unity, or navigate back to it if it's already open, Unity detects the new file, or any changes you've made to an existing file. It imports it and adds it to the list of available assets.Anything you need to do that can't be done in your 3D program, such as specify a shader or identify the physics engine properties for the object, you do right in Unity, and most of that can be done without writing code (though everything you can configure without code can also be changed from code).

Which 3D program do you need to use? Pretty much any one you're comfortable with. Unity3D has direct import support for the native file formats from several programs including Blender , but any package that can export to Autodesk FBX or Collada can be used with full support for all features like bones, textures, animations, etc.It also supports native Photoshop files (.psd) for textures, flattening layers in a non-destructive manner when you build your app.Assets can even be given different characteristics for different platforms. You could have, for example, a 2048x2048 texture asset for the desktop version of your game but tell Unity to use a 1024x1024 version for game consoles and a 512x512 version on iOS and Android.

The Bottom Line

As I stated earlier, there are situations where I could see any of the four engines I looked at being a good choice, as could many of the other engines I didn't look at. But, honestly, if I had to make an engine decision without detailed information, Unity3D would be my first recommendation. The tools are solid, the company and community support is awesome, it supports many platforms, and getting assets into your game couldn't be easier. It's relatively easy to start using for both experienced developers and those who aren't.

A good, experienced graphics programmer working in mobile right now can easily ask $200 per hour or more because the demand far outstrips the supply. Figure it out. Unity's full iOS license is basically the equivalent of 15 hours of a graphics programmer's time. Yet, Unity will easily cut five times that many hours off of any decent size software game project's schedule, probably a lot more.

I'm giving Unity3D two big thumbs up. I'm using it on a project now and hope to use it on many more in the future because it's fun to use and removes much of the tedium associated with 3D programming without removing power.


1 Many of the more advanced features require the more expensive "Pro" license, however, and really cutting edge features from the latest games generally take a little while to show up in the tools

Wednesday, May 25, 2011

A Few Seats Left

There are a few seats left for the afternoon trip to Cupertino on June 6th. If you're interested, go here.

As I write this, there are less than 15 seats, though, so if you want one, I suggest you hurry.

Saturday, May 21, 2011

Bus Update

Just to let you all know, we're down to eleven remaining available seats on the third and last bus, and they're about equally split between morning and afternoon. If you missed getting a seat on the first two buses, and haven't filled out the interest form for the third, there probably won't be a seat. So, go here now to tell us you're interested in one of the remaining seats. Speak now or forever hold your peace.

Thursday, May 19, 2011

Pre-WWDC Schedule Update

The good news:

The additional bus is a go! We'll be opening up payment for those seats this weekend to people who signed the interest form, and then opening it up to the public 24 hours later until seats are gone. The third bus will leave Moscone a bit later than the other two (11:30 and 3:45), but will not stop at SFO. If you're interested in the additional bus, but need to be picked up at SFO, drop me an e-mail (jeff at martiancraft dot com) or send me a tweet, and we'll see if we can find a way to accommodate you by shuffling a few seats. Update: The third bus will stop at SFO!.

The bad news:

There will not be another bus once we fill this one. We're already threatening to overflow both The Company Store and BJ's, a fourth bus would be overkill even if we were sure we could fill it, which I'm not at all sure we could do anyway.As of right now, there are approximately 25 spaces left on the third and final bus.

The interest form will remain open until we either run out of seats, or we open up the reservation payment again. People who signed up on interest form get dibs on the remaining seats.One final note: last year, we had some people show up without signing up in advance. Please don't do that this year. Simply put, we won't have any place to put you. The bus company won't let people stand while the bus is driving, so if you're interested in going, you've got to reverse a seat in advance.

Wednesday, May 18, 2011

Pre-WWDC 2011 Pilgrimage Additional Buses

Okay, here's the deal folks. We're trying to find out from the bus company what are options are. In the meantime, we need to know how many of you are interested in a seat on the bus. If you want to go, and didn't get a seat, you need to go fill out this form right now. If we get enough interest to cover the cost of another bus, we'll then send you all information on how to pay for your seats. Spread the word, because we really don't want anybody to get left behind if at all possible.

Tuesday, May 17, 2011

Sold Out

Okay, I'm just about to head to bed, but wanted to let you know that we've officially sold out all four bus trips for the June 5 pilgrimage. Scott and I are going to regroup in the morning and see what our options are for adding capacity. Because we have to pay for buses by the day and not per trip, we have to be sure we can fill two more bus trips in order to cover the cost of adding an additional bus. We're also going to see if adding a smaller bus is a possibility and how that would impact the per-seat price. Whatever we do, I'll post about it here and also tweet it. But not until tomorrow. G'night.

Pre-WWDC Pilgrimage 2011 Update

If you signed the interest form, you should have received an e-mail telling you how to reserve seats on the pilgrimage buses. If you did sign the earlier form but didn't get an e-mail, let me know. If you didn't sign the interest sheet, don't worry, we'll be opening registration up to the public tomorrow. We thought it only fair to give the people who signed up in advance a bit of a head start. We should have enough room for everybody, as we're able to add additional buses if we need more capacity. We just have to make sure that we have enough additional people to cover the cost of another bus. Keep an eye here or follow me on twitter to find out when we open registration up to everyone else.

Saturday, May 14, 2011

3D Game and Graphics Engines

One thing that I get asked about a lot is whether you should use a game or graphics engine instead of learning OpenGL ES. Often, these emails are prefaced by a statement about how hard graphics programming. I've had to answer this question enough times now that it seems like a good topic for a blog post.

Honestly, I find it kind of hard to answer, because I don't see the "using an engine" and "learning graphics programming" as being distinct or mutually exclusive approaches. While a good game or graphics engine will handle a lot of the more gnarly programming tasks for you and shorten your development time, you still need to understand the underlying concepts to build anything of any complexity.

All of these engines are built on top of OpenGL (and/or DirectX if they support Windows), and are subject to the same limitations and strengths. Not understanding, at least at some level, how these lower-level graphics libraries work and the basic maths of 3D programming will eventually hold you back.

But… that doesn't necessarily mean you need to learn OpenGL before you can start using these tools effectively. You don't. It's just that some of the difficult, sticky math and concepts that might be scaring you away from OpenGL are still there (though better hidden), and you may well still have to deal with them at some point if you're doing the coding on the game (as opposed to just creating assets or doing level design).

Here's kind of a simple nutshell rule:

If you love graphics programming or are fascinated by it, then study OpenGL ES and the underlying maths and forget about using the engines at first (though studying their source is a great way to learn). There's always going to be work for good graphics programmers and you can't put a price tag on doing what you love.

If, on the other hand, your goal is to make a game or other graphics-heavy application, and graphics programming is just a means to that end, then use an engine, because it will shorten the amount of work you have to do tremendously, which inherently increases your chances of making money because time is money and there's never enough of it.

So, when shouldn't you use an existing engine if your goal is to make a game and not to try and be the next John Carmack? Almost never. Rolling your own game engine should be a labor of love. It's got to be an itch you can't scratch; the kind of desire that I probably couldn't talk you out of anyway. Otherwise, it's just a waste of your time.

What about when there just isn't an engine that works for what you want to do?

Honestly, that's not all that likely in this day and age, but even if it is, you're far better off starting with an existing engine and then modifying it to meet your needs.

From a business and financial perspective, it's almost never better to start from scratch. Even many of the AAA commercial game engines are derivatives of other engines. To give an example: Valve's Source Engine, is derived from their older Goldsource Engine, which itself was forked from the Quake Engine back around 1996.

Though there are quite a few game engines around, a very large percentage of high-end commercial games, both console and PC, are based on either the Unreal engine or the Quake engine or one of their derivatives. If you throw in a handful of other engines, like the CryEngine, you've probably covered all but a few outliers.

If it's not cost effective for large, multi-person development teams with multi-million dollar budgets to develop their own game engines, it's probably not the best choice for individual indie developers or small shops.

So, don't reinvent the wheel. Use an engine and stand on the shoulders of John Carmack and others like him. Don't spend your time trying to solve problems that are long-solved. Just be aware that using an engine can't completely eliminate the need to learn a little math or to understand the underlying concepts.

Engines

It just so happens that for a number of proposals I've done lately, I've been looking at game engines in some depth. I'm not going to do "reviews" per se, but over the next few weeks, I will try and post my thoughts about several of the engines available for iOS, including Unity3D, Sio2, Ogre3D, and Cocos3D.

I won't be discussing the UDK, even though it's a phenomenal engine, because it requires using Windows for many tasks, and I don't want to spend time in Windows. If you've got both a Mac and a Windows machine, however, and don't mind splitting time between OS X and Windows, you might want to check it out. A lot of time and brainpower has gone into getting the UDK to have incredible performance on iOS and the license terms have been changed to be much more friendly to small indie shops ($99 plus 25% of royalties after the first $50,000).

Wednesday, May 4, 2011

Empty OpenGL ES Application Xcode 4 Template

Jacques De Schepper sent in an updated version of my old Empty OpenGL ES Application Template, updated to use Xcode 4's completely revamped templating mechanism. You can download the new Xcode 4 version of the template right here. I haven't had a chance yet to test this out, but once I do, I'll also add it to GitHub. Thanks, Jacques!

Tuesday, May 3, 2011

Bus Trip Update

Just wanted to give you all an update on the bus pilgrimage to Cupertino on June 5th. We had a tremendous show of interest. Approximately 300 people expressed an interest, plus several people tweeted and e-mailed after the interest form was closed down. Last year, we took 100 people.

Scott Knaster is investigating bus options, including a possible bus directly from SFO to the Apple Store and then up to WWDC for people who wouldn't be able to get up to San Francisco in time for the bus.

We'll start the official signups the middle of this month, once all the arrangements are squared away and we know how many seats there will be. Once the arrangements are made, the seats will be made available on a first-come, first-served basis. If you filled out the interest form, you'll get an e-mail with details of how to reserve your seat and pay for it as soon as signup opens. If you didn't fill out the interest form, you probably want to follow me or Scott on Twitter, as we'll tweet when the signups start and then periodically re-tweet until the seats are gone.

I want to set expectations, especially for first timers. The only thing open at Apple HQ will be The Company Store, which is similar to an Apple Store, but with a lot of Apple schwag and paraphernalia (t-shirts, pens, mugs, sweatshirts, etc). Being not just a Sunday, but the Sunday before WWDC, don't expect to see many Apple employees coming and going, and you will definitely not be able to get into the quad (the inside portion of One Infinite Loop). There is no official Apple recognition of this trip, and we don't have any expectation that there will be.

In the parking lot near The Company Store, there is a restaurant called BJ's, affectionately referred to as "IL7" by Apple employees (the buildings at One Infinite Loop are named IL1 through IL6), which is fairly good for what it is. You can have lunch or a drink there, but if you do, I advise you to order quickly and have your check brought with your food. Since the same bus will be used for multiple trips, we won't be able to wait for stragglers. The bus will leave at the scheduled departure time with or without you. We didn't leave anybody behind last year, but we had one table that cut it awfully, awfully close. It's an awfully long damn walk back to San Francisco, and they get pretty busy on Sundays even without a bus full of additional customers.

Lastly, if you see Scott on Sunday, make sure to say a big thank you to him. Scott has done nearly all of the legwork again this year and the trip is happening very much because of him, so thanks Scott!

 
Design by Wordpress Theme | Bloggerized by Free Blogger Templates | coupon codes