Testing Unity’s Flash Export on a Large Project – Part 1

Over the last weekend, I’ve been hard at work trying to get an unannounced Mind Candy project (made in Unity) to export to Flash. I thought it would be useful to share some details from the experience since most of the issues I’ve encountered would probably be avoidable if your project is architected in a way that lends itself to Flash export.

During the Christmas holidays, I made a game for Unity’s Flash in a Flash contest. It wasn’t the most exciting game, but it worked. The core mechanic of that game (including new 3.5 features such as nav mesh) exported to Flash well. The reason this game worked is because I had been paying close attention to the Flash export and knew what features wouldn’t work at that time. I avoided anything overly complicated and developed the game with the limitations in mind. Fundamentally, I decided to make a new, simple game rather than trying to port an existing one.

Now, I’m doing the opposite. I’m trying to get an existing game to publish to Flash. This project is a relatively large one. The game has been in development for quite a long time. It contains a lot of complex C# code and most importantly: a lot of features that don’t yet work in the Flash export. Trying to get this game to export to Flash is no easy task. I’ve spent numerous weekends on this since the 3.5 beta was made available and I still haven’t got it to work.

Despite the export (currently) not working for our project, there are a lot of lessons to be learned. Hopefully these will be of use to other people attempting the same task, and will be a good reference point for myself when I inevitably try to export the game again at a later date.

Currently Unsupported Features

Unity have already listed some of the unsupported features in the Flash export as part of the 3.5 preview faq. Some of these features (and the ones that have proved most problematic for me) are:

  • LINQ
  • Terrains
  • Asset Bundles
  • WWW
  • Raknet networking

If you’re using these features, then you’ll encounter a lot of errors as soon as you try to get Unity to build to Flash. Some example errors I’ve seen are:

Networking

  • error CS0246: The type or namespace name `ConnectionTesterStatus’ could not be found. Are you missing a using directive or an assembly reference?
  • error CS0246: The type or namespace name `NetworkView’ could not be found. Are you missing a using directive or an assembly reference?
  • error CS0246: The type or namespace name `BitStream’ could not be found. Are you missing a using directive or an assembly reference?
  • error CS0246: The type or namespace name `WWW’ could not be found. Are you missing a using directive or an assembly reference?

MovieTextures

  • error CS0246: The type or namespace name `MovieTexture’ could not be found. Are you missing a using directive or an assembly reference?

These errors are effectively a checklist of all the classes you’re using that aren’t yet supported and there’s only one thing you can do: remove them from your build. There are numerous ways to do this (depending on what you’re trying to achieve), from brute force deletion to telling Unity to skip these sections in a Flash build. You can do the latter by using platform dependant compilation.

All you need to do is wrap your Flash specific code in a platform check such as:

#if UNITY_FLASH
Debug.Log("Flash build");
#endif

In my case, the first thing I had to do was to try and remove these unsupported features. MovieTextures were easy to take out, as they’re not vital to our game. Networking, however was more problematic. And this is my first (and most important) lesson…

Lesson 1 – Separation of Networking Code

Our game currently uses the inbuilt RakNet networking solution. These networking elements are fundamental to our game, and as such, the networking code exists in many different areas of our codebase. When publishing to the web player or a standalone app/exe build this is fine. For Flash export, this suddenly creates a big problem when the networking solution isn’t yet supported.

As an example, if your game uses RPCs across clients to update core data in your game, then you’re going to have problems. I’m sure that there are other solutions which are better suited to Flash export, but this doesn’t fix my immediate problem: we have a game, where our chosen networking solution won’t publish to Flash. Unity suggest that you can use Flash networking instead of RakNet, but since I’m doing this export with tight time constraints (self imposed, by the mere fact it’s a weekend), that solution is not feasible for this test.

This has left me with one option in my mission to get our game working: rip out RakNet. This is not ideal, but luckily, our game copes with it ok.

This raises an interesting point in that the networking code should be as decoupled from the core mechanic of your game as possible. In some cases this can’t be done, but if you can find a way to make your networking layer easily removed/changed, then you’ll be in a much better place than I was regarding Flash export. It will also help you if you ever decide to switch to a different networking solution.

At this point, I’m going to gloss over about 10 other failed builds. It takes a few attempts at building to clear up this first wave of errors. Once you’ve cleared that first wave, you can breathe a sigh of relief and ready yourself for wave two: Attempting an actual build…

Attempting a Build

Once you’ve fixed/removed/hacked-out all the unsupported features, you’ll get to a point where the build process will now try to publish your game to Flash. The type of errors you get now will be more complex than those in wave one. Below is a screenshot of one of my build attempts at this stage:

You’ll note that these errors are more complicated than the “you can’t use ClassX because it’s unsupported” ones. In the case of these errors, it’s up to you to go into each of these classes and try to simplify your code as much as possible.

Some areas where our build failed were where we’d used generics. For example, we had fairly complex code to randomise the order of elements in an array. It wasn’t vital, so it went in the bin. This seems to be a common trend in trying to get this project to build to Flash. I’m slowly, over time, discarding features to the point where it’s a very stripped-down version of the game.

There are a couple of errors regarding our audio library in the above screenshot. This library wouldn’t convert at all (I got multiple waves of errors). My only solution at present has been to remove it.

The last item in that list is log4net. This caused a lot of issues. Rather than spending ages resolving them for this test, I decided it should also be removed. Since we used the logging in a lot of our code, I’ve ended up writing my own logging classes based on the log4net interfaces. This meant that I only had to fix up the imports in the class and our existing logging would still work using Unity’s own Debug.Log etc.

A few more iterations and build attempts occurred before wave 2 was complete. All in all, the first two waves have taken out large chunks of our features, and as a result the game feels somewhat unstable.

Akin to a game of [insert zombie survival FPS game of your choice here], we’ve just about survived the first few waves. We’re battererd, we’re bruised, but most importantly, we’re not defeated! We’re now ready for the next wave. Bring on the boss; the tank; the last major hurdle in the flash export – the conversion of your code to ActionScript.

Converting your code to ActionScript

At this stage, when you try to build, Unity will attempt to convert your source to ActionScript. Having previously spent years as a Flash developer, I find this part of the build rather exciting. The guys at Unity have done a fantastic job of getting this process to the stage it’s at.

That said, this is probably the toughest part of the process. Ripping out features and (to some extent) fixing the errors in the previous stage is easy. Trying to work out why the generated ActionScript doesn’t work is much more difficult. Luckily, when a build fails, you can find all the AS classes in a temp folder in your project (/Temp/StagingArea/Data/ConvertedDotNetCode/global/). This will enable you to look at them (if you wish) and try to understand where it might be going wrong, such that you can adjust your C# or js accordingly.

In my first attempt at this stage, I was left with 87 errors. The following are a small selection of these to give you an idea of the kind of problems I’ve seen:

Conversion Error 1

  • Error: Access of possibly undefined property $Type through a reference with static type Class.

This error seems to be very common and occurs when reflection is used (and probably in other situations). Unfortunately, a lot of our core libraries use reflection, and as such, this is a large problem to try and fix.

Conversion Error 2

  • Error: Call to a possibly undefined method IComparable$1_CompareTo_T through a reference with static type Number.

This has occurred because we’re trying to compare two values whose classes implement IComparable. In our case, this could be worked around relatively easily.

Conversion Error 3

  • Error: Type was not found or was not a compile-time constant: ReadOnlyCollection$1

In some of our classes we’re providing access to ReadOnlyCollections. It seems that we can’t use these at present and we could work round this by simply returning a standard Collection.

Conversion Error 4

  • Error: Call to a possibly undefined method String_Constructor_Char_Int32 through a reference with static type String.

A common style of conversion error that’s quite tricky to work out. I saw a lot of errors similar to this one.

These are just 4 of the 87 errors which need fixing. I expect that if/when all 87 are resolved, I’d have another wave or two to get through before the game would actually build. For now though, it’s Sunday night and I’ve run out of time to work on this test.

Next Steps…

My next challenge in this Flash export test is to go through the aforementioned 87 conversion errors and try to resolve them. I’m hoping that I’ll be able to get the game to build after another solid few days working on the export.

If that task proves too difficult then I will try a different approach of starting from a clean project and adding features one by one. In theory, that should be easier to get working, although that’s not how we’d want to export to Flash in the long run.

If I do get the export to work, I shall write a follow-up post with a walkthrough of some conversion errors. For these, I’ll include (where possible) the raw C#, the converted AS, and examples of how the errors can be avoided/solved.

For now though, I’m going to give up and play some well-earned Killing Floor! :D

Flash on the Beach 2011

Last month I went to Flash on the Beach in Brighton. It was the first time I’ve to this particular event and I really enjoyed a lot. For the few of you that don’t know, FOTB is an annual conference full of code, design and inspiration.

The three days in Brighton were full of inspiring stuff, like Carlos Ulloa new WebGL project, Lights, the Seb Lee-Delisle live experiment mixing OpenFrameworks, HTML5 and Phones, as well as lots of new people of the Elevator Pitches. Just check out the impressive main titles video created by Gmunk, creator of some of the FX for Tron Legacy.

Adobe showed some of the new stuff like EDGE, a Flash-like productivity tool to create HTML 5 canvas animations, and talked about Molehill/Stage 3D. They also talked about a new hardware accelerated framework for 2D animation in Flash recently released under the name of Starling. But all that doesn’t mean that that the “Flash is over” controversy wasn’t in the air, just check out the slide of Adobe’s official position on the question “When must I use Flash and when not?”.

Adobe posture on the Flash-HTML debate

Adobe posture on the Flash-HTML debate

Remy Sharp talked about this question too in “HTML5: Where Flash isn’t needed anymore”. He spoke about the fallback solutions when some features don’t work (usually using Flash), support of different parts of the specification in different browsers/platforms and the pitfalls that we will find on our path embracing this new standard.

In the closing speech John Davey, the creator and main organiser of the event, revealed that this is going to be the last Flash on the Beach! But don’t panic yet! It’s just a change of title and (maybe) format, to allow the conference to not be related with a single technology (i.e. the Flash platform) and be more based on design and creative coding (maybe something like the move of Flash Belt to The Eyeo Festival?)

Of course I’m leaving out a lot of things, like the interesting chat about kids games playability done by Jon Howard, or the demos of the new Away 3D using the new Stage 3D API, so don’t forget to check out the list of speakers and check out their individual sites.

LFPUG invasion!

Last Thursday Mind Candy had the pleasure of hosting the latest LFPUG meetup!  LFPUG or London Flash Platform User Group is a monthly meet up of Flash enthusiasts who either work in the industry or enjoy experimenting with Flash in their spare time!  Each month the members take the opportunity to talk about exciting projects and new technologies in the field.  The night was a great success around 50 people turned up.  Mind Candy provided beer and snacks and everyone had a chance to mingle and chat before the presentations began.

This month there were two presentations.  First up was Rob McMichael who talked us through the recent breakthroughs with Flex Mobile, he showed off some examples of how easy it is to use the Flex API with mxmlc and the sort of components that are currently available within the framework as well as upcoming features in the upcoming version of Flex. The second presentation was made by Tink who told us all about Flex Navigators and he talked us through some very impressive work he’s been doing on some open source navigators.  He showed off some examples of complex navigators that could nest themselves within each other and produce some beautiful effects such as 3D cover flow. It was a great evening and a great way to meet like minded Flash enthusiasts!

The next meetup is on the 27th October and features a presentation on the version control system Git and the methodology of Designers and Developers working in harmony.

Hope to see you there!

Unite11 – Exporting to Flash from Unity

Last week, four of the Mind Candy tech team ventured over to San Francisco for the Unite conference. One of the things I was most keen to learn about is the upcoming Flash export.

On the Tuesday, we attended the Flash afternoon where Lucas Meijer and Ralph Hauwert detailed the latest progress on Unity’s export to Flash. On first impressions, the games they’ve been working on look fantastic! One of the reasons I’ve been keen on working with Unity over Flash for 3D games dev is the awesome toolset, and these guys have really nailed the Flash export.

As long as your code isn’t doing anything too “exotic”, Unity will convert your code (c#, js (strict) and boo) to ActionScript. It will then compile this, along with your assets, into a swf using the mxmlc compiler. One thing to note here is that literally everything is compiled into that one swf. There was mention of them using asset bundles at a later date to generate individual swfs for content such as scenes. Since everything is in one swf, that means file sizes could get pretty large really quickly. One of the demo apps generating simple spheres compiled to a ~1.4mb (iirc) swf which is pretty chunky for something so simple.

The generated AS3 code is pretty readable although since there’s no method overloading in Flash, they’ve had to compromise on function names somewhat! That said, it should be pretty easy to debug your exported app.

The features currently supported in Flash are:

  • PhysX
  • Particle system
  • Custom and standard shaders

Things that won’t work in the first version include:

  • Anything needing depth textures
  • Advanced audio such as doppler and reverb
  • Dynamic shadows
  • Mouse lock
  • Unity networking (you’ll have to use a Flash networking solution for now)

Looking at the performance of the games, they seemed to run pretty well. They mentioned trying to push anything you can to the GPU rather than CPU. An example given would be to animate textures in a shader rather than scrolling it in a script, as well as the usual light baking and occlusion culling. Basically, as Lucas put it: “The best way to make your game go faster, is to have it not do stuff”.

So to summarise – from a first glance, the Flash export looks pretty awesome, and the Unity guys have done a great job getting it working. There are still a fair few features missing, but there should be enough there for most simple Unity games to be exported. Unfortunately, both the release date and the price were listed as “TBA”, so I guess you’ll have to wait a little longer before you can try it out.