Sunday, April 19, 2009

Dropping a Dimension: Cocos2D and Box2D on iPhone

Over Easter I decided to drop a dimension in my iPhone project to go from a 3D evolution game simulator to 2D.

I started out playing with the Chipmunk physics engine, just out of curiosity. I watched some videos of the engine in action, read the forums and downloaded the code base and example moon buggy project. The code comes with an Xcode project and the 8 demos make working with the engine look easy.

I started playing around with cocos2d for the iphone because it came with Chipmunk already ported. I hacked on the chipmunk demos (also ported to cocos2d) and found the lack of OO-design frustrating and the speed terrible, even after reading tweaks from the cocos2d forum and blog.

I kept seeing references to the Box2d physics engine (elements of which Chipmunk is based) and eventually dropped what I was working on and grabbed a copy of the code base. The code also had an Xcode project and I was impressed by the number and variety of demos. I dug deeper and came across the box2d port to iphone donated by Simon Oliver who built Rolando using Box2D. I graped the port from the box2D SVN server and started developing my game. I started fleshing out a basic game engine with physics and rendering call backs each frame, tweaked based on some game tutorial screencasts on 71^2.

The speed of the demos was still not good enough, but the object-oriented design sat right and I assumed I could optimize my application into submission (I have so far). While googling fixes for the issues and questions I was having in my basic game engine I kept coming back to the cocos2d forums and codebase. It was obvious that cocos2d had already solved the problem of a simple game engine, and then some.

I was decided. The rapid progress I was able to affect in 2D with both chipmunk and box2d as well as the ready-to-exploit and well documented cocos2d game engine convinced me.

The following is the dead-simple procedure I wrote down for manually integrating the box2D physics engine into the cocos2d game engine for the iPhone:

  1. Check-out cocos2d-iphone from SVN. This is because the downloadable archive from the site does not allow one to decouple Chipmunk as easily.
  2. Check-out box2d physics engine from SVN. This is because the downloadable archive is outdated and does not include the iPhone port (and subsequent changes to the codebase?).
  3. Create a new Xcode project for cocos2d based on Monocle Studios - Introduction to Cocos2d iPhone Whitepaper. I only included the cocos2d directory (no Chipmunk for example), and I tweaked a few things a long the way (OpenGL-based project as a starting point, names of things, etc).
  4. Because Chipmunk is no longer in my codebase I used the new replacement macros whenever the old Chipmunk macros were referred to (such as in forum posts and in the new cocos2d project tutorial in the previous step).
  5. Add the box2d source to the project, specifically the 'include' and 'sources' directories.
  6. The first build had some compile issues (a 'FALSE' rather than a 'false' and missing ';') that required minor fixes.
  7. The first thing I did was create a custom Box2D cocos2d layer that ran the physics engine and generated a basic world with cute 2-box creature (big box with a little box flipper).
  8. I used the rendering code listed in the box2D iPhone port (GLES-Render.mm) for drawing shapes, segments and points, and used the debug-drawing engine in the box2D core (b2World.cpp) as the basis for traversing world elements for drawing each frame. I considered using the cocos2d primitives (ChipmunkDemo/main.m) as is done in the ported Chipmunk examples, but I figured I am going to need custom drawing routines anyway, so the simple custom OpenGL drawing routines were a good base. I also ripped the mouse/touch code from the iPhone port of Box2D which works great.
  9. I had some initial problems importing Box2D.h into my Objective-C++ header files. The solution was simple enough, involving #ifdef __cplusplus/#endif around the cpp header.
  10. Finally, when compiling for iPhone hardware I had some additional errors in Box2D ('finite' was not declared in this scope), that were easily fixed.
I'm sure there are easier/better ways to get up and running with Box2D in cocos2d-iPhone (tell me please!) and millage may vary as the code bases change (I checked out the working copies of each project), although it has worked well enough for me thus far. If there is sufficient demand, I'll create an opensource project with the bare-bones project, or even just open up my current codebase. Let me know.

I'm currently struggling with the fabled "codesign failed with exit code 1" while trying to push my application to my iPhone device, specifically "object file format invalid or unsuitable". I've dropped 6 hours into this problem already and am still nowhere, although I'm reasonably sure it is not project specific. I will get there, but it is so damn frustrating!

Reading has turned up an array of interesting snippets. Cocos2d game engine was originally written in Python and ported to Objective-C for the iPhone. Notes on Cocos2d iPhone Development provide a great intro to cocos2d and specifically the arrangement of scenes, layers and nodes. Box2D has been ported all over the place including to Flash, and there are lots of useful box2d-flash related posts that are directly useful (like this lot that helped me figure out Revolute Joints). I have also seen lots of discussion about tuning box2d for performance (like 1m bodies are the sweet spot) and interesting physics engine comparisons and speed tests.

My current plan is to continue to realize the procedural creature generation and evolutionary engine for my project in 2D and play-test the hell out of it. If something fun drops out I will polish and push it to the app store and/or consider a port to 3D. The raw computation required for any meaningful morphology/controller evolutionary process is still my biggest technical risk. I am still not convinced it is viable on this hardware. I've got some thoughts regarding work-arounds (pre-evaluated strata in the search space, amazon EC2 compute servers, etc), although I am also thinking about a creature app without evolution.

Sunday, April 5, 2009

Oolong Engine for the iPhone: A First Look

I set a side some time this weekend to have a look at the Oolong Engine for the iPhone and one thing is clear - it is the domain of the graphics programmer, hardcore or otherwise (note: not me).

The project started as a side project by Wolfgang Engel exploring graphics programming on the iPhone and iPod Touch, seemingly initiated in late 2007. The project went by the name iGDK (the iPhone Game Development Kit), was located on google code, and got some early attention given that the official iPhone SDK was at that time unreleased. Still in late 2007, Wolfgang renamed the project to the Oolong Engine, seemingly changed the license agreement to the MIT License and created the still current google code project and public facing website. A mailing list followed soon after and is now the primarily means of support containing almost 12 months of user interest discussions.

The main form of documentation for the project is Wolfgang's blog entitled "Diary of a Graphics Programmer", that details (among other things) insight into his progress on the project as a free-time exercise, as well as a series of (at last count) 9 iPhone programming tips released at then end of 2008 (approximately one year after the project was initiated).

For completeness, the following list the Oolong related posts from the blog:

Interpreted as an attempt at induction for programmers new to the platform and his engine, Wolfgang's wrote a series of iPhone and iPod Touch (iP*) programming tips from November 2008 to January 2009. Wolfgang's contribution in the Quake III Arena port to the iPhone shines through in some of these articles.
From the blog posts and news entries on the projects webpage, one may deduce that the Wolfgang's contributions to the project peaked early to mid 2008 (around the launch and resultant integration with the iPhone 2.0 SDK) and have simmered down since, except for an interest in VFP and the writing of programming tips over the 2008 Christmas period. The google project also lists Erwin Coumans from the Bullet Physics project as a second project owner, and there are number of additional members listed as contributing to the effort.

Oolong is the side project and domain of serious graphics and game physics programmers, and as such code is what this project is all about.

The project incorporates a number of sister open source projects and offers a suite of example projects. There is no documentation provided with the project other than some out-dated and vapid readme files for the examples and some reasonable in-line comments littered throughout the examples and the core engine code.

The leveraged third-party open source projects that were listed (or that I could deduce) and integrated into the code base are as follows:
  • Bullet Physics (2.73), for 3D physics simulation
  • Memory Manager, apparently by Fluid Studios although seemingly previously listed on Flip Code
  • IPROF, A Portable Industrial-Strength Interactive Profiler for C++ and C, by Sean Barrett
  • enet, the network subsystem used in cube
  • VFP math library (also by Wolfgang Engel) offering math functions in iPhone-friendly ASM
  • OpenAL sound engine/wrapper, (?)
The /Examples directory offers a number of discrete example Xcode projects logically grouped into sub-directories. Many of the examples worked for me (in the iPhone Simulator), although some failed to demonstrate their intended feature, some black-screened (is that a thing?), and a number crashed (specifically the 10 Ported PowerVR Examples under the Renderer directory). Initially I thought that the 10 'Ported PowerVR Examples' were a direct porting of the 10 Imagination Technologies Khronos OpenGL ES 1.x SDK for POWERVR MBX examples, although this may not be the case given the the names of the examples do not clearly align.

Given my newness to the platform, I am unsure whether the failing example projects were an artifact of the 'project in flux' or my iPhone SDK that was hacked to run on my PPC iBook G4 (yep, non-Intel). Additionally, the PowerVR Examples use code optimized for the iPhone hardware and so may need to be deployed to the device for execution. Given that I tested the examples in the simulator, this is a third possible cause for the examples that crashed out.

I am in no position to assess the efficiency of the engines rendering pipeline, but I bet it is smokingly fast relative to competing engines. What is clear to me is that the engine is bare-bones, requiring the programmer to do a lot of work to realize the (in principle) simplest 3D scenes. I am not a graphics programmer and I've been spoiled recently by frameworks in other domains that have delivered big wins with modest effort. I'm not giving up, but I want to hedge my engine betting. My next objective is to assess SIO2 and see what it can offer in terms of a more scripted (ready to write game code) solution.