ANE for iOS with Custom Framework – Using Custom Fonts

We’re developing a set of games for iOS, some objective-C and some using Adobe AIR, and we’re using an iOS custom framework to hold a bunch of storyboard-based screens that we want to use across all the apps.

On the AIR side, we’ve created an Adobe Native Extension and figured out how to include our framework in it. This may be a subject for another blog post, because it was quite complicated, but this post really helped us figure out how to get all the images, storyboards, and sound files (among other assets) to get included in the ANE, and thus into the final app. We also used it to include our custom font file that the storyboards made heavy use of.

However, this was not enough. Using this post, I was able to troubleshoot all the possible steps that could go wrong. I had to make sure that the .ttf file got included in the final output of the framework, but the real key was Step 4 – adding the font information to your app’s info.plist file. Since an ANE is NOT an app, these keys need to go in the info.plist of the final app the ANE gets included in. But AIR apps use an Application Descriptor File, not an info.plist file. The info.plist file of the completed .IPA is auto-generated when the app is built.

Not to worry, Adobe has provided a place in said app descriptor file where you can specify items to add to the auto-generated info.plist. Appropriately enough, it’s called the InfoAdditions element. The content of this element must be wrapped in CDATA tags, and anything inside it will be added to the info.plist of the final app. So, in an XCode sample app, I followed step 4 above and created the required key/value in XCode’s graphical plist editor, and then opened the generated file in a text editor and copy/pasted those values. Here’s what I got:

<key>UIAppFonts</key>
<array>
	<string>name-of-your-font.ttf</string>
</array>

And here’s what that looks like pasted into an InfoAdditions tag in the app descriptor:

<iPhone>
	<InfoAdditions><!&#91;CDATA&#91;
		<key>UIAppFonts</key>
		<array>
			<string>name-of-your-font.ttf</string>
		</array>
	&#93;&#93;></InfoAdditions>
</iPhone>

I’ve omitted lots of other things that are in my descriptor for brevity – keys specifying minimum iOS version, custom URL schemes, which devices the app targets – but you get the idea.

Once I had this all put together, it worked like a charm! Our storyboards look great as ever with their custom fonts!

Install Android apps from outside the Play Store

The screenshots for this post are from my Samsung Galaxy Tab 2 running Android 4.2 Jelly Bean.

When you click on a downloaded .APK in your downloads app, your device will tell you that the installation is blocked. You’ll want to click the settings button.
androidoutsidestorestep1

Clicking the settings button in the previous image takes you to the settings app, where you will want click the checkmark next to “Unknown Sources”.
androidoutsidestorestep2

Once you do that, the device warns you that you do this at your own risk, because you could possibly download a malicious app that hurts your tablet. Read the warning carefully, and then click “OK”.
androidoutsidestorestep3

Now you can download apps from outside the Google Play store for testing, etc. Be careful and don’t download apps that aren’t from sources you trust, and consider turning off this capability once you don’t need it anymore.

Flash Builder 4.7 hangs loading workbench OSX

Today Flash Builder randomly started hanging while loading the workbench on startup.

I found a lot of places that said to delete the .snap directory located at [workspacelocation]/.metadata/.plugins/org.eclipse.core.resources but there was never a .snap file or folder.

Eventually I found a trick here that said the following:

remove all the <editor> elements in workspace\.metadata\.plugins\org.eclipse.ui.workbench\workbench.xml

I did that and at least got Flash Builder to start up.

You apparently can also delete all the files in the [workspacelocation]/.metadata/.plugins/org.eclipse.ui.workbench as well (this removes your custom window layouts), but I haven’t tried this method.

As a last-ditch effort, you could do one of the following:

  • delete your .metadata folder in your workspace folder. You will have to reimport ALL your projects after doing this.
  • close Flash Builder, rename your workspace folder (defaults to “Adobe Flash Builder 4.7”), and re-open Flash Builder. It will create a new, empty workspace. Then quit flash builder again, delete the empty workspace, and rename your old workspace to its old name. Hopefully when you start Flash Builder again, things will work better.
  • This post has the following workaround (copied here to protect against link-rot). This is for Flash Builder 4.5 but may work for 4.7.
    This happens because the Eclipse workspace gets corrupted. The easiest way I've found to recover from this is as follows:
     
    1. Use Windows Task Manager (Ctrl+Shift+Esc) to make sure FlashBuilder.exe isn't running as a process. End the process if it is.
    2. Navigate to your workspace folder (the default location is under your users folder in "Adobe Flash Builder 4.5", though you may have placed is elsewhere).
    Mine is c:\Users\grayson\Adobe Flash Builder 4.5
    3. There is a folder named .metadata (on Windows 7 there is an issue where it may appear as a nameless folder because Windows started truncating the "extension")
    move it to another location on your hard drive.
    4. Launch Flash Builder to make sure that this it has solved the issue.
    5. Close Flash Builder (this writes the default workspace settings to the .metadata folder in your workspace location)
    Inside the original copy of the .metadata folder you made, COPY the following folders to the same location in the newly created .metadata folder in your workspace folder, overwriting the files and folders that are there.
    .metadata\.plugins\org.eclipse.core.resources\
    .metadata\.plugins\org.eclipse.core.runtime\
    (as I mentioned before, Windows 7 can truncate the folder names to be without the last portion of the name, so you may see two folders that appear to be named "org.eclipse.core.runtime". Copying them will still work)
    6. This will restore the projects, workspace settings, and key bindings. (the dialog/window layout will be reset to the defaults and External Tool Configurations aren't copied. I looked but didn't find where those are stored)

FlashDevelop 4.6 BinaryHeader error on startup on Win64 8.1

Today FlashDevelop got stuck on startup into an infinite loop of the following error:

Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.

I found this really old forum post that said to delete the whole FlashDevelop app data folder.

So, I deleted/renamed the folder located at C:/Users/YOURUSERNAME/AppData/Local/FlashDevelop, and it works again!

FlashBuilder 4.7 Win8.1 x64 unexplainable java.lang.NullPointerException

This one’s a weird one. Sometimes Flash Builder 4.7 has a problem where weird errors come up in library code (Feathers, usually) that doesn’t have any actual errors in it.

The error raised is the following: com.google.common.collect.ComputationException: java.lang.NullPointerException

The (non-obvious) solution is to find a little button called “Mark Occurrences” in the toolbar and turn it to OFF.

Here’s a picture of what the button looks like when set to OFF:
mark occurrences off

And here’s what it looks like when set to ON:
mark occurrences on

Oh, and sometimes restarting Flash Builder doesn’t do it, so sometimes in order to fix it, I have to set mark occurrences to ON, close and restart FB, and then set it to OFF again to get it to work.

More info is available in this post in the Feathers forum here.

AIR for iOS Runtime Error #1520: Mutex cannot be initialized.

Situation: I’m making an app for iOS and Android using Flash Builder 4.7 and AIR SDK 4.0. It includes the Lua 5.2 interpreter as compiled from C code into a SWC using CrossBridge (formerly FlasCC). I’m just using the lua.swc file from the crossbridge samples. However, apparently there’s some problem with the multithreading code or something (is multithreading even supported in AIR 4.0? I don’t remember), because I get the following run-time error when debugging on the device (not on Android or AIR simulator, just iOS):

Error #1520: Mutex cannot be initialized.

Solution: I don’t know why this works, but if you add the following compiler options:

--swf-version=17

It works. This probably means I’m targeting an older flash player and one day I will need to figure out how to get the Lua interpreter code.

Here’s a pretty picture of the box where you enter the code in Flash Builder 4.7:
version17

Sensors in Box2D

Box2D has these things called “sensors”. What are they? They are shapes that can be attached to a body with a fixture just like any other, but the crucial difference is they don’t participate in collisions. In other words, something colliding with a sensor will never cause the object containing the sensor to change position, speed, rotation, or acceleration. “So, what’s the point?” you say. The point is you can still cause code to execute when these collisions begin or end, through your contact listener.

What good does that do? Plenty. You can use sensors to determine when any two shapes start or end colliding. You could use sensors to define field-of-vision for enemy units, create a proximity alarm when the player gets too close to laser tripwires or torpedoes, guide a heat-seeking missile, manage fog of war rendering decisions, or help enemies avoid crashing into other enemies and walls.

In my upcoming game Deep Space Demolition Derby, I’m using sensors in a few places. First, there is a big circular sensor surrounding the player:

20140408-015555.jpg

The above picture shows the game in debug mode, where the shapes overlaid on the sprites show the Box2D objects that represent the sprites for physics purposes. I have chosen to represent most of the objects in my game with circles. You can see a small circle around the player, and a small circle around each collectible crystal. This defines their physical extent – when those shapes touch, a collision has happened.

The large circle around the player is a sensor that doesn’t cause collisions, but causes collectible crystals and powerups to appear when you get close enough. Also, when you have a magnet powerup, any crystal that is within that distance will be sucked towards you.

Enemies have sensors to help control their AI. I put a couple of circles to the front left and right of enemies. These are like “vision” areas that help the enemy “sense” what’s in front of it to the right or left sides. When a wall or other enemy or the player overlaps either of those sensors, the enemy turns away to avoid a collision.

In the picture below, the enemy’s sensor has overlapped with the player and so it will turn to avoid a collision:

20140408-020112.jpg

The next picture shows the enemy has turned away and dodged the player:

20140408-020327.jpg

As development continues, I’m sure I’ll find a lot more uses for Box2D’s sensors. I’m excited to continue exploring this cool feature, and excited for the possibilities it has to improve my games.

FlashDevelop 4.5.2.5 crashes on startup under Win8.1 x64

I use FlashDevelop for a lot of work projects. It’s a much better IDE for writing code-based ActionScript 3 projects than Flash itself.

Today, out of the blue, it started freezing on startup while trying to load the last project I had open. I thought I’d post about it in case a.) it ever happens to me again, or b.) it helps you, dear reader.

A quick Google search produced this forum thread, which solved it for me.

The solution was to rename/delete the file C:\Users\[USERNAME]\AppData\Local\FlashDevelop\Data\ProjectManager\Settings.fdb, which probably got corrupted.

Back to work! 🙂