Skip to content

Unibbl is a new blog to track my progress on developing our first Unity project.

This provides many tips, flag caveats and will help anybody trying to build their first 3D adventure/platformer using Unity.

Read here: Unibbl

What’s up?

  • Unity
    Although I have a license for unity, it is only valid for Unity 3.5. Unity 4.5 is free, with some limitations.
  • Unreal
    UDK 3.5 is free but doesn’t support OS-X (this doesn’t mean you can’t target iOS). UDK 4.5 charges $19 monthly.
  • CryEngine
    I don’t see OS-X support here.

What’s hip?

There’s an engine I haven’t seen before, Minko. Cross platform, free and open source, is Minko worth a shot? Maybe. One thing that’s not very clear from their blurb is whether they mainly target HTML5 or if we can run native iOS apps (seems like the latter). Minko looks C++ centric but… okay.

One good point (from a coder point of view) may be that, in their own words “ the world editor (Minko Studio) and the 3D engine (Minko Engine) are two separate things”

Also…

See a source engine comparison on ManiacDev

With the release of our new game, Darwin’s nightmare, I am facing a simple question: how to reach players?

So, I’m putting together some resources:

Seems like we have a candidate for the first public release of our OpenGL-ES2/3 engine, O-C3D.

I set the following requirements for this library:

  • Facilitate using, but do not obfuscate, or abstract away from, OpenGL-ES.
  • Target OpenGLES-2/3
  • Support 2D/3D applications
  • Suitable for writing simple 2D/3D applications without hassle.
  • Suitable foundation for higher level APIs (e.g. scenegraph oriented).
  • Get developers started quickly without the need to dive into much documentation.

This library powers the latest release of our new iPhone/iPad game, Darwin’s nightmare (aka The Strain)

SVN repository:  https://xp-dev.com/svn/oc-es3/trunk

You can also have a look at the source without downloading the whole package.

The package includes:

  • Xcode workspace
  • Full source code
  • template/demo project

In a coming article I will explain how the demo project was setup.

This is not a Game Centre integration tutorial, but includes useful notes that can help you troubleshoot your GC integration.

Confusion about network connectivity

Some developers seem to think that the game centre sandbox is ‘local’ because GC will accept submitted scores and authenticate users while devices are offline. GC sandbox is definitely a hosted, network-enabled service. AFAIK what happens is

  • GC does not need a network to authenticate the player, i.e. the player may have logged in earlier while a network was available.
  • GC can delay submitting scores until a network is available, so it will just cache the data and return no error.
Overall I think this is good news, because it makes GC more secure. This way I don’t need to store scores locally, all scores submitted to GC are sent after a real match has been played (so that, tampering with local data isn’t enough to submit fake scores).

Issues with multiple leaderboards:

When setting up multiple leaderboards, it can take time for all the leaderboards to show in the game centre widget. This is what I observed:

  • Only the default leaderboard shows in the “leaderboards” section.
  • Even though we can make another leaderboard display in GC by configuring the widget.
  • Sometimes a leaderboard may not show up (“no data available”) when configuring the GC widget programatically BUT it may still show when browsing GC.
AFAIK the solution is, take it easy, if things feel a bit ‘clunky’ just sleep over it and it may look better when you wake up ()

Issues with opting out

After logging out of an app 3 times, it appears that a game is opted out of game centre. This rule applies to sandbox builds.

How to opt back in to continue testing? Apparently the only thing that does the trick is re-setting the settings of the test device. Inelegant maybe, but at least, it works (See the SO item here).

Caveat: After you reset the device settings, remember to log back into your WIFI network.

Quick notes for drawing point sprites:

  • Draw using GL_DRAW_POINTS
  • Call glBindTexture(GL_TEXTURE_2D,handle)
  • Attach your sampler (in simple, cases, attach it to the first texture unit / channel, “0″):
    glUniform1i(samplerSlot, 0);
  • Enable alpha blending (typically needed)
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  • in your vertex shader:
    glPointSize = X ( e.g. X = 10.0 or 60.0 )
  • In your fragment shader:
            gl_FragColor = texture2D( sampler, gl_PointCoord );
Caveats

If you forget to disable GL_BLEND after rendering your sprites, unexpected results may occur…

In ES 3.0, 2.0, you can draw lines of variable thickness. Somewhat surprisingly glLineWidth(GLfloat) is still supported. It appears that glEnable(GL_LINE_SMOOTH) is deprecated since ES 2.0; consider using MSAA (or maybe a dedicated shader) to support line antialiasing.

Caveats

  • GL-ES does not support rounded line caps. In fact, even square line caps tend to look pretty rough.
  • The range of supported line width range is limited.

Check Jay Fuerstenberg’s blog for a workaround.

If, like us, you have a rendering API based on OpenGL ES1, you should start feeling… uncomfortable. Additionally, as I accumulated knowledge about 3D rendering, I think that the design of our rendering engine is outdated.

There are not many resources out there for learning OpenGL-ES3, so I will try to track my progress on the blog.

OpenGL-ES3 is backwards compatible with OpenGL-ES2. To learn about the latter, I recommend Philip Rideout’s “iPhone 3D programming”, available online.

Migrating from OpenGL-ES1 to OpenGL-ES3 is not a trivial matter. So I will attack the problem from several angles:

  1. (Re)building an OpenGL-ES(1?)/2/3 renderer from scratch
  2. Integrating the new renderer with our game engine.
  3. Understanding OpenGL-ES2/3
A template

Apple provide an introduction to OpenGL-ES on iOS. Recent documents may require an apple ID.

In XCode, selecting new project, we find “OpenGL game”. As well as providing a stub for new OpenGL-ES applications, this doubles as an example featuring spinning, shaded cubes. As such it is comprehensive:

  • Demonstrates basic vertex and fragment shaders
  • Demonstrates how to render geometry
  • Demonstrates how to use the depth buffer
  • Demonstrates the use of basic matrix maths.
While the template is targeting ES2 – it should be forward compatible.

This is a ~400 lines program, running like this:

  • setup
    • init EAGLContext (viewDidLoad)
    • setup OpenGL
      • load shaders
        • compile a vertex shader
        • compile a fragment shader
      • link program
  • rendering loop
    • draw view (glkView: drawInRect:)
    • update

A catch with this ‘sample program’ is that finding documentation for it isn’t easy. A stack overflow item explains some of the code. Also, a you tube video introduces the template.

Ray Wenderlich describes an alternative setup on his blog.

I will not cover this template in detail here. I started refactoring the template to create a simple (yet usable) renderer.

Migration issues

Upgrading to XCode 5 is causing me headache; our setup for unit testing, migrated from XCode 4, doesn’t work.

“RunUnitTests is obsolete”

In XCode 4 (and earlier), the TEST_AFTER_BUILD flag allowed running tests after building a test target. In XCode 5 we receive the following message if the flag is set to YES:

error: RunUnitTests is obsolete. To run unit tests for your target, use the Test scheme action in the Xcode IDE and the test action in xcodebuild.

So, we have functionality that is now phased out, and we are left with concise hints regarding alternatives:

  • use the Test scheme action in the Xcode IDE
    (AND?)
  • the test action in xcodebuild.
I am assuming that it is still possible to run tests after building, and maybe the “test action in xcodebuild” has made the TEST_AFTER_BUILD flag somewhat redundant. After poking around I didn’t find anything well baked so I’m looking at XCodeBuild
Using xcodebuild to test
Looking at the man page for xcodebuild here I cooked up input to run my tests:
xcodebuild test -workspace MY_WORKSPACE.xcworkspace -scheme MY_SCHEME  -destination ‘platform=iOS Simulator,name=iPhone’
The embarrassing part here is the destination setting. In XCode 4 you could run so called “logic tests” without booting the simulator. Setting the platform key to “OS X” does not help. We get the following message:

The run destination My Mac 64–bit is not valid for Testing the scheme ‘SCHEME_NAME’.
The scheme ‘SCHEME_NAME’ contains no buildables that can be built for the SDKs supported by the run destination My Mac 64–bit. Make sure your targets all specify SDKs that are supported by this version of Xcode.

Sadly, this makes sense. We have libraries (and tests) built for iOS (checking ‘Architectures’ in build settings), so we’d have to do some (re)configuration to get this to work on OS X. The question is: how did it work before?

I can live with this for now.

Calling xcodebuild after running a build?

Pre/post-actions won’t do

Under ‘edit scheme > build ‘ (unfold it), we find ‘Pre-actions, build, post-actions’. I’m hoping that I can run xcodebuild using a post-action. While not ideal (for lack of integration with… xcode) I don’t have a better idea at the time.

It took me a while to convince myself that pre-post actions are actually being run. A comment on SO explains why:

“In Xcode 4 [and 5] you could run this script as a pre- or post-action script on the “Archive” action. However, pre- and post-action scripts are not considered part of the build itself; their output is not part of the build log, and a failing script will not cause the build to fail.”
( http://stackoverflow.com/questions/5471396/running-script-only-for-an-archive-build-in-xcode-4 )

This is no good. I don’t just want to run tests and get no output, let alone have broken tests go un-noticed – quite the opposite.

adding a build phase

So, instead of a post-action, I added a build phase: editor > add build phase > add run script build phase. XCode doesn’t hide the output of a custom build phase. Additionally, running tests as part of a build phase is actually helpful:

  • If a test fails, the custom build phase – and the build – also fail.
  • Somehow, XCode manages to open the failing test and highlight the emitting assert.

My build phase script is simple, looking like this:

cd DIR
xcodebuild -workspace MY_WORKSPACE.xcworkspace -scheme MY_SCHEME -destination ‘platform=iOS Simulator,name=iPhone’ test

where DIR is the directory containing the target workspace.

Yea that’s it. But there is a caveat. You probably can’t include this as part of the build action for the project that you are testing. This is because the test action tends to invoke the build action, causing recursive invocation of the test action and build action.

I’m guessing it could be done using an additional target in the same project. Because the project realising our app does not really contain code, what I do is add the custom build phase to that, calling xcodebuild for every library needed by the app.

Pending a merge of my related articles, I put together related info and also include interesting finds related to unit testing and setting up linkages.

Previous articles

The ‘symbol not found’ error: setting up linkages correctly

Remember that…

  • For each project
    • For each target depending on your static library
      • You need to add “mylib.a” to the “Link Binary With Libraries”

This typically includes:

  • Targets that generate an executable
  • Testing targets.

This means that you may encounter this error several times, and fix it in a variety of places. Say you have the following workspace:

  • Project MyApp
    • Target MyApp (executable) [requires Baselib.a]
    • Target MyAppTests (unit tests)  [requires Baselib.a]
  • Project FunkyStuff
    • Target MyFunkyStuff (static lib)
    • Target My FunkyStuffTests (unit tests) [requires Baselib.a]
  • Project Base
    • Target MyBase (static lib)
    • Target MyBaseTests

Assuming that FunkyStuff uses a class in Base, I have highlighted places where you probably need to add a dependency.

More linkage errors (important!)

Beyond the above, typically you have setup a workspace and sooner or later you’ll run into cases where you make a change in the library source code, but can’t see the result when running your app unless you do a full clean and rebuild (this is an awesome productivity killer) . I found two SO items that are rather helpful in this case, and they’re probably not the ones everybody’s looking at:

  • One possibility is that your libraries rebuild, but the app does not re-link. Read this SO item, here. But in short if you relate a project to libfoo.a, it’s “location” setting in inspector should be “Relative to build products”
    (and for this to work you really ought to keep your library projects in a workspace)
  • And there is an in-depth answer (notably covering the whimsical question: “Why do the library items in project not turn black, but remain red) here.
After applying changes as described in the first SO item, above, you may see warnings regarding -L paths not being found.
=> Have a look under the relevant build setting “Library Search Paths” – I seem to  find that fixing library locations generates introns in the search path, which later causes the warnings.

Setting up for unit testing

While XCode kindly creates a unit test target for you by default tests will not run when you want them to: unless you have some kind of continuous integration setup (if so, why are you even reading this post?) you want tests to run whenever-after the library is built.

I’m still wrapping my head around exactly what all the related buttons and fidgets do, in the meantime here’s a couple of things that work well:

  • Edit scheme for myLib; in Edit Scheme > Build you should see myLib and myLibTests.
    • Check the run action for myLibTests. Otherwise your tests won’t run.
    • myLib *may* be removed.
      (Not recommended – but knowing that this works, and why, is enlightening:
      look into the myLibTests target and see that myLib is under ‘target dependencies’ – the library cannot be tested before it is built, so the tests require it, ergo it is redundant as declared in your scheme )
  • Build and check messages. You can see “RunUnitTests exited without running tests…” under “TEST_AFTER_BUILD”.
    So, look for TEST_AFTER_BUILD in the test target build settings and set this to TRUE
  • If you have an app using myLib, you can ensure that tests will run (and the library will rebuild whenever needed) by adding myLibTests to the myApp scheme just like we did for myLib.
    For solo dev this is probably the most useful tweak. Assuming you bother maintaining separate projects and libs (I do)…
    - You don’t care to switch scheme whenever making a minor change to one of your static libs
    - You really want tests to run (and possibly fail) BEFORE the simulator launches.