Archive for the ‘programming’ Category

Why and how to pack your textures for iOS/Android

Sunday, December 4th, 2011

Introduction

When I developed Don’t Feed the Trolls on X360 (using XNA), I did not optimize the textures files of the game : the game was very simple, the final hardware (X360) is very fast, so it was not necessary. I arranged the sprites so that I could get their coordinates in-game very easily. Every “troll” sprite for instance is the same size, so most of them are filled with transparent pixels. A lot of space is wasted. Have a look at the sprite sheet for the characters that I use on X360.

X360 Don't Feed the Trolls Characters Sprite Sheet

The characters texture on X360 is 2048×1024. I could easily have it into a 1024×1024 but it was a lot easier if I could have all the sprites of the same kind in a row (for example, all the bear heads are on the top row). I also made a few other sprites sheets for UI, birds, tutorial for instance.

For the first draft of my Android port, I first concentrated on the gameplay and integrate this sprite sheet as is. Of course, I quickly realized I had to spend some time to optimize as obviously, constraints on mobile and X360 are different.

Why packing your textures?

Why is proper texture packing important for games, especially on mobile? Packed textures use less pixels, and from this simple fact, the game is greatly improved in many ways:

Memory

Less pixels takes less memory. Mobile have big memory constraints and saving memory from the ressource is great. Texture ressources are often the biggest ressources.

Loading

There are less files to open, and less pixels to read, this will therefore be faster to load.

Runtime performance

When packing your textures in atlases, more sprites will share the same texture. In runtime, the GPU will then have less textures changes to make and this will therefore speed up your game. This will improve performance if you draw the sprites using the same texture in a row.

It will allow you to reduce your texture sizes. Some Android devices are performing very slowly with 2048 pixels-wide textures.

Game size

The downloadable package size will be smaller too. This is great, especially for people using 3G or with limited bandwidth that won’t download big games.

How to pack?

I first thought of packing my sprites manually but quickly searched for a tool to assist me in that tedious task. There are a few tools available to automatically pack your sprites, and I am currently using TexturePacker, and I’m very happy with it (please note that I got a free copy of TexturePacker from the developer). It’s easy to use and has a lot of functionnalities, such as:

  • Auto-refreshes the packed texture in the tool when I add images to my folders
  • Export in one click
  • Support cocos2d and therefore cocos2d-x which I am using (and many more formats).
  • Removes useless transparent pixels around sprites
  • Efficient packing

All the features are listed here.

Here is a sample of a packed sprite sheet for the Android version of Don’t Feed the Trolls made with TexturePacker:

Packed sprite sheet for Don't Feed the Trolls Android/iOSInstead of 2048×1024, this is just 1024×1024, and most importantly, I have all my characters, the UI elements, and some background elements in the same, smallest texture!

Generic code

I did some code so that resource loading does not have to deal with packs or single sprites. That way, I can send a version without packs to the artist and he can test his ressource live. In cocos2d-x, this is very easy. You first need to load your pack(s) with CCSpriteFrameCache ::addSpriteFramesWithFile( file_name ). And then, read the ressource from the file if it’s not found in the packs. I did it like this:

CCSprite *GetSprite(const char *file_name )
{
 CCSprite *psprite = new CCSprite( );
 psprite->autorelease();
 // Search in the cache, first
 CCSpriteFrameCache *sfc = CCSpriteFrameCache::sharedSpriteFrameCache();
 CCSpriteFrame *psf = sfc->spriteFrameByName( file_name );
 if( psf != NULL )
 {
  psprite->initWithSpriteFrame( psf );
  return psprite;
 }
 CCLog("WARNING : %s not in a PACK!", file_name );
 psprite->initWithFile( file_name );
 return psprite;
 }
sprite->autorelease();
// quite ugly wait to skip dlg/img directory
if( file_name[3] == ‘/’ )
{
CCSpriteFrame *psf = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName( &file_name[4] );
if( psf != NULL )
{
psprite->initWithSpriteFrame( psf );
return psprite;
}
}
fgLog(”FROZAX : %s not in a PACK”, file_name );
psprite->initWithFile( file_name );
return psprite;

Conclusion

Packing your textures is very important on mobile platform, but hopefully, great tools make that task very easy and straighforward.

Do you pack your ressources? Do you do it by hand? Which tool do you use?

Follow me on twitterfacebook or google+ for more game development information.

Android Game Development : from Java to C++ (with cocos2d-x)

Saturday, November 12th, 2011

Introduction

In a previous post (here), I was talking about my progress with libgdx, a Java library for Android (and other platforms). Shortly after writing this article, I realized that there is a big disadvantage that I forgot to talk about. It’s so big that it made me stop using libgdx : It is not portable on iOS. I knew this from the beginning but didn’t really think about using anything else than Java. I finally realized that while porting from one language to another is easy, it can take a lot of time.

Cocos2d-x

I searched for multiplatform libraries (Android and iOS). As the game I’m porting (Don’t Feed the Trolls) was developed with XNA, I looked at C# solutions. There is at least one but it’s too expensive. I’ve been doing C++ indie/casual games in the past and I develop in C++ in my day job, so this is the obvious choice. I like the efficiency of languages such as C# or Java (easy to write and debug), but if I want to avoid porting the game another time for the iPhone, I should to use C++. There are quite some libraries in C++ (such as Marmalade). I finally decided to use cocos2d-x. This is a C++ port of the famous cocos2d library for iPhone which is in Objective C. Cocos2d-x has an active community, some multiplatform games have been released already, it’s free and open source. All good stuff!

C++ on Android

I am mostly working using the Windows build of the library but I also did some work on Android. Mixing C++ and Java (using JNI : Java Native Interface) is doable, but really not user friendly. Debugging is terrible, building is slow, you have to install tools such as cygwin, use makefiles (how old school!), and so on. It really does not seem the right solution at first. However, once everything is set up correctly, it’s working fine. Cocos2d-x has good tutorials about this. I develop with Visual C++ 2010 Express on the Windows build, I have all the great tools to debug generic problems. The only real troubles are when you have android-specific bugs in the C++ code but it’s really not frequent. And there are a few ways to debug it with gdb and gdb-server (I never had to use it yet). When you have a crash, there is a very useful tool in the NDK called addr2line (here’s how to use it) that allows you to get the callstack. It’s usually enough to understand and fix the bug. You also can still use old-school debugging techniques such as logging to the output ;) Hopefully, most of my bugs are multiplatform, or in Java code, so I can fix them easily.

Java is still needed

To develop Android-specific code, you still need Java. For example, I use Java for AdMob integration, In-App Purchases or the Facebook SDK for instance. Setting up Java functions called from C++ is not very intuitive, so I opted for a very simple and centralized way: I have one Java function that can be called from C++ with two String parameters. In the Java code, I read these parameters that contains all I need to know to call the specific Java code.

Conclusion

Even though libgdx is really a great lib, after a few weeks working on C++, I’m confident that I made the right choice with cocos2d-x. I did not start developing on iPhone already but it should be quite fast compared to porting Java to C++ (or worse, Objective-C!). I have a working Android version of my game and the performances seems good.

Which language do you use to build your multiplatform mobile games? Do you know other good C++ solutions? Feel free to comment!

Follow me on twitter, facebook or google+ for more game development information.

Android Game Development with libGDX

Tuesday, September 27th, 2011

androidAfter selling games on PC, Mac and Xbox 360, I want to develop games on mobile plaforms, and I will start with Android. I chose Android instead of iPhone for two reasons:

  • It’s cheaper: my Mac is a PowerPC and you need a Mac Intel for iPhone development. Also Android phones are cheaper than iPhones.
  • Java is similar to C# : I have C# games ready to be ported to mobile. As Android uses Java, it’s a great platform for me to port those games.

My last X360 game, Don’t Feed the Trolls is a great fit for mobile: quick gameplay sessions and not requiring too much processing power or memory. I therefore decided to port it to Android.

libgdxI started to look for available 2D game libraries on Android and after hesitating between AndEngine and libGDX, I chose libGDX. I will describe here some features and my thoughts about this library.

What I like

Complete API

It’s a simple but complete API. We often see libraries with only rendering support, but with libGDX, you can do rendering (2D and 3D), audio, file management and input (touchscreens). There are also a few useful utility classes and tools (more on this below).

Box2D

box2dThere is also a port of Box2D, the physics library used in Spring Up Harmony (PC, X360). If I ever want to port Spring Up Harmony to Android (probably), the physics part should be easily portable.

Open Source

I like to have access to the source code of libraries I use. I find it reassuring and when debugging, it’s good to be able to step into libraries source code.

Activity

activityThere is currently quite a lot of updates and bug fixes, by the creator of the lib (Mario Zechner) and by community.

Bitmap Fonts

font_small_cropThere is a tool available to create bitmap fonts. This is very similar to the tool I used on XNA (SpriteFont2 Texture Tool) so porting my existing code was very easy.

Desktop Version

If you ever used the Android Emulator of the SDK, you are probably aware that it’s terribly slow and not really usable. I didn’t buy my Android Device yet, but can still work on the game and test it properly because libgdx also compiles for desktop java.

Don't Feed the Trolls for Android running with the Desktop version in libGDX

Don't Feed the Trolls for Android running with the Desktop version of libGDX

Texture Packer

This is another great tool, used to pack many textures in one. I usually don’t care much about texture size and texture memory waste when developing on X360 but this is important on mobile devices due to their limitations. Some features of this tool:

  • Grouping small textures in textures pages (power of two).
  • Strip transparent pixels on the borders of textures. This required quite some tweaks and update in my own fgDrawSprite class and rendering functions to manage properly, but this is really a great way to save memory and disk space.
  • Has an incremental option to avoid generating everything when updating only some resources.
  • Can be called from the game itself in the desktop version. A good practice is to automatically call the packer in the desktop version, and use the generated assets in both Desktop and Android.

This is really a time saver tool.

What I don’t like

Lack of documentation

There is no good and centralized documentation. You need to look for information on the forums, in the source code and/or on blog articles. Due to the activity of the library, I sometimes find out that I’m using old stuff that is not supposed to be used, because it’s deprecated and has been replaced by something else. The parameters of some API functions are not always properly documented too. For instance, I had trouble using a rendering function and found out that the rotation parameter was an angle in degrees (it’s usually in radians in the libraries I used before).

Reverted Y-Axis

coordsI found this very strange but in all the 2D APIs I used, the coordinate system used the point (0,0) as the top-left corner, with X going right and Y going down. In libgdx, the Y axis is going up, and the 0,0 is bottom-left. I had to change some rendering functions to take this into account.

Android Specific

Doing Android specific code is not very clean because the lib is supposed to work on desktop and Android. I guess this is also because of Java, and I wished we could have some preprocessing to condition Android specific code. There are many workarounds, because the Android application overloads the Desktop application. So you can create empty methods on Desktop that are overloaded only in the Android project with Android specific code. I hope this won’t get too messy when I’ll work on very specific and touchy stuff such as in-app purchases.

What I don’t know

Performance

I don’t own an Android device yet and did not test other API, so I can’t really talk about the performance of the API. According to users, it is faster than most other APIs.

Conclusion

Using libGDX is a good and easy way to start developing Android games. For now, I’m happy with this library and you can see on the screenshot above that development is going well. I will probably release a few games with it.

If you tested different Android libs or have anything to add, feel free to comment about it.

You can find out more about Frozax Games or me on twitter, facebook or g+.

Useful C# and Visual Studio tips you might not know

Tuesday, May 31st, 2011

While working on my next game, I tried to keep notes of interesting tips I used. They are related to C# and Visual Studio.

Overriding ToString()

When debugging or prototyping, you often need to display complex objects on the screen on in the debugger output. A handy way to do this when dealing with complex classes is to override the ToString() member. Here is an example:

class ComplexClass
{
   int _number = 0;
   string _string = "My String";

   public ComplexClass( int n, string s )
   {
      _number = n;
      _string = s;
   }

   public override string ToString()
   {
      return String.Format( "{0} / {1}", _number, _string );
   }
}

ToString() is also used by the debugger in the Watch dialog.

?? operator

I discovered the ?? operator a few months ago. I don’t use it much but could be useful in some cases. It allows you to replace the following code:

if( a != null )
   b = a;
else
   b = c;

by

b = a ?? c;

New class template

When you create a new class (using the right-click on the project, Add, New Item…), the file created is not empty but already has a template and a few using statements. You can edit this template easily. For instance, I added a “using fg;” with my own game library to this template. The template is found in the Visual Studio directory: {Program Files}\Microsoft Visual Studio 10.0\Common7\IDE\VCSExpress\ItemTemplatesCache\1033\class.zip. There are templates for anything and you will probably want to edit a few of them.

new does not always allocates

In C#, even when using the new operator, you might not allocate memory. For instance, the following line:

Vector2 point = new Vector2( 10, 20 );

does not allocate memory, because Vector2 is not a class, but a structure. The rule is as simple as that: a class allocates memory (and returns a pointer) and a struct does not allocate memory. It’s simple, but often misunderstood, especially if you come from C++.

Add As Link source file

Recently, I re-used source files from a previous project for a new one. I used the Add Existing Item option but Visual C# creates a copy of the source file in the current project directory instead of referencing the old file. I want to reference the old file so that it can be modified in both projects. To avoid that, you must select the hidden Add As Link option, by clicking the small arrow next to the Add button of the dialog box.

add_as_link

Overloading the [] operator

I often have objects containing a list of items. For instance, in Spring Up Harmony, I have a Ball Manager used to manage and draw the balls. I found it very handy to overload the [] operator to access elements of the list inside the manager from the outside directly.

List<Ball> _balls = new List<Ball>();
public int Count { get { return _balls.Count; } }
public Ball this[int i] { get { return _balls[i]; } }

That’s it!

I hope you found some of the tips useful!

Feel free to share more tips in the comments!

Follow me on twitter or facebook to get notified of new posts.

How to recover a file in Google Chrome cache (gzipped or not)

Saturday, May 14th, 2011

Exceptionally, this article is slightly off-topic and will not be related to game development.

I wished I could find an article like this one a few hours earlier, therefore I’m writing it myself, hoping to help people fixing the same problem I had.

The context

Earlier today, I was logging onto my ftp to download the latest log of Spring Up Harmony hiscores history in order to gather up-to-date piracy statistics. As the log files can grow quite large, I regularly download it locally and remove the server copy. Then, I use all my local copies to generate new stats, similar to the one shown in my 96% Piracy blog article.

The mistake

I was probably not really focused, but instead of transferring from my site to my local computer, I transfered the other way round and lost all my logs of the last 4 days! Argh! I’m sure the next time I will examine the “Are you sure you want to overwrite this file?” popup carefully.

The failed strategies

Here is a list of actions I made trying to recover data:

  • As I looked at my stats log online a few hours earlier, I hoped that I kept a tab open in my browser but I didn’t.
  • I checked the automatic backup of my hosting provider, but the daily backup was made 20 hours ago. That’s already a few days recovered, but I hoped to recover more of it.
  • I looked into Chrome cache folder, only to find 285 Mb of strangely-named binary files. That will not get me anywhere.
  • I looked for a free app to access chrome cache but the only one I found only told me which binary file contained my log file (ChromeCacheView).

However, this last app gave me hope because it displayed information about the name and date of the file I was looking for. Only 3 hours from the mistake. Losing 3 hours of log would be acceptable.

The Solution

Looking on google, I found that Chrome has an interesting integrated cache viewer that could have helped me from the beginning. By typing about:cache in the address bar, you access a list of cached files. You can also type a direct url if you know the file in the following form: chrome://view-http-cache/http://example.com/file.htm. I thought I found the solution and quickly accessed my log file. However, Chrome does not simply give you a way to get the cached file but instead displays raw data with HTTP headers and data received from the server. For my file, it gave me something like that (click for full size):

chrome_cache

As you can see in the red circle, it’s pretty obvious that the binary data displayed below is gzip data, and not plain text sadly. However, the presentation in Chrome is not really handy to get the real binary data because it contains on the left the addresses and on the right the binary form. The useful part is the hexadecimal version on the middle.

An article on Alex Korn site gives a php script he used to extract the file content section of Chrome cache into a text file. It won’t be that simple in my case because my content is binary but it’s a good start. Alex Korn had his text file directly visible. The first time I ran this php script, I had errors extracting the gzip file (corrupted data). After a closer look it’s because of the reg exp used in the preg_match_all. Some data on the right side (binary) could match the reg exp and inject invalid bytes. I replaced the reg exp by using spaces (\s) instead of whitespaces (\b) and added code to directly decode the gzip data. This is the full script I used:

// cache.log is a copy of chrome cache page with only the file content section
$cacheString = file_get_contents("cache.log");
$matches = array();
preg_match_all('/\s[0-9a-f]{2}\s/', $cacheString, $matches);
$f = fopen("t.bin","wb");
foreach ($matches[0] as $match)
{
  fwrite($f,chr(hexdec($match)));
}
fclose($f);

ob_start();
readgzfile("t.bin");
$decoded_data=ob_get_clean();
echo $decoded_data;

And that did it, I finally recovered my file!

Conclusion

I know this article is really specific but as I said in the beggining, I really hope people looking for this information will find it here instead of spending as much time as I did figuring it out.

You can follow me on twitter or facebook, and feel free to comment this article here.

My Experience Converting from XNA Game Studio 3.1 to 4.0

Sunday, October 31st, 2010

Microsoft released a big update to XNA Game Studio with version 4.0. The main improvement is Windows Phone 7 support. I will probably not develop for WP7 (see reasons below) but I still need to upgrade my current Xbox 360 project from XNA 3.1 to 4.0.

The process was not as smooth as I though it would be, so I wrote this article to help people transitionning from 3.1 to 4.0.

Upgrading to XNA 4.0

To install Game Studio 4.0, you normally need Windows Vista or Windows 7. However, Microsoft made a version for Windows XP working only for Windows and X360 projects. I don’t want to buy a new OS, therefore I am going with this “light” version. However, this version does not support Windows Phone 7. That’s a shame as I’d be interested to try things with a touch screen but upgrading to Windows 7 is expensive.
To install GS 4.0, you need Visual C# 2010 Express, and to get Visual C# 2010 Express on XP, you need the Service Pack 3. Problem: SP3 install failed for some strange reason. I could find this article on Microsoft’s site: When you try to install Windows XP Service Pack, you receive the error message “Access is denied” and the third solution consisting in running command line utilities solved my problem. I was not really sure what I was doing, but it finally worked :)

Converting the Project

When opening a GS3.1 project with Visual C# 2010, it automatically tries to convert it to GS4.0. Each project of the solution is converted. Of course, if you are using a compiled library (dll), you need to get or compile a 4.0 version. I had to re-compile Box2D.XNA and download the latest version of TiledLib’s dlls.

However, I had a problem when compiling for the first time, with the following error: “The referenced assembly “Microsoft.Xna.Framework.Content.Pipeline, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553″ could not be resolved because it has a dependency on “Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” which is not in the currently targeted framework “.NETFramework,Version=v4.0,Profile=Client”. Please remove references to assemblies not in the targeted framework or consider retargeting your project.”
Luckily, one guy had the same problem on Creators Club forums and the solution given by Stephen Styrchak solved my problem. It should be solved by changing the Target Framework in the application properties, but the option is greyed out. I had to edit my csproj manually with a text editor.

API changes

Ok, this is where the conversion really starts: fixing compiling errors due to numerous API changes in the framework. Here is a list of the main changes that affected my project:

Color struct: The Color struct has moved to XNA.Framework (from Xna.Framework.Graphics). A few constructors have also been removed, such as this one: Color( Color, float). I used it a lot. Easy to fix but Color is widely used in my project so that involved many changes.

Vertex buffers and Effects: There has been a few changes with vertex buffers and effects. There are many portions of code to update because of that but the new API is really simpler and better. For instance, you do not have to do Begin/End on effects and each pass, but you just use Pass.Apply: Less code to write for the same result. Also, when you have standard vertex types, you do not need to use VertexDeclarations. The GraphicsDevice.VertexDeclaration member has been removed. Again, less code to write!

Pixel/Vertex Shader compiler : I found the compiler more strict. For instance, I had a texture and a technique with the same name, it did compile with GS 3.1, but not with GS 4.0. I also had a pixel shader function called PixelShader and it does not compile on GS 4.0.

Point Sprites: They simply have been removed. I don’t use them in my current project, but my last game Spring Up Harmony used point sprites for the back ground effect. It takes some time to update to triangles.

Render Targets: In addition to a few simple API changes when setting render targets, the most notable change is the removal of the ResolveTexture2D class. You now need to use a RenderTarget2D and can’t directly get a texture from the backbuffer.

Storage changes: A few API changes have been made in the storage too. Biggest change is the OpenContainer method that is now asynchronous (Begin/EndOpenContainer). A few functions have been renamed too.

Executing of the Game

Ok, now that the game compiles, let’s run it! And another problem occured here: The game does not run at all and asks for a DX 10 graphics card. Easy to fix: modify the XNA project properties and choose “Reach” instead of “HiDef”. Difference is that Reach has a limited API for WP7 but should be enough for me.

References

Here is a list of resources/blogs that I found very useful while converting my game to GS 4.0. You should read them all ;)

MSDN Page: What’s new in XNA Game Studio 4.0

Shawn Hargreaves’ blog: articles on Vertex BuffersEffects, removal of point sprites, render targets.

Nick Gravelyn’s blog: article on storage in GS4.0

Done

And voilà! Conversion is done and the game runs properly (I did not test thoroughly yet). I was worried the new default use of premultiplied alpha would cause problem but I haven’t found any. If you had a problem converting your project that is not mentioned here, feel free to comment!

3 Simple Tips to Avoid Memory Allocations with XNA/C#

Friday, May 21st, 2010

Long time without posting. I’ve spent a lot of time working on the game, contracting art, buying sound effect and music assets, designing the levels… New screenshots/video should come very soon.

Anyway, back on topic: when developing from C++ to C#, I found out very strange that you can allocate memory but you cannot free it and have to let the garbage collector do it. But I finally got quickly used to it and found it quite handy… Until I found out that garbage collection is not free and usually causes framerate drops, especially on X360.

clrprof

Using the CLR Profiler (screenshot above), you can easily see where you are wasting memory (well, it can be scary the first time you see it but in fact, it’s easy). I nearly removed all my runtime allocations with this tool, here are the few tips that can be useful:

1. Be careful with the class string

String is allocating memory every time it returns a new string. StringBuilder is the key to the problem. I didn’t even know what StringBuilder was before working on memory and now I use it everywhere I need to take care about memory. There are some awesome tips (and source code) about StringBuilder on Gavin Pugh’ blog. Especially this and this. You have everything you need now :)

2. Reuse your lists

I had multiple sections of code creating a temporary List<> in order to add elements to need a special treatment. This was in an update function in my case. It is handy and fast to write code like that, but it allocates memory. To fix this, I know have the List<> as a member of the class. I clear it and reuse it when needed. When creating a list, you should use the constructor with an int used to define the default capacity of the list. (List<Vector2> l = new List<Vector2>(64) for instance).

3. foreach loops

I converted my foreach loops in C++ like for loops and it saved me some allocations. Memory allocated due to foreach loops on lists is showing up in the CLR Profiler as System.Collections.Generic.List<T>.

Conclusion

I hope you’ll find this useful. In Spring Up Harmony, I still have some run-time allocations, mostly in the particle engine, when a new fx is launched (I use Mercury for now). However, it seems that the garbage collector is not causing hick-ups therefore I’m ok with it.

Yes, multi-threading in XNA/C# can be that simple!

Wednesday, April 14th, 2010

I never really liked multi-threading, because of all the additional problems it creates: synchronization, deadlocks, concurrent access to memory… But with my recent experience with multi-threading in XNA/C#, you can really do simple and efficient optimizations.

While looking for possible performance improvements in Spring Up Harmony for Xbox 360 (PC), I have seen a simple situation really suited for multi-threading. You can see that situation with the following screenshot of my in-game profiler (click to enlarge):
Frozax-4
I have two tasks with performance issues since I started to run the game on Xbox 360 : the dynamics of the background effect and the computation of the estimation of the launch of the ball (running a simplified physics simulation multiple times, through Box2D.XNA). On this screenshot, these tasks are called VelGrid.U(9) and Launchers.U(14). The first part of VelGrid.U (Comp.Balls,10) uses the data of the physics simulation but DynaColLines(11) doesn’t. Therefore, the VelGrid.DynaColLines and Launchers.U are totally independent with each others. No data is shared between these code sections. Perfect candidates for my initiation to multi-threading in XNA! :)

The e-book found here (recommended in multiple threading articles) is really awesome and helped me find the algorithm I need to use. I want to start the Launchers.U at the same time than VelGrid.DynaColLines and wait until both are finished. I know this is not optimal, but it allows me to simplify the problem and avoid so many threading pitfalls.

I just have to use two AutoResetEvents. The Launchers.U section is created in a thread and waits for a “Go” signal from VelGrid. After doing its job, it sets a Ready signal so that VelGrid knows when to carry on after doing its own stuff. Two different cases can happen, depending on which section finishes before the other.

Here are screenshots of the in-game profiler showing the differences (taken on X360). Every code section prefixed by a * means it’s executed on the thread.

Case 1 : The code on the main thread completed before the code on the worker thread:

thread_slower
The Velgrid section has to wait for the Launchers to complete, shown with the red arrow.

Case 2 : the code on the main thread completed after the code on the worker thread:

thread_faster

The thread is idle while the main thread still works (red arrow).

With this simple threading mechanism (coded and tested in a few hours only), I have been able to optimize the game. In the basic test level shown here, instead of 2.3 + 3.1 = 5.4 milliseconds spent on the main thread for both features, the game now spends 3.6 milliseconds, running two threads at the same time (33% gain). In this test scene, the Velgrid.DynaColLines is “free”.

Since I took these screenshots, I have made a few more changes : now, the whole Box2D update used while the game is in motion is threaded too.

Last important thing to know, on Xbox 360, you must choose which core to use for your thread. Just read the msdn page about the SetProcessorAffinity, everything you need to know is here. You can see in this article that I still have a few cores available :)

In conclusion, if you have independent sections of code that take some time to run, you can improve that very quickly using this method.

On-screen profiling for XNA

Wednesday, April 7th, 2010

A few days ago, I read an article called Among Friends: How Naughty Dog Built Uncharted 2. The interesting screenshots on the third page gave me the urge to create what I call an “on-screen profiling” tool for Spring Up XNA. I talked before about profilers and how to use them to find which sections of your code need to be optimized. But a visual tool is really handy, because it’s real time, and with Edit and Continue on PC, you can even see your improvements live!

So, I spend some time working on it, and here is a sample screenshot (click to enlarge):

onscreen_profiling_sample_x360The bars show the timeline of the current frame. In the bars, there is the name of the section. For clarity, all profiled sections are also displayed in plain text with the following informations: Name, Time elapsed this frame (in millisecond), smooth time elapsed, percentage of the 60 fps frame (16.6 ms). The vertical magenta line is the limit of the 60 fps frame. On this screenshot, my objective of 60 fps is not met, there are some bars displayed after it :)

I am really happy with the results, you instantly see where optimization is needed and you also see the results quickly. For instance, after seeing the previous screenshot, I concentrated on the “Velgrid.D” section (section drawing the background effect that is seen in motion here). After some improvement, it still was not fast enough. I noticed that the problem was simply the overhead of calling SpriteBatch.Draw more than 5000 times. I therefore decided to write my own vertex+pixel shaders and you can see the result here:

onscreen_profiling_final_x360It’s now so fast that we can’t even see the name of the section in the bars and I have to have a look at the list to see the exact time taken by this section of the game (number 15).

The profiling works obviously on both Xbox 360 and PC so I could compare both hardware. As I could read here and there, the X360 build is much slower than the Windows one. I made two screenshots of the same scene with a scale of the bars so that the length in pixels of the full frame is around the same on each platform. Here is the screenshot of the windows build that you can compare to the first screenshot of this post: 
onscreen_profiling_pc_scaled

The “slower” sections are not the same. Globally, the X360 is better at using its GPU and the PC using its CPU. Of course, this is heavily dependant on the PC platform. For information, I am using a 3.4 GHz computer with a X850 graphics card.

And just for fun :) , the first screenshot of the profiler on X360, before I started any optimizations:

onscreen_profiling_first version x360The frame took 165% of my objective target frame (60 fps). I can’t even see it all on screen. I am now at 75% of the frame, and with an additional feature (glow around objects, section 9 on the second screenshot).

So the small amount time taken to make this in-game tool is very well spent. It’s obviously quicker than running a profiler and waiting for the results, even if it’s not as precise. And the great thing is that this was easy and interesting to program :)

First Run on Xbox 360 : Problems and Solutions

Friday, April 2nd, 2010

I decided about a month ago to start working on the Xbox 360 version of Spring Up in April. I think it can be interesting to share my experience about that.

Part 1 : XNA Creator Membership

Basically, you just need to pay creator membership (99 € for one year in Europe), launch XNA Game Studio Connect on your console and that’s it.

Problem 1 : You have problems to redeem your XNA account to a new X360 profile?

Solution 1 : Do not mix up your forum name and GamerTag. Yes, this one was easy but it took me at least 30 minutes to find out what was happening. :)

Problem 2 : XNA Game Studio Connect does not recognize your account as premium when you launch it even though you paid for membership?

Solution 2 : You have to wait for some time (a few hours, maybe half a day) and everything will be fine. Quite frustrating, I know.

Part 2 : Compiling your game for Xbox 360

Microsoft made something simple : just right click on your project in Visual C# and choose “Create copy of Project for Xbox 360″. I took my main project and all the dependencies were converted too.

Problem 3 : You have very strange compiling errors? When converting Box2D.XNA, I had weird errors such as “Class C does not implement inherited abstract member M” AND “no suitable method found to override M”.

Solution 3 : Make sure you use the proper version of assemblies. I don’t know why but the converter put assemblies of XNA 3.0 instead of 3.1. Using 3.1 assemblies fixed my problem.

Problem 4 : The code does not compile but it works fine on Windows?

Solution 4 : Make sure you do not use windows specific code. You will be able to see warning icons if you have invalid assemblies in your Xbox 360 projects. If you want to keep windows specific code, just use #if WINDOWS / #endif so that it compiles properly on Xbox 360. In my case, my level and dialog box editors are only available on windows because it needs to create XML files.

Problem 5 : You can’t build your XNB data from XML using your own classes?

Solution 5 : Make sure the Content projects still have references to windows builds. Resources are built on the development computer, using the windows assemblies.

Part 3 : Running the Game on Xbox 360

Problem 6 : Code 3 Error?

Solution 6 : When you have Code X errors, it is because the console hangs without being able to break or throw an exception to the debugger. To track this problem, I simply traced the code I suspected. As the problem happened on a specific action, I could easily see where was the problem. My problem was just a null pointer access that happens only when there is no savegame. I always have a savegame on PC, so I did not see the problem before. The strange fact is that when I traced the code the second time, I properly had the NullPointerException.

Problem 7 : Your game is slow?

Solution 7 : I knew Xbox 360’s are usually slower than PCx with XNA but I was still very surprised my I ran my game for the first time. I immediatly launched a release build to try to reassure myselft but it’s still quite slow. I am not sure what is the problem for now so I will improve my profiling code to see which GameComponent is the problem.

Conclusion

That’s it for my first run on X360. I hoped this helped some of you!