Running Native Code on Android – Part 2

Original Author: Gustavo Samour

In the first part of this series, I mentioned a way to call C/C++ code from Java, and viceversa, on the Android platform. That method allows you to run performance-critical native code inside a Java-based Android project. Now I’ll show you a way to create an Android app without writing a single line of Java code.

The API level 9. This means you can only run them on devices with Gingerbread or greater (Android 2.3+).

How-To

There are actually two ways we can create a native activity. The first is to start with a blank slate and write all of the code to initialize and update the activity. The other is to use the “glue” code provided in the NDK. This code defines several important enums and callbacks. I don’t want to reinvent the wheel right now, so I’ll use the second approach.

To use the NDK glue code, you’ll need to add it to your Android.mk file. You can either use it as a static library, by importing the module from its current location (android-ndk/sources/android/native_app_glue), or you can copy-paste the source files to your project’s jni subfolder. Here’s my Android.mk file:

LOCAL_PATH := $(call my-dir)
 
  include $(CLEAR_VARS)
 
  LOCAL_MODULE := NativeActivitySimpleExample
 
  LOCAL_SRC_FILES := main.cpp
 
  LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
 
  LOCAL_STATIC_LIBRARIES := android_native_app_glue
 
  include $(BUILD_SHARED_LIBRARY)
 
  $(call import-module,android/native_app_glue)

 

Native Activity Hello World

Once we have the makefile, it’s time to create a main source file.

#include <android/log.h>
 
  #include <android_native_app_glue.h>
 
  #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "NativeActivitySimpleExample", __VA_ARGS__))
 
   
 
  void android_main(struct android_app* state)
 
  {
 
     while(1)
 
     {
 
        LOGI("Tick!");
 
     }
 
  }

The native activity’s main entry point is “ANativeActivity_onCreate()”, which is implemented in the glue code. After initialization, it calls “android_main()”, which you can think of as your own entry point. If you build this code, you’ll get a nice libNativeActivitySimpleExample.so file.

At this point you’re probably wondering, how will Android know it should run my native code, instead of looking for a normal Activity class? This is handled inside the AndroidManifest.xml file. As usual, you declare the properties of your activity with an <activity> tag. But inside it, we’ll pass along some metadata to reference our C/C++ library. Here is what my AndroidManifest.xml looks like:

<?xml version="1.0" encoding="utf-8"?>
 
  package="com.gsamour.adbad" android:versionCode="1" android:versionName="1.0" >
 
     <uses-sdk android:minSdkVersion="10" />
 
     <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" >
 
        <!-- Our activity is the built-in NativeActivity framework class. This will take care of integrating with our NDK code. -->
 
        <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
 
           <!-- Tell NativeActivity the name of or .so -->
 
           <meta-data android:name="android.app.lib_name" android:value="NativeActivitySimpleExample" />
 
           <intent-filter>
 
              <action android:name="android.intent.action.MAIN" />
 
              <category android:name="android.intent.category.LAUNCHER" />
 
           </intent-filter>
 
        </activity>
 
     </application>
 
  </manifest>

We pass along the name of our native code library via a <meta-data> tag. Keep in mind that the compiled library will have a name like “libNativeActivitySimpleExample.so”, but the name to write here is simply “NativeActivitySimpleExample” (lose the “lib” and “.so”).

We can now package the app and run it, but if we do, it’ll throw a RuntimeException, with a message like “…unable to start activity… unable to load native library…”. The problem is the linker decided to strip the glue module, because none of its functions were being called directly in our code. After all, the glue code is made up of callbacks, mostly. The decision was made because the –gc-sections linker flag is enabled automatically in default-build-commands.mk. You can read a brief paragraph about this optimization here.

The NDK’s way of solving this problem is by adding a direct call to a dummy function declared in native_activity_app_glue.h. If you look at the NDK’s native activity sample, you’ll notice the following code at the top of “android_main ()”:

// Make sure glue isn't stripped.
 
  app_dummy();

This ensures android_native_app_glue.o is linked. If you add these lines, rebuild, and run, you should now see the “Tick!” message appear as log output. We now have a “hello world” app which is free of Java code!

Touch Input

As long as you leave the previous application alone, it will probably keep running just fine. However, we game developers like to mess with things. So let’s try tapping on the screen several times to send input to our app. It may take a while but, at some point in time, the OS will bring up a “app not responding” popup and will ask you to either keep waiting or force close the app. If we look at the log, we’ll see lines like these:

I/InputReader(XXXX): dispatchTouch::touch event’s action is 1, pending(waiting finished signal)=0

I/InputDispatcher(XXXX): Delivering touch to current input target: action: 1, channel ‘XXXXXXXX Sorry! (server)’

The glue module implements input handling, but we’re not using it explicitly in our code. So the app will not respond to touch and the OS will wait for a period of time, eventually asking you to force close. The way to enable input handling is by enabling general event processing. Here’s an updated main.cpp:

#include <android/log.h>
 
  #include <android_native_app_glue.h>
 
  #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "NativeActivitySimpleExample", __VA_ARGS__))
 
   
 
  void android_main(struct android_app* state)
 
  {
 
     // Make sure glue isn't stripped.
 
     app_dummy();
 
   
 
     while(1)
 
     {
 
        int ident;
 
        int fdesc;
 
        int events;
 
        struct android_poll_source* source;
 
   
 
        while((ident = ALooper_pollAll(0, &fdesc, &events, (void**)&source)) >= 0)
 
        {
 
           // process this event
 
           if (source)
 
              source->process(state, source);
 
        }
 
     }
 
  }

The “ALooper_pollAll()” function waits for events to be available. Its signature is:

int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);

The return value is an identifier which, if greater than or equal to 0, means there is an event for us to process. The first argument is an optional timeout which will wait a desired amount of milliseconds for an event to appear. If the value is set to zero, the function returns immediately without blocking. If it is a negative number, it will block until an event is available. In game development we don’t want to wait indefinitely, so let’s set it to zero. The second, third, and fourth arguments are the file descriptor, events, and source data. These are all set to NULL if we get a negative identifier. For more information on this function and the android_poll_source structure, check the looper.h and android_native_app_glue.h files in the Android NDK.

In the case of a native activity, ALooper_pollAll() can give us two types of events: lifecycle events and input events. To execute your own logic, you’ll need to set the appropriate callbacks. The state variable passed into android_main is an android_app instance and has two member function pointers for this purpose: “onAppCmd” and “onInputEvent”. Let’s set the input callback and do something simple in it.

static int32_t handle_input(struct android_app* app, AInputEvent* event)
 
  {
 
     if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
 
     {
 
        size_t pointerCount = AMotionEvent_getPointerCount(event);
 
        for (size_t i = 0; i < pointerCount; ++i)
 
        {
 
           LOGI("Received motion event from pointer %zu: (%.2f, %.2f)", i, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i));
 
        }
 
        return 1;
 
     }
 
     else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
 
     {
 
        LOGI("Received key event: %d", AKeyEvent_getKeyCode(event));
 
        return 1;
 
     }
 
   
 
     return 0;
 
  }

When touching the screen, we should see the touch coordinates in the log output. If a key is pressed, the key code should appear. If we handled the event, we should return 1.

Lifecycle Events

To execute our own logic for a lifecycle event, such as pause/resume, we need to set the onAppCmd callback:

static void handle_cmd(struct android_app* app, int32_t cmd)
 
  {
 
     switch (cmd)
 
     {
 
        case APP_CMD_SAVE_STATE:
 
           // the OS asked us to save the state of the app
 
           break;
 
        case APP_CMD_INIT_WINDOW:
 
           // get the window ready for showing
 
           break;
 
        case APP_CMD_TERM_WINDOW:
 
           // clean up the window because it is being hidden/closed
 
           break;
 
        case APP_CMD_LOST_FOCUS:
 
           // if the app lost focus, avoid unnecessary processing (like monitoring the accelerometer)
 
           break;
 
        case APP_CMD_GAINED_FOCUS:
 
           // bring back a certain functionality, like monitoring the accelerometer
 
           break;
 
     }
 
  }

The full list of commands can be found in android_native_app_glue.h.

That’s it for part 2! In the next post, I want to write about drawing to the screen and getting input from sensors.


Players don’t want their games to smell of money

Original Author: Julien Delavennat

I almost didn’t write a post today, but I found something interesting at the last minute before going to bed. So random post today. About what ?

This.

So, I’ve been discussing this with someone earlier and ended up summing up the situation in a way that we found was pretty neat and clear:

Players just don’t want their games to smell of money.

Think about it in the following way: let’s ask players for practical and rational arguments  about why the principle of “cash-grabbing” methods would be wrong (day-one-DLC for instance).

Why are we talking about rational stuff here ? It actually doesn’t make sense.

Players play for entertainment. Games are supposed to make them feel good. Rationality and common sense have got nothing to do here.

This reminds me of another article.

The point of this article is simple: you can do shady stuff to get customers to buy more stuff (targeted advertising here), if they don’t know about it they don’t complain.

Does that sound immoral ? You decide, but I think there’s got to be a way to avoid the question entirely.

This basically means two things.

For developers: if your players interpret what you do as some lowly cash-grabbing, you might be doing something wrong. Making sure your players feel good about buying your stuff is important. As far as I know Steam is usually recognized for doing just that: buying a game doesn’t feel like getting ripped-off because it’s overpriced and hard to unpack. It feels like the sales are nice for you because the games are just so affordable and convenient to acquire and play.

For players: nobody is going to get out of this, you either take the the red pill, forget you’re being marketed at and stop complaining, or you take the blue pill, keep complaining, and the marketing will get sneakier. I don’t mean to offense the marketing departments anywhere, marketing is also about getting the right stuff in the right customers hands, don’t mind me, making money is a job and everybody needs to eat n_n

Red Pill vs Blue Pill

To conclude, there doesn’t seem to be any simple solution. I guess the best we can do is listen to players, note what they don’t like and take it into account.


Why Accreditation Matters

Original Author: Lee Winder

Choice is a wonderful thing. Blind choice isn’t and when it comes to degrees listing themselves as a great place to do a ‘Technical Games Degree’ there’s a lot of choice and not a lot of information available to sort the good from the bad.

It’s this abundance of choice and the issues resulting from making the wrong choice that drives my involvement with SkillSet. Good courses need as many opportunities as possible to stand out from the crowd especially when prospective students may have to narrow down the Universities they’ll investigate let alone apply too.

 

 

What Is The Accreditation Process?

I’ve been a lead evaluator for the SkillSet accreditation process for quite a few years now. The process (I’ll keep it short) involves an application by the University to SkillSet, a paper based investigation into the University covering the skills taught, the attainment and employability of students (amongst other things) followed by an on-site visit by an evaluation team. This visit involves interviews with staff and students, examination of the work done and the facilities available with a recommendation to accredit based on their findings.

This evaluation team is always made up of active game developers working in the discipline the course focuses on.

Courses have and will continue to be rejected at various stages of the process if they are not up to scratch and the criteria used is often very strict with a high barrier for entry. Courses have to be producing quality graduates with the skills suitable for the industry before they can even start to think about applying for accreditation. Cross skill courses (those teaching programming, art and design in a single degree) have never been accredited and never will.

The process and documentation is publicly available so you can have a more detailed look here.

 

 

Student Choice

There are a lot of Universities in the UK and a large number of them provide a some kind of game related technical course. Unfortunately a lot of them don’t provide a high enough level of education to warrant the time and money students spend on them. Accreditation awards allows students to quickly narrow down the kinds of Universities they should be looking at and to spend the time they have investigating the best rather than trying to simply find the ones worthy of their time.

Word of mouth and past experience all goes into this but it still takes time that could be better spent especially when students will be applying to Universities at the same time as working towards their A-Levels, a period of time which may well be the most stressful time they’ve had in their academic career so far.

An accredited University at least gives them the knowledge that they’ll get the right kind of education allowing them to focus on finding one that best suits them rather than anything else.

 

 

Industry Involvement

A lot of developers want to get involved with the education of future game makers and University partnerships such as guest lectures and industry panels are one of the best ways to do that. Universities like industry involvement and some developers can end up being overwhelmed with requests especially if they are already working with other courses and word starts to spread. And because a developers time is so valuable, it helps to be able to target the Universities that we know are already providing the kinds of skills students will need in the future.

Building on a quality foundation allows much more scope for growth than having to start from the bottom and working upwards.

But you might think this is a path to ruin. If the industry only helps accredited courses surely none can become accredited because no-ones willing to work with them to get there!

But that’s not the case. Bigger companies such as Sony, MS, Blitz, Codemasters and others work with those up and coming courses, allowing them to get the point where they can apply for or work towards accreditation. Once that happens, it becomes a positive feedback loop, as the course gets better and gets accredited it leads to more industry involvement which leads to a better course…

 

 

It’s The Skills Stupid

The argument between game focused and traditional Computer Science courses is always the same and is usually spot on. Take a CS course over a game course because in a few years you may not want to work in the industry and the skills you learn on a CS could will put you in a stronger position should you want to do something else.

Without a doubt this is a good argument to make but one that I hope accreditation can resolve. In every evaluation I’ve taken part in the skills we look for and the modules on display show that the course could quite easily be rebranded as ‘Computer Science with a games slant’ rather than ‘Games Technology with a little bit of Computer Science thrown in’. As a result the skills taught will still put the student in a good position should they decided the industry is not for them and while a ‘Games Technology’ degree won’t look as good as a ‘Computer Science’ degree on a CV, accreditation should allow it to grow in stature depending on which University awarded the degree.

Jumping from Web to Mobile, Part 2

Original Author: Amos Laber

This is a continuation of my previous post Jumping from Web to Mobile, Part 1 about planning a multi-platform game.

Here I will present a blueprint for an actual port of a specific game project. This is a typical 2D game that feature scrolling backgrounds, animated characters and touch (or mouse) controls. This should give an overview to the practical aspets of planning and building a game on Flash as the primary platform and iOS as the secondary, with possible porting to Android later on.

Choosing Flash as the primary platform enables experienced Flash developers to take advantage of the quick designer-to-developer tooling available, namely Adobe Flash Builder and Flash CS, to easily setup gameplay code over a framework, and create a quick prototype of the game before spending more resources on porting to mobile. Although this is a subjective choice I made, it makes more sense to start developing on a desktop environment, as  iOS developers often do, to achieve shorter development cycles.

There are few different options for going mobile from Flash, the first is Adobe AIR mobile. Adapting a game to AIR requires very little code changes and it deploys to a wide range of mobile platforms. AIR has its advantages, and while it may be the right choice for some projects, it is not in the scope of this article- the  focus here is on using native code for mobile.

Frameworks and Platform Differences

In recent years, a new breed of modern game frameworks has emerged and is gaining popularity among game developers. Most of them free and open source, they borrowed practices from web, desktop and mobile platforms and include an impressive array or out of the box features.

Such frameworks are Cocos2d and Sparrow for iOS, and Starling and ND2D for Flash. Starling is actually a port of Sparrow, using almost identical class names, while ND2D is closer to Cocos2d in style. Regarding content, all of them use the same asset types for images and animation, which make the game content portable when switching between one framework to another. This includes sprite sheets, animation data files and particle effect data (in json and xml).

As a side note, both Starling and ND2D use the hardware accelerated GPU rendering (Stage3D) available in Flash 11. In some cases, developers opt for the software renderer to target wider range of users – and use their own custom framework that supports blitting, or alternative game frameworks like Flixel, FlashPunk and PushButton.

Whatever choice is made, being comfortable with the language and framework you use translates directly to efficiency and shorter timelines. The same goes for art tooling.

The above list of target platforms is by no means the only choice for the the platform, but it’s a choice based on my own preference to code in a strict typed, object-oriented environment (sorry, Javascript and LUA).

Armed with a game framework for the platform and a set of tools we are ready to move on to technical design.

Architecture and Code Structure

As it turns out, clean and structured code is much easier to port than messy, over complicated one. Rule #1 is keep it clean.

The key for easy porting between platforms is building the right architecture. All the proper OOD methodologies apply, and most of all encapsulation and minimizing dependencies. First we need to create a separation between framework (engine) and game logic.These form the two tier architecture where dependencies goes from higher level to lower level modules.

Within each tier, we make a subdivision between platform independent code and platform specific code. This may not be clear cut. The goal is to isolate the platform specific code and keep it to minimum. In some cases we need to create an abstraction layer over that module, but usually this abstraction is already in place in the framework.

The Content Tools

As already mentioned, the said frameworks all use the same type of assets, so the same tools can be used across platforms and frameworks. All graphical assets are bitmap based and the most common use is for textures, sprite sheets and animation data. Here are a few good tools for packing sprite sheets and designing particle effects:

The Game Entity

Another important aspect is the way we design a ‘game entity’ class. Composition is preferred to inheritance here, specially when display object classes are concerned. To be more specific: avoid basing your game entity class on a display class (like Sprite or MovieClip in AS3 and CCSprite in Cocos2d), as its commonly being done in tutorials and sample demos. In real life games, the game entity need to remain neutral and hold a reference to its display object. So instead of the game entity ‘is -a’ display class, it would be a ‘has-a’ relationship.

When done properly, the framework code should manage two separate lists: one for game objects and one for their corresponding display objects, which would be the display list, or scene graph. Note that processing the scene graph (i.e. draw code) is done internally by the framework and never by the game objects. The game loop would look like that:

  1. process user input and game state
  2. update all game objects
  3. draw/render the display list

Making the move

Once the game is up and running on the primary platform, it is ready to be ported from web (Flash / AS3) to the first mobile platform: iOS with Cocos2d.

The process of porting can be summarized in the following steps:

  1. Switching the Framework
  2. Porting the Game code
  3. Porting the contents (game assets)
  4. Converting to touch controls
  5. Adjusting to screen size, language constrains and specific platform optimization

Practically we need to create a new project on the target platform and start with the Framework. In this case it would be an XCode project with Cocos2d. The game code comes next.

Since the game contents and logic are now completely neutral, and porting it into the new project should be straight forward – off course language and syntax conversion should be made. While this can be a tedious job going class by class, it is very much doable.

AS3 to Objective-C

Converting classes and code to Cocos2d requires some knowledge in Objective-C. For simplicity, I’ll skip the detailed description of language porting, and just state that while there are a few differences, both languages are close in the way they handle classes and OOD. For those interested in this topic I recommend this excellent tutorial by Rogers Engelbert.

The hard part is getting it to compile, and adjusting the display code. Another issue is user controls: depending on the type of controls used, they should be converted to touch controls. These can be simple touch and drag, or more complex, like a virtual joy-pad and on screen buttons.

Display Specifics

As each framework uses its own terminology of display objects, it may require some amount of work in replacing references, but since the display code is well contained in the framework and mostly referenced by the game entity, that should not be too difficult. Following is a simple conversion of the main display classes in pure AS3 and ND2D and their equivalents in Cocos2d.

Coordinate systems are different between Flash and Cocos2D. Flash uses the top left corner as origin with Y-down, while cocos2d uses the OpenGL coordinate system, where the origin is at the center and Y-up. If you used Nd2D, there is no need for conversion of coordinates.

More Mobile: Android

The same process applies for Android, using libGDX as the game framework. It may be easier to use the ActionScript project as the source and use the iOS project as a reference, since Java is closer in nature to ActionScript that to Objective-C.

There are plenty of Android specific issues to address, but I will not discuss them here. The main idea is that most of the game code and content (assets) will work almost without change and the project can leverage the work that was already done in the iOS port without having to rewrite any of the components.

Conclusion

Planning a game to be deployed on multiple platform is now within reach for small, indie studios. With borrowed practices from the desktop and console space, modern frameworks such as Cocos2D allow a team of developers to leverage knowledge and expertise gained in one platform to be applied on other platforms.

 

“Refactor”

Original Author: Rob-Galanakis

Refactoring is defined as a “disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior” by Martin Fowler.

But its everyday usage takes a very different meaning. We use the word refactor to everything from the original meaning, to a complete side-by-side rewrite of a barely-functional system. How can you use the same word to refer to something that does not change external behavior, with building an entirely new replacement system?

More than once, I’ve elicited sighs for my efforts to clarify the language we use. But when you have people that use wildly different vocabularies- artists, programmers, project managers- this is of paramount importance. So the fact that we say ‘refactor’ to meaning any type of rewriting of code or functionality irks me.

So recently I’ve begun a dictionary in my head for the type of tasks we do.

Refactor: The original and ‘precise’ meaning of restructuring a module without altering external behavior, up to a rewrite of parts of a larger system, that may change internal behavior of the system (including the external behavior of large internal components). While I’d love to keep only the more limited original meaning, when we’re dealing with large legacy codebases that often have zero tests, the original meaning doesn’t apply often enough.

Renovate: Rewriting a system so that its external behavior changes considerably but it still fulfills the same purpose (obviously). I name it as such because it is like renovating a building- the exterior and interior may greatly change, but what goes on inside may stay the same. Similar to ‘Rewrite’ but generally applies to a smaller (module/system) scale. An example would be, if you have a library for dealing with source control, and you no longer like the API. So you greatly change how the module works, and it still fulfills its fundamental purpose of dealing with source control.

Recycle: Writing a replacement system side-by-side with the old system, using components from the old system (by either referencing or copy/pasting), with the goal that once the new system is working, the old system will be shut down. The goal is a replacement that is easier to use but fulfills similar requirements. An example would be replacing legacy procedures for data transformations, that may have a lot of imperative code and poor reuse. You would replace the system with something better written, often taking chunks of logic from the old system, or writing tests that verify it produces the same results, then hook up calling code to use the new system, then delete the old one entirely.

Rewrite/Rebuild: When a system is to be written from the ground up, using the original implementation as an example or in a prototype role only, resulting in a system that fulfills the business requirements of the original system but does not necessarily preserve anything else about it. Similar to ‘Renovating’ but generally applies to a larger (application) scale. An example would be, if you have a website/game feature that you want to replace, you’d build the new one to fulfill the same business requirement (we need a website/some feature), but the features may be completely different.

So that’s my personal language right now. My hope is that it will expand to my team and then out from there. I don’t know if I’ll refine it much more- too granular and it would become unwieldy. Do you have suggestions or a language of your own?

Constraint Based Design

Original Author: Claire Blackshaw

In some cases the most destructive action one can perform on the creative psyche is to give it absolute freedom. The blank page, blue sky, and empty word document are among the most terrifying monsters in the creative world.

  1. Apply artificial Constraint
  2. Design within Constraint
  3. Remove Contraint
  4. Analyze

That sums up a little bit of advice I’m going impart as to how I defeat these monsters. I’ve used this model in various ways and below I’ll give some examples of this simple piece of advice.

One Button

The modern gamepad (or keyboard/mouse) provides a massive subset of control options. Too many in most cases. As a programmer I often just find myself going “bind” crazy because its easy to bind to a key. This leads to terrible interfaces; original Blender UI anyone 😉

As a designer I often force myself to only have one button and one stick on a gamepad, or maybe just mouse interaction. I force myself to use less buttons than I think I need. Then I will often find ways to contextualize or simplify a mechanic or control. Leading to a more elegant control solution.

This also means I can often later in a project arbitrarily say something like, “Okay we will map that Global button to Shoulder button, they aren’t used anywhere”. Which is great when in crunch or a great feature occurs late in development.

Box It

Often when doodling an idea I will just draw a box on the page. Then draw only inside that box. This only really works for visual designs but I find it works really well to focus once I have a set boundary.

Coin Toss

Have two options?

Do a blind coin toss, and then before revealing the coin if you find yourself wishing for heads or tails you know your answer.

Three Point System

When constructing a narrative it’s easy to lose sight of the overall structure or lose detail. One trick I use is what I call the Bullet Point System. The system that forces groups of three means your always forced to find that third thing but also that you often self prune. Some of my best ideas come while reaching for that third point to fit. I also find that often something sounds great but then I can’t flesh it out to three points so I discard it.

Rules

  • Write 3 lines
  • No line can go onto the next line
  • Always write 3 lines
  • You can expand a point with exactly 3 sub lines

Story of Lost Boy

  • Boy Gets Lost
    • Follows Butterfly
    • Goes into Cave
    • Can’t See Butterfly
  • Boy Wanders
  • Boy Finds Way Home
    • Mother Asks where he has been
    • Boy Gives Silly Answer
      • Don’t Retell Story
      • Child’s Vision
      • Doubt the Experience
    • Butterfly Lands on Boy

Pick It

Alternatively called the F it system this is for when often I’m uncertain or given too many options. If there are 6 different ways we can go and we can’t be sure which to go well then just throw hands in the air, F-it, and pick one.

Most importantly I document the choice!

I will force myself to finish the design or complete going down the path, no regrets. Then if possible when we have more time I go back to that fork in the road and re-examine the choice. Though to be frank it’s rare that you find yourself going back and re-evaulting.

Conclusion

Keep It Simple Stupid! This is all very basic advice that I was hesitant to post but then I recall watching a 30 minute cooking show on cooking Potatoes and thought well sometimes simple advice is very useful. 😉

Comparing Floating Point Numbers, 2012 Edition

Original Author: Bruce-Dawson

Technology/ Code /

We’ve finally reached the point in this series that I’ve been waiting for. In this post I am going to share the most crucial piece of floating-point math knowledge that I have. Here it is:

[Floating-point] math is hard.

You just won’t believe how vastly, hugely, mind-bogglingly hard it is. I mean, you may think it’s difficult to calculate when trains from Chicago and Los Angeles will collide, but that’s just peanuts to floating-point math.

Seriously. Each time I think that I’ve wrapped my head around the subtleties and implications of floating-point math I find that I’m wrong and that there is some extra confounding factor that I had failed to consider. So, the lesson to remember is that floating-point math is always more complex than you think it is. Keep that in mind through the rest of the post where we talk about the promised topic of comparing floats, and understand that this post gives some suggestions on techniques, but no silver bullets.

Previously on this channel…

This is the fifth chapter in what is currently a four chapter series. The previous posts include:

Comparing for equality

Floating point math is not exact. Simple values like 0.1 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations or the precision of intermediates can change the result. That means that comparing two floats to see if they are equal is usually not what you want. GCC even has a warning for this: “warning: comparing floating point with == or != is unsafe”.

Here’s one example of the inexactness that can creep in:

    float f = 0.1f;
 
      float sum;
 
      sum = 0;
 
   
 
      for (int i = 0; i < 10; ++i)
 
          sum += f;
 
      float product = f * 10;
 
      printf("sum = %1.15f, mul = %1.15f, mul2 = %1.15fn",
 
              sum, product, f * 10);

This code shows two ancient and mystical techniques for calculating ‘one’. I call these techniques “iterative-adding” and “multiplying”. And, just to show how messy this stuff is I do the multiplication twice. That’s three separate calculations of the same thing. Naturally we get three different results, and only one of them is the unity we were seeking:

sum = 1.000000119209290, mul = 1.000000000000000, mul2 = 1.000000014901161

Disclaimer: the results you get will depend on your compiler and your compiler settings, which actually helps make the point.

So what happened, and which one is correct?

What do you mean ‘correct’?

Before we can continue I need to make clear the difference between 0.1, float(0.1), and double(0.1). In C/C++ 0.1 and double(0.1) are the same thing, but when I say “0.1” in text I mean the exact base-10 number, whereas float(0.1) and double(0.1) are rounded versions of 0.1. And, to be clear, float(0.1) and double(0.1) don’t have the same value, because float(0.1) has fewer binary digits, and therefore has more error. Here are the values for 0.1, float(0.1), and double(0.1):

Number Value
0.1 0.1 (duh)
float(0.1) 0.100000001490116119384765625
double(0.1) 0.1000000000000000055511151231257827021181583404541015625

With that settled, let’s look at the results of the code above:

  1. sum = 1.000000119209290: this calculation starts with a rounded value and then adds it ten times with potential rounding at each add, so there is lots of room for error to creep in. The final result is not 1.0, and it is not 10 * float(0.1). However it is the next representable float above 1.0, so it is very close.
  2. mul = 1.000000000000000: this calculation starts with a rounded value and then multiplies by ten, so there are fewer opportunities for error to creep in. It turns out that the conversion from 0.1 to float(0.1) rounds up, but the multiplication by ten happens to, in this case, round down, and sometimes two rounds make a right. So we get the right answer for the wrong reasons. Or maybe it’s the wrong answer, since it isn’t actually ten times float(0.1)
  3. mul2 = 1.000000014901161: this calculation starts with a rounded value and then does a double-precision multiply by ten, thus avoiding any subsequent rounding error. So we get a different right answer – the exact value of 10 * float(0.1) (which can be stored in a double but not in a float).

So, answer one is incorrect, but it is as close to 1.0 as a float can get without being there. Answer two is arguably correct, but so is answer three.

Now what?

Now we have a couple of different answers (I’m going to ignore the double precision answer), so what do we do? What if we are looking for results that are equal to one, but we also want to count any that are plausibly equal to one – results that are “close enough”.

Epsilon comparisons

If comparing floats for equality is a bad idea then how about checking whether their difference is within some error bounds or epsilon value, like this:

bool isEqual = fabs(f1 – f2) <= epsilon;

With this calculation we can express the concept of two floats being close enough that we want to consider them to be equal. But what value should we use for epsilon?

Given our experimentation above we might be tempted to use the error in our sum, which was about 1.19e7f. In fact, there’s even a define in float.h with that exact value, and it’s called FLT_EPSILON.

Clearly that’s it. The header file gods have spoken and FLT_EPSILON is the one true epsilon!

Except that that is rubbish. For numbers between 1.0 and 2.0 FLT_EPSILON represents the difference between adjacent floats. For numbers smaller than 1.0 an epsilon of FLT_EPSILON quickly becomes too large, and with small enough numbers FLT_EPSILON may be bigger than the numbers you are comparing!

For numbers larger than 2.0 the gap between floats grows larger and if you compare floats using FLT_EPSILON then you are just doing a more-expensive and less-obvious equality check. For numbers above 16777216 the appropriate epsilon to use for floats is actually greater than one, and a comparison using FLT_EPSILON just makes you look foolish. We don’t want that.

Relative epsilon comparisons

The idea of a relative epsilon comparison is to find the difference between the two numbers, and see how big it is compared  to their magnitudes. In order to get consistent results you should always compare the difference to the larger of the two numbers. In English:

To compare f1 and f2 calculate diff = fabs(f1-f2). If diff is smaller than n% of max(abs(f1),abs(f2)) then f1 and f2 can be considered equal.

In code:

bool AlmostEqualRelative(float A, float B, float maxRelDiff)
 
  {
 
      // Calculate the difference.
 
      float diff = fabs(A - B);
 
      A = fabs(A);
 
      B = fabs(B);
 
      // Find the largest
 
      float largest = (B > A) ? B : A;
 
   
 
      if (diff <= largest * maxRelDiff)
 
          return true;
 
      return false;
 
  }

This function is not bad. It works. Mostly. I’ll talk about the limitations later, but first I want to get to the point of this article – the technique that I first suggested many years ago.

When doing a relative comparison of floats it works pretty well to set maxRelDiff to FLT_EPSILON, or some small multiple of FLT_EPSILON. Anything smaller than that and it risks being equivalent to no epsilon. You can certainly make it larger, if greater error is expected, but don’t go crazy. However selecting the correct value for maxRelativeError is a bit tweaky and non-obvious and the lack of a direct relationship to the floating point format being used makes me sad.

ULP, he said nervously

We already know that adjacent floats have integer representations that are adjacent. This means that if we subtract the integer representations of two numbers then the difference tells us how far apart the numbers are in float space. That brings us to:

Dawson’s obvious-in-hindsight theorem:

If the integer representations of two same-sign floats are subtracted then the absolute value of the result is equal to one plus the number of representable floats between them.

In other words, if you subtract the integer representations and get one, then the two floats are as close as they can be without being equal. If you get two then they are still really close, with just one float between them. The difference between the integer representations tells us how many Units in the Last Place the numbers differ by. This is usually shortened to ULP, as in “these two floats differ by two ULPs.”

So let’s try that concept:

/* See
 
  Tricks With the Floating-Point Format
 
  for the potential portability problems with the union and bit-fields below.
 
  */
 
  union Float_t
 
  {
 
      Float_t(float f1 = 0.0f) : f(f1) {}
 
  	// Portable sign-extraction
 
  	bool Sign() const { return (i >> 31) != 0; }
 
   
 
      int32_t i;
 
      float f;
 
      struct
 
      {   // Bitfields for exploration. Do not use in production code.
 
          uint32_t mantissa : 23;
 
          uint32_t exponent : 8;
 
          uint32_t sign : 1;
 
      } parts;
 
  };
 
   
 
  bool AlmostEqualUlps(float A, float B, int maxUlpsDiff)
 
  {
 
      Float_t uA(A);
 
      Float_t uB(B);
 
   
 
      // Different signs means they do not match.
 
      if (uA.Sign() != uB.Sign())
 
      {
 
          // Check for equality to make sure +0==-0
 
          if (A == B)
 
              return true;
 
          return false;
 
      }
 
   
 
      // Find the difference in ULPs.
 
      int ulpsDiff = abs(uA.i - uB.i);
 
      if (ulpsDiff <= maxUlpsDiff)
 
          return true;
 
   
 
      return false;
 
  }

This is tricky and perhaps profound.

The check for different signs is necessary for several reasons. Subtracting the signed-magnitude representation of floats using twos-complement math isn’t particularly meaningful, and the subtraction would produce a 33-bit result and overflow. Even if we deal with these technical issues it turns out that an ULPs based comparison of floats with different signs doesn’t even make sense.

After the special cases are dealt with we simply subtract the integer representations, get the absolute value, and now we know how different the numbers are. The ‘ulpsDiff’ value gives us the number of floats between the two numbers (plus one) which is a wonderfully intuitive way of dealing with floating-point error.

One ULPs difference good (adjacent floats).

One million ULPs difference bad (kinda different).

Comparing numbers with ULPs is really just a way of doing relative comparisons. It has different characteristics at the extremes, but in the range of normal numbers it is quite well behaved. The concept is sufficiently ‘normal’ that boost has a function for calculating the difference in ULPs between two numbers.

A one ULP difference is the smallest possible difference between two numbers. One ULP between two floats is far larger than one ULP between two doubles, but the nomenclature remains terse and convenient. I like it.

ULP versus FLT_EPSILON

It turns out checking for adjacent floats using the ULPs based comparison is quite similar to using AlmostEqualRelative with epsilon set to FLT_EPSILON. For numbers that are slightly above a power of two the results are generally the same. For numbers that are slightly below a power of two the FLT_EPSILON technique is twice as lenient. In other words, if we compare 4.0 to 4.0 plus two ULPs then a one ULPs comparison and a FLT_EPSILON relative comparison will both say they are not equal. However if you compare 4.0 to 4.0 minus two ULPs then a one ULPs comparison will say they are not equal (of course) but a FLT_EPSILON relative comparison will say that they are equal.

This makes sense. Adding two ULPs to 4.0 changes its magnitude twice as much as subtracting two ULPs, because of the exponent change. Neither technique is better or worse because of this, but they are different.

If my explanation doesn’t make sense then perhaps my programmer art will:

ULP based comparisons also have different performance characteristics. ULP based comparisons are more likely to be efficient on architectures such as SSE which encourage the reinterpreting of floats as integers. However ULPs based comparisons can cause horrible stalls on other architectures, due to the cost of moving float values to integer registers.

Normally a difference of one ULP means that the two numbers being compared have similar magnitudes – the larger one is usually no larger than 1.000000119 times larger than the smaller. But not always. Some notable exceptions are:

  • FLT_MAX to infinity – one ULP, infinite ratio
  • zero to the smallest denormal – one ULP, infinite ratio
  • smallest denormal to the next smallest denormal – one ULP, two-to-one ratio
  • NaNs – two NaNs could have very similar or even identical representations, but they are not supposed to compare as equal
  • Positive and negative zero – two billion ULPs difference, but they should compare as equal
  • One ULP above a power of two is twice as big a delta as one ULP below

That’s a lot of notable exceptions. For many purposes you can ignore NaNs (you should be enabling illegal operation exceptions so that you find out when you generate them) and infinities (ditto for overflow exceptions) so that leaves denormals and zeros as the biggest possible problems. In other words, numbers at or near zero.

Infernal zero

It turns out that the entire idea of relative epsilons breaks down near zero. The reason is fairly straightforward. If you are expecting a result of zero then you are probably getting it by subtracting two numbers. In order to hit exactly zero the numbers you are subtracting need to be identical. If the numbers differ by one ULP then you will get an answer that is small compared to the numbers you are subtracting, but enormous compared to zero.

Consider the sample code at the very beginning. If we add float(0.1) ten times then we get a number that is obviously close to 1.0, and either of our relative comparisons will tell us that. However if we subtract 1.0 from the result then we get an answer of FLT_EPSILON, where we were hoping for zero. If we do a relative comparison between zero and FLT_EPSILON, or pretty much any number really, then the comparison will fail. In fact, FLT_EPSILON is 872,415,232 ULPs away from zero, despite being a number that most people would consider to be pretty small.

For another example, consider this calculation:

float someFloat = 67329.2348f; // arbitrarily chosen
 
  // exactly one ULP away from 'someFloat'
 
  float nextFloat = NearbyFloat(someFloat, 1);
 
  // Returns true, numbers one ULP apart.
 
  bool equal = AlmostEqualUlps( someFloat, nextFloat, 1);

Our test shows that someFloat and nextFloat are very close – they are neighbors. All is good. But consider what happens if we subtract them:

float diff = nextFloat - someFloat; // .0078125000
 
  Float_t fDiff_t(diff);
 
  // returns false, diff is 1,006,632,960 ULPs away from zero
 
  bool equal = AlmostEqualUlps( diff, 0.0f, 1 );

While someFloat and nextFloat are very close, and their difference is small by many standards, ‘diff’ is a vast distance away from zero, and will dramatically and emphatically fail any ULPs or relative based test that compares it to zero.

There is no easy answer to this problem.

The most generic answer to this quandary is to use a mixture of absolute and relative epsilons. If the two numbers being compared are extremely close – whatever that means – then treat them as equal, regardless of their relative values. This technique is necessary any time you are expecting an answer of zero due to subtraction. The value of the absolute epsilon should be based on the magnitude of the numbers being subtracted – it should be something like maxInput * FLT_EPSILON. Unfortunately this means that it is dependent on the algorithm and the inputs. Charming.

The ULPs based technique also breaks down near zero for the technical reasons discussed just below the definition of AlmostEqualUlps.

Doing a floating-point absolute epsilon check first, and then treating all other different-signed numbers as being non-equal is the simpler and safer thing to do. Here is some possible code for doing this, both for relative epsilon and for ULPs based comparison, with an absolute epsilon ‘safety net’ to handle the near-zero case:

bool AlmostEqualUlpsAndAbs(float A, float B,
 
              float maxDiff, int maxUlpsDiff)
 
  {
 
      // Check if the numbers are really close -- needed
 
      // when comparing numbers near zero.
 
      float absDiff = fabs(A - B);
 
      if (absDiff <= maxDiff)
 
          return true;
 
   
 
      Float_t uA(A);
 
      Float_t uB(B);
 
   
 
      // Different signs means they do not match.
 
      if (uA.Sign() != uB.Sign())
 
          return false;
 
   
 
      // Find the difference in ULPs.
 
      int ulpsDiff = abs(uA.i - uB.i);
 
      if (ulpsDiff <= maxUlpsDiff)
 
          return true;
 
   
 
      return false;
 
  }
 
   
 
  bool AlmostEqualRelativeAndAbs(float A, float B,
 
              float maxDiff, float maxRelDiff)
 
  {
 
      // Check if the numbers are really close -- needed
 
      // when comparing numbers near zero.
 
      float diff = fabs(A - B);
 
      if (diff <= maxDiff)
 
          return true;
 
   
 
      A = fabs(A);
 
      B = fabs(B);
 
      float largest = (B > A) ? B : A;
 
   
 
      if (diff <= largest * maxRelDiff)
 
          return true;
 
      return false;
 
  }

Catastrophic cancellation, hiding in plain sight

If we calculate f1 – f2 and then compare the result to zero then we know that we are dealing with catastrophic cancellation, and that we will only get zero if f1 and f2 are equal. However, sometimes the subtraction is not so obvious.

Consider this code:

sin(pi);

It’s straightforward enough. Trigonometry teaches us that the result should be zero. But that is not the answer you will get. For double-precision and float-precision values of pi the answers I get are:

sin(double(pi)) = +0.00000000000000012246467991473532
sin(float(pi))     = -0.000000087422776

If you do an ULPs or relative epsilon comparison to the correct value of zero then this looks pretty bad. It’s a long way from zero. So what’s going on? Is the calculation of sin() really that inaccurate?

Nope. The calculation of sin() is pretty close to perfect. The problem lies elsewhere. But to understand what’s going on we have to invoke… calculus!

But first we have to acknowledge that we aren’t asking the sin function to calculate sin(pi). Instead we are asking it to calculate sin(double(pi)) or sin(float(pi)). What with pi being a transcendental and irrational and all it should be no surprise that pi cannot be exactly represented in a float, or even in a double.

Therefore, what we are really calculating is sin(pi-theta), where theta is a small number representing the difference between ‘pi’ and float(pi) or double(pi).

Calculus teaches us that, for sufficiently small values of theta, sin(pi-theta) == theta. Therefore, if our sin function is sufficiently accurate we would expect sin(double(pi)) to be roughly equal to pi-double(pi). In other words, sin(double(pi)) actually calculates the error in double(pi)! This is best shown for sin(float(pi)) because then we can easily add float(pi) to sin(float(pi)) using double precision. Insert table here:

float(pi) +3.1415927410125732
sin(float(pi)) -0.0000000874227800
float(pi) + sin(float(pi)) +3.1415926535897966

If you haven’t memorized pi to 15+ digits then this may be lost on you, but the salient point is that float(pi) + sin(float(pi)) is a more accurate value of pi than float(pi). Or, alternately, sin(float(pi)) tells you nothing more than the error in float(pi).

Woah. Dude.

Again: sin(float(pi)) equals the error in float(pi).

I’m such a geek that I think that is the coolest thing I’ve discovered in quite a while.

Think about this. Because this is profound. Here are the results of comparing sin(‘pi’) to the error in the value of ‘pi’ passed in:

sin(double(pi)) = +0.0000000000000001224646799147353207
pi-double(pi)   = +0.0000000000000001224646799147353177
sin(float(pi))  = -0.000000087422776
pi-float(pi)    = -0.000000087422780

Wow. Our predictions were correct. sin(double(pi)) is accurate to sixteen to seventeen significant figures as a measure of the error in double(pi), and sin(float(pi)) is accurate to six to seven significant figures. The main reason the sin(float(pi)) results are less accurate is because operator overloading translates this to (float)sin(float(pi)).

I think it is perversely wonderful that we can use double-precision math to precisely measure the error in a double precision constant. If VC++ would print the value of double(pi) to more digits then we could use this and some hand adding to calculate pi to over 30 digits of accuracy!

You can see this trick in action with a calculator. Just put it in radians mode, try these calculations, and note how the input plus the result add up to pi. Nerdiest bar trick ever:

pi =3.1415926535…

sin(3.14)
   =0.001592652
sin(3.1415)
   =0.000092654
sin(3.141502050)
   =0.000090603

The point is, that sin(float(pi)) is actually calculating pi-float(pi), which means that it is classic catastrophic cancellation. We should expect an absolute error (from zero) of up to about 3.14*FLT_EPSILON/2, and in fact we get a bit less than that.

Know what you’re doing

There is no silver bullet. You have to choose wisely.

  • If you are comparing against zero, then relative epsilons and ULPs based comparisons are usually meaningless. You’ll need to use an absolute epsilon, whose value might be some small multiple of FLT_EPSILON and the inputs to your calculation. Maybe.
  • If you are comparing against a non-zero number then relative epsilons or ULPs based comparisons are probably what you want. You’ll probably want some small multiple of FLT_EPSILON for your relative epsilon, or some small number of ULPs. An absolute epsilon could be used if you knew exactly what number you were comparing against.
  • If you are comparing two arbitrary numbers that could be zero or non-zero then you need the kitchen sink. Good luck and God speed.

Above all you need to understand what you are calculating, how stable the algorithms are, and what you should do if the error is larger than expected. Floating-point math can be stunningly accurate but you also need to understand what it is that you are actually calculating. If you want to learn more about algorithm stability you should read up on Numerical Computing with IEEE Floating Point Arithmetic.

The true value of a float

In order to get the results shown above I used the same infinite precision math library I created for Fractal eXtreme to check all the math and to print numbers to high precision. I also wrote some simple code to print the true values of floats and doubles. Next time I’ll share the techniques and code used for this extended precision printing – unlocking one more piece of the floating-point puzzle, and explaining why, depending on how you define it, floats have a decimal precision of anywhere from one to over a hundred digits.

Credits

Thanks to Florian Wobbe for his excellent error finding and many insights into this topic.

Sensible Error Handling — Part 3

Original Author: Niklas Frykholm

In my epic trilogy on sensible error handling I’ve arrived at the third and final category of errors — warnings.

Warnings happen when the user does something that is kinda sorta bad, but not exactly wrong per se. It can be things like having two nodes with the same name in an entity’s scene graph, a particle effect with 1 000 000 particles or a 4096 x 4096 texture mapped to a 3 x 3 cm flower.

Not necessarily wrong — perhaps there will be a sequence where the player is miniaturized and has to walk on the surface of the flower, fighting off hostile pollen — but definitely fishy.

The problem with warnings is that they are so easy to ignore. When a project has hundreds of warnings that scroll by every time you start it, no one will pay any particular attention to them and no one will notice a new one.

But then of course, if warnings are not easy to ignore, everyone on the project will have to spend a lot of their valuable time ignoring them.

So the real problem, as in so many cases, is that we don’t really know what we want. We want warnings to be both hard to ignore and easy to ignore. We can’t get good warnings in our tools without resolving this conflict in our minds.

Types of warnings

To progress we need more information. We need to think about what kind of warnings there are and how we want to handle them.

In the Bitsquid engine, our warnings can be classified into three basic types:

  • Performance warnings

  • Suspicion warnings

  • Deprecation warnings

Performance warnings occur when the user does something that is potentially bad for performance, such as using a texture without a MIP chain or loading a 300 MB sound file into memory.

Suspicion warnings occur when we detect other kinds of suspicious behavior and want to ask the user “did you really mean to do X?”. An example might be defining a font without any glyphs. It is not exactly an error, but it is not very useful either, and most likely, not what the user wanted.

Deprecation warnings, finally, are warnings that really should be errors. We want all our data to follow a particular rule, but we have too much legacy data to be able to strictly enforce it.

A typical example might be naming conventions. We may want to force all nodes in a scene graph to have unique names or all mesh names to start with mesh_, but unless we laid down that rule at the start of the project it might be too much work to fix all the old data.

Another example of deprecation is when a script function is deprecated. We may want to get rid of the function AudioWorld.set_listener(pos) (because it assumes that there is only one listener in the world) and replace it with AudioWorld.set_listeners(table), but there is a lot of script code that already uses set_listener and no time to rewrite it.

As for when warnings should be shown, I think there are only two times when you really care about warnings:

  • When you are working with a particular object (unit, mesh, level, sound, etc), you want to see all the warnings pertaining to that object.

  • When you are doing a review of the game (e.g., a performance review), you want to look through all warnings pertaining to the aspect that you are reviewing (in this case, all performance warnings).

Armed with this information, we can come up with some useful strategies for dealing with warnings.

Treat warnings as errors

Errors are a lot easier to deal with than warnings, at least if you adhere to the philosophy of “asserting on errors” that was outlined in the first part of this series. An error is always an error, it doesn’t require a judgement call to determine whether it is right or wrong. And since the engine doesn’t proceed until the error has been fixed, errors get fixed as soon as possible (usually before the content is checked in, and in the rare occasions when some one checks in bad data without test running it — as soon as someone else pulls). Once the error is fixed it will never bother us again.

In contrast, warnings linger and accumulate into an ever expanding morass of hopelessness.

So, one of the best strategies for dealing with warnings is to make them errors. If there is any way you can convert the warning into an error, do that. Instead of warning if two nodes in a scene graph have the same name, make it an error. Instead of warning when an object is set to be driven by both animation and physics, make it an error.

Of course, when we want to make an error of something that was previously just a warning, we run into the deprecation problem.

Ideas for deprecation warnings

The strategy for deprecation warnings is clear. We want to get rid of them and treat them as “real errors” instead. This gives us cleaner data, better long term maintainability and cleaner engine code (since we can get rid of legacy code paths for backward compatibility).

Here are some approaches for dealing with deprecation, in falling order of niceness:

1. Write a conversion script

Write a conversion script that converts all the old/deprecated data into the new format. (An argument for keeping your source data in a nice, readable, script-friendly format, such as JSON.)

This is by far the nicest solution, because it means you can just run the script on the content to patch it up, and then immediately turn the warning into an error. But it does require some programming effort. (And we programmers are so overworked, couldn’t an artist/slave spend three weeks renaming the 12 000 objects by hand instead?)

Of course, sometimes this approach isn’t possible. I.e., when there is no nice 1-1 mapping from the current (bad) state to the desired (good) state.

One thing I’ve noticed though, is that we programmers can have a tendency to get caught up in binary thinking. If a problem can’t be solved for every possible edge case we might declare it “theoretically unsolvable” and move on to other things. When building stable systems with multiple levels of abstractions, that is a very sound instinct (a sort function that works 98 % of the time is worse than useless — it’s dangerous). But when it comes to improving artist workflows it can lead us astray.

For example, if our script manages to rename 98 % of our resources automatically and leaves 2 % tricky cases to be done by hand, that means we’ve reduced the workload on the artist from three weeks to 2.5 hours. Quite significant.

So even if you can’t write a perfect conversion script, a pretty good one can still be very helpful.

2. Implement a script override

This is something I’ve found quite useful for dealing with deprecated script functions. The idea is that when we want to remove a function from the engine API, we replace it with a scripted implementation.

So when we replace AudioWorld.set_listener() with AudioWorld.set_listeners(), we implement AudioWorld.set_listener() as a pure Lua function, using the new engine API:

function AudioWorld.set_listener(pos)
 
  	local t = {pos}
 
  	AudioWorld.set_listeners(t)
 
  end

This leaves it up to the gameplay programmers to decide if they want to replace all calls to set_listener() with set_listeners() or if they want to continue to use the script implementation of set_listener().

This technique can be used whenever the old, deprecated interface can be implemented in terms of the new one.

3. Use a doomsday clock

Sometimes you are out of luck and there simply is no other way of converting the data than to fix it by hand. You need the data to be fixed so that you can change the warnings to errors, but it is a fair amount of work and unless you put some pressure on the artists, it just never happens. That’s when you bring out the doomsday clock.

The doomsday clock is a visible warning message that says something like:

Inconsistent naming. The unit ‘larch_03′ uses the same name ‘branch’ for two different scene graph nodes. This warning will become a hard on error on the 1st of May, 2012. Fix your errors before then.

This gives the team ample time to address the issue, but also sets a hard deadline for when it needs to be fixed.

For the doomsday clock to work you need a producer that is behind the idea and sees the value of turning warnings into errors. If you have that, it can be a good way of gradually cleaning up a project. If not, the warnings will never get fixed and instead you’ll just be asked again and again to move the doomsday deadline forward.

4. Surrender

Sometimes you just have to surrender to practicality. There might be too much bad data and just not enough time to fix it. Which means you just can’t turn that warning into an error.

But even if you can’t do anything about the old data, you can at least prevent any new bad data from entering the project and polluting it further.

One way of doing that is to patch up your tools so that they add a new field to the source data (another argument for using an easily extensible source data format, such as JSON):

bad_name_is_error = true

In the data compiler, you check the bad_name_is_error flag. If it is set, a bad name generates a hard error, if not a warning. This means that for all new data (created with the latest version of the tool) you get the hard error check that you want, but the old data continues to work as before.

Design the tools to avoid warnings

Warnings are generated when the users do stuff they did not intend to. The warnings we see thus tell us something of the mistakes that users typically make, using our tools.

One way of reducing the amount of warnings is to use this information to guide the design of the tools. When we see a warning get triggered we should ask ourselves why the user wasn’t able to express her intents and how we could improve our tools to make that easier.

For example, if there are a lot of warnings about particle system overdraw, perhaps our particle system editor could have on screen indicators that showed the amount of overdraw.

There are lot of other ways in which we can improve our tools so that they help users to do the right thing, instead of blaming them for doing wrong.

Put the warnings in the tools

The most useful time to get a warning is when you are working on an object. At that time, you know exactly what you want to achieve, and it is easy to make changes.

It follows then that the best place to show warnings is in the tools, rather than during game play. You may have that as well, to catch any strays that don’t get vetted by the tools, but it should not be the first line of defense.

For every tool where it makes sense, there should be a visible warning icon displaying the number of warnings for the currently edited object. For added protection, you could also require the user to check off these warnings before saving/exporting the object to indicate: “yes I really want to do this”.

Make a review tool for warnings

Apart from when a particular object is edited, the other time when displaying warnings is really useful is when doing a project review in order to improve performance or quality.

I haven’t yet implemented it, but the way I see it, such a tool would analyze all the content in the project and organize the warnings by type. One category might be “Potentially expensive particle systems” — it would list all particle systems with, say, > 2000 particles, ordered by size. Another category could be: “Possibly invisible units” — a list of all the units placed below the ground in the levels.

The tool would allow a producer to “tick off” warnings for things that are really OK. Perhaps, the super duper effect really needs to have 50 000 particles. The producer can mark that as valid which means the warning is hidden in all future reviews.

Hiding could be implemented real simply. We could just hash the object name together with the warning message and make sure we don’t show that particular message for that particular object again.

This has also been posted to The Bitsquid blog.


Python’s documentation at your fingertips

Original Author: Gustavo Ambrozio

The pain

my last blog post, I started learning Python some time ago and fell in love with it. But, as with any new programming language, I spent a lot of time browsing through the documentation to find out the correct name of the method to find a substring within a string for example. Is it indexOf, find, rangeOfString, locate??? Off I went to the (very well done, btw) online Python docs to look for the right method in the string module.

In the meantime I also fell in love with another tool: Dash. If you’re an iOS developer and don’t have Dash you should go get it right now! It’s one of the most useful tools in my tool belt at the moment. And for the very lowprice of free you just can’t go wrong. As I said to the author, I’d gladly pay good money for it.

Dash’s first use for me was to browse inside iOS’ documentation. I never liked XCode Organizer’s documentation browser. The search is incredibly slow, pages take forever to load, there’s no easy way to jump to a method’s documentation, you name it…

Dash is the complete opposite:

  • The search is amazingly fast;
  • Once you find the class you’re looking for it builds a list of all the methods so you can quickly jump there;
  • If you click on a method’s declaration it automatically copies it to your clipboard. It’s now a breeze to create delegate methods;
  • You can search inside a class documentation just as easily;

Not to mention other very nice features, such as a collector of code snippets and as a text auto expansion tool. Even if you’re not an iOS or OSX developer Dash can be a great tool just to collect snippets and auto expand text. Enough praise, let’s go back to the problem.

Dash can be used to browse through any documentation that has been bundled in Apple’s docset format. When I learned this, one of those flashbulbs appeared over my head and I immediately started to scour the web for a version of Python’s documentation in docset format only to find that such a thing either does not exist or is very well hidden.

Using the snake to help the snake

So I decided to take matters into my own hands and build this documentation myself. Using Python, of course.

With the help of Dash’s author I learned how to build docsets that were easily searchable inside Dash. After a few hours of coding, reading Apple’s documentation and building regexes to collect all the information I thought should be in the documentation, I managed to create a docset, configure Dash to use it and, voilá, instant Python documentation search!

I managed to generate documentation for Python 3.2.2, the latest versions at this time. Click the links to download and feel free to use them. You’ll have to unzip the file and put the resulting .docset bundle somewhere. I would recommend putting them in ~/Library/Developer/Shared/Documentation/DocSets as this is the place XCode will look for when searching for docsets. I believe Dash will look in this folder too or at least is the default folder for when you try to add new docsets to it.

And I’m proud to say that Dash’s author will bundle this bundle (the 2.7.2 version) with Dash’s new version. If you want to have documentation for version 3.2.2 you can download my version and use that instead. Oh, and before I forget, Dash now comes with a lot of docsets created by the author. Currently Android, Java, Perl, Python, PHP, Ruby, jQuery and Cocos2D docsets are included.

Plus, I’m adding this script to my my repos.

To use the script you’ll need to have the BeautifulSoup module installed (sudo pip install beautifulsoup4). I use it to parse the documentation’s HTML so I can find all interesting methods, functions, classes to grab. I also had to add anchor tags to all html files so Dash could jump to the correct place inside the HTML.

This is what you have to do to generate a new version of the documentation from the HTML version:

  1. Download the documentation for the version you want here. You should download the zip file for the HTML version of the docs.
  2. Expand the documentation somewhere.
  3. Open terminal and cd to the folder where you expanded the docs.
  4. Run the script from this folder.
  5. The script will create a python.docset bundle with all the necessary files.
  6. Move the python.docset bundle to some folder. Again, I recommend ~/Library/Developer/Shared/Documentation/DocSets
  7. Use it!

Conclusion

This is my first contribution to the Python community. I hope you like it and that using my blog’s post.

The docset does not have the complete documentation (it does not have the tutorials and howto for example) as I personally use it only as a reference. But, as I said before, feel free to change the script to include more stuff and make a pull request so I can add it to my repo.


Running an Industry Night

Original Author: Forrest Smith

Every month in a discrete location Seattle area game developers come together. They do so to drink beer, trade war stories, and socialize with industry peers. What I’m talking about of course is industry night and I organize one. It’s surprisingly easy to run and every game dev city should have one. If your city doesn’t have one then I implore you to read this article and start it yourself!

What

Industry night is a bunch of game devs showing up to hang out. That’s it. Nothing more. In fact it is explicitly nothing except that. There is no affiliation with IGDA or any other organization. There are no speakers and no presentations. Those things are good, but industry night is for drinking and socializing.

My proudest moments are when someone gets a job through industry night. It’s not the place for handing out resumes, but it is the place to meet new people and make new friends. That’s real networking and that’s what opens doors down the road.

Who

Game devs of course! The event I organize has about 40-60 people show up in a typical evening. There are even four #altdevblogaday authors who show up on a regular basis. We had five until one moved away. Peer pressure is a wonderful thing.

One important point to make however is that industry night is not for students. Students aren’t invited. It sounds terrible but that’s simply not what the evening is for. When students start showing up then real devs stop coming out because no one wants to be nagged for a job. There is a time and place for students to mingle with those in the industry, but industry night is not one of them.

When

Once a month. Pick a day of the week and host it in a predictable fashion. For example the first Tuesday or third Thursday of every month. I strongly recommend picking a night from Monday through Thursday. Our gathering is officially scheduled for 8pm to 11pm although it’s not uncommon for a few folks to stick around til midnight.

Where

At a local bar of course!

If I had one and only one bullet point to get across this would be it. Getting space is easy and, most importantly, free. Here’s how you do it.

First, pick out a local bar. It needs to be in an accessible location and have lots of space. Second, make sure you are hosting during the week. Friday nights and weekends are too busy. Third, contact the bar owner and say, “Hello. I run a local industry night and we’d love to meet at your bar. About thirty beer thirsty people will be coming. Can we meet at your establishment or should we go somewhere else?”

Say it with a less snark of course, but you get the idea. 🙂 A couple of dozen people ordering drinks and food during an off night is a great business. Why would they not give you free space? We’re even big enough to get a side room to ourselves and a dedicated waitress. It’s super easy once you get 15+ people showing up. Until then you can just pick a bar and meet in the back.

Getting Started

I was fortunate enough to take over an existing event. I can however offer up a few suggestions.

I use socializer for invite management. Each month I copy the previous event, change the text slightly, and invite my mailing list. I have a gmail account for people who wish to get added to the list.

Although Industry Night is not associated with the IGDA there is room to work together. For example the IGDA and Industry Night helped kickstart each other by having sequential events. IGDA had a presentation from 6:30 to 8:00 which smoothly rolled into industry night from 8pm to 11pm. IGDA allows student members so industry night is not officially listed on their calendar.

Sponsored Events

On special occasion there will be corporate sponsorship. This is always tied into recruiting and usually results in an open bar. There is no better way to get devs to show up somewhere than to offer them free booze. It’s relatively cheap for the sponsor and gets a huge turn out. Our average monthly headcount is 40-60 and that turns into 150 when free booze is involved.

Secrecy

You’ll notice I haven’t mentioned when or where the Seattle industry night event is. This is quite intentional! I never publicly disclose it’s location on Facebook or Twitter to prevent random fans from showing up. With mega developers such as Bungie and Valve in the area it’s a necessary precaution.

Conclusion

Industry night is awesome. If your city has one and you don’t go then you should. If your city doesn’t have one then you should start it. It costs zero dollars, requires a minimal time investment, and is extraordinarily beneficial for game developer community.

If anyone is thinking about starting up an industry night event and has more questions feel free to contact me as I’d love to help.