Phil Hassey - game dev blog
Phil Hassey as Snidely Whiplash
"You can't buy awesomeness.
You're born that way."

Archive for August, 2010

Galcon and Cosmic Nitro come to the Palm Phones!

Monday, August 30th, 2010

FACT: You either own a Palm Pre / Palm Pre Plus Phone or know someone who does! Let’s do this.

palm-galcon
Galcon for Palm
palm-nitro
Cosmic Nitro for Palm *FREE*

Here are some sweet games my friends created for the Palm platform – check ‘em out!

Smiles by Sykhronics Entertainment

Ancient Frog by Ancient Workship

Thanks!
-Phil

P.S. Galcon and Cosmic Nitro may also be available on the Palm Pixi eventually, so keep your eyes open!

Android Day 11 – Troubleshooting

Friday, August 27th, 2010

Hey, so Galcon has been on the market for about a week and some. I’ve gotten plenty of feedback, so it’s time to do a bugfix update to address a few issues.

Item 1 – Backspace doesn’t work with Swype keyboard.

This is because the Swype keyboard is broken. Amusingly enough in earlier betas it wasn’t broken, but the latest one that everyone seems to have is broken. If you are part of the Swype beta you should send them feedback pointing out that the backspace key doesn’t work with some applications because the Swype keyboard is failing to send onKeyDown and onKeyUp events when users press the delete key.

As a workaround, I’ve added a message on the Settings page to tell users “Tip: you may have to switch to the default keyboard to press delete” .. Another solution would be to have a dialog pop up that they can do text input into. A fellow Android dev has outlined how to do this.

Item 2 – Application won’t install

The Android Market has some oddball bugs here. Beats me what is actually going on but the advice I’ve heard is:

1. Launch “Google Talk” .. That may help.
2. Reboot your device. That may help more.

Anyone got any other tips on this sort of problem?

Item 3 – The License check fails

So it seems that when the network isn’t on, the licensing check sometimes fails. This causes user rage. To remedy this, I’ve adjusted the dialog that pops up to include a Retry button and further explanation. “Tip: if you have purchased this application, press Retry a few times. It may take a minute to connect to the licensing server. If that does not work, try rebooting your phone.”

Item 4 – Crashes when starting up the browser

I’ve gotten reports from a few users about the game crashing when receiving calls or when they go to a browser. I have been unable to reproduce this issue locally. If anyone has more details on this, I’d appreciate whatever they can come up with. If you can send me a copy of the Android log, that would be helpful too!

Item 5 – Screen stretched

Since this is an exact port of the iPhone (480×320) version of the game, this was a choice I had to make. It was either a stretched screen or letter-boxing. I decided a stretched screen would be the better of the two evils. The reason this is an exact port of the iPhone version is that makes it cross-platform compatible with the iPhone for multi-player games! No matter what option I take here, it isn’t going to be ideal because everyone has to have the same map on their screen to be able to play against each other. This is the cost of being on a platform with no standard screen sizes or aspect ratios.

Anyway, I’m pleased with the update. I wasn’t able to fully correct everything since most of these issues are out of my hands, but at least I’ve added some textual tips that should help people get through the main issues (#1, #3). #2 unfortunately I’ll have to continue to handle via support emails since the game isn’t even starting at that point. And again, if anyone has #4 affecting them, I’d appreciate more feedback.

-Phil

Galcon Labs FREE – This Weekend Only!!

Friday, August 20th, 2010

Hey,

As part of the “Community Restoration and Rejuvenation Act” I’ve changed the price of Galcon Labs for the iPhone to FREE for the weekend! This is a great opportunity for you to get all your friends in on the Galcon multi-player frenzy! So Go GO GO! Twitter about it! Facebook about it! Email about it! Get the word out!

labs550

Thanks!
-Phil

Android Day 10: Implementing License Server

Wednesday, August 18th, 2010

So .. License Server came out about a week ago. When I heard about that I was all, “eh, more DRM, why bother, the users won’t see any benefit, so it’s not worth my time.” Turns out I got that wrong! There are actually several concrete benefits to the user by using the License Server (which I found within a day of releasing Galcon due to the quantity of emails from users explaining my failure to care about them!) If you use the “Copy Protection” feature of the Android Marketplace publisher, you do two things to the user:

– The app will take up twice as much room.
– The app cannot be stored on the user’s SD card.

I covered some of this in a previous blog, but the users memory is very limited, so over utilizing it is a “bad thing”!

The documentation for the Licensing Server is really really long looking, but there isn’t that much you have to do, actually. You’ll probably want to read it, but if you want the synopsis of what you actually end up having to do, here it is:

Step 1: Install the LVL SDK.

You just power up the SDK installer software and find the “Market Licensing package” and install that.

Step 2: Copying the LVL SDK into your project.

Just copy path/to/android/market_licensing/library/src/* into your local src/ folder. The SDK isn’t part of the Android platform, so you have to include it in your own codebase.

Step 3: Get your app to check the license using a Policy.

You can do some complicated things, but the documentation says, “… don’t do that. Just use the included ServerManagedPolicy or StrictPolicy.” I’m going to use the ServerManagedPolicy because that doesn’t require the user to ALWAYS be on-line to use your App. The StrictPolicy only works when the user is on-line and checks the license every time.

At this point, you’ll want to just go find path/to/android/market_licensing/sample and check out the source there. It includes an example that will pop up a dialog to send the users off to buy your app if they don’t have it licensed properly. This seems to be pretty much what I want, so I’ll just copy-n-paste from that.

Tips:

– To grab your public key go to http://market.android.com/publish/ and click on “Edit Profile” and your key is at the bottom of the page.

– You’ll (maybe) want to grab the example res/values/strings.xml and paste the Licensing related strings into your own strings.xml

– applicationError(ApplicationErrorCode errorCode) should call dontAllow()

– add finish() after the app goes to the market Intent. This way, they can’t go back to the app and get pestered about buying it again. They will have to restart the app and the license will check out fine.

Step 4: Testing it out

You can test out your app by again going to http://market.android.com/publish/ and clicking on “Edit Profile” .. at the bottom you can add market user emails that are being tested and you can change what license response you want to force out to the user.

Tip: be careful not to hit the licensing server too often, or you’ll start getting 503 errors which indicate overuse of resources. These take a while to reset.

Step 5: Adding a demo mode

You may want to add a demo mode to your game if licensing fails. Or somehow stop the game entirely, because the AlertDialog seems to be full of “holes”. That dialog will disappear and reveal your game under a number of scenarios. So don’t count on it blocking the user.

I just recall showDialog(0); in onTouchEvent if the game is in demo mode to keep bringing up the dialog again. I suppose a less annoying way to do it would be to respawn the dialog every minute or something. But maybe I’ll do that later!

Step 6: Applying ProGuard code obfuscation

This step is highly recommended by the Android developer guide. It would be nice if this were built into the Android toolchain, but it isn’t. Here’s a blog post that tells you how to do this.

However, I found that the binary that got build crashed. I’m not sure what is going on, but I’m guessing the NDK and ProGuard just aren’t getting along somehow. I’m going to leave out ProGuard for the time being. (I gave this a few hours effort. Again, this is where having support as part of the Android developer’s kit would be great!)

Update: this blog post explains what you need to do. Beyond that, you also need to handle your native methods and callbacks properly.

Step 7: Enabling Install on SD Card!!

This step is basically the whole point of this entire blog post. This gets the app out of the main memory on the device and onto the SD card for the user’s improved happiness.

To do this, add android:installLocation=”preferExternal” to the manifest tag in AndroidManifest.xml

Also change target=android-8 in default.properties.

And that’s that!
-Phil

Galcon for Android has ARRIVED!

Monday, August 16th, 2010

Hey, it’s been a wild ride, but the Android edition of Galcon has ARRIVED!

newandroidshot

qrcode

Have some fun! Be sure to tell your Android toting friends that this is the real deal! This now puts Galcon available on about 70 new types of phones! Crazy!

-Phil

P.S. If the links don’t work, just search for “GALCON” in the store :)

P.S.S. I’ve updated the links so they should work now :) Thanks to everyone who emailed me how to do that!

Android Day 9: Taming the G1

Saturday, August 14th, 2010

The G1 is the baseline Android phone. I found that users who tested with one of them were getting low framerates and crashes. Since the G1-level-devices are about 20% of the market, I wanted to be able to support them. Here’s the journey I took:

Step 1: Getting and activating a G1

Getting one was relatively easy. They are no longer produced, but I found a good one on eBay and with shipping and everything it was only $137 to get it. Activating was another matter altogether. The phone is locked so that you have to sign into your Google Account upon startup to activate the phone in order to get to the Home screen. After reading numerous tips on the internet, the way I was able to activate it was by borrowing a friend’s SIM for a few minutes to activate my phone. Then I put a dummy SIM back into mine and things worked fine.

Step 2: Fixing crashes

As I’ve found, the event loop and the graphics loop are in two separate Java VM’s on the phone. Some tweaks I had added to get it working on the Nexus One / Droid were not working on the G1. Again, global variable hacks coming back to haunt me. I adjusted some of my hacks and it seems to be working on the G1 now, so I’ll have to re-test on the Nexus One / Droid later. The lesson here, again, is avoid using globals in C if you can, because a lot of how the whole Android setup is makes it a real pain.

Step 3: Graphics performance improvements

The graphics were going at about 2 FPS. Which was not acceptable. I did a lot of investigating and I found that this one thing got me from like 2 FPS to an acceptable (though not blazing) 15 FPS or so. I changed my bitmaps from their default format to ARGB_4444. I do this during my load_texture method:

Bitmap bitmap = BitmapFactory.decodeStream(stream).copy(Bitmap.Config.ARGB_4444,false);

That was all it took! However, I’d like to have it be ARGB_8888 on higher-end phones if possible. I’ll see if I can figure out a way to do that. It’s a bit of a tough call, because on the Droid the 4444 improves the framerate, but if you look closely you can see a difference from the 8888.

One way would be to detect the SDK version, however, I hear rumors that older devices might be getting an update to 2.x. So that wouldn’t be foolproof either. I think I’ll be sticking with 4444 for now. It improves the framerate on most devices and the visual change is pretty minor in the larger scheme of things.

Step 4: Removing warnings about “call to OpenGL ES API with no current context”

These warnings are just annoying. Basically they happen anytime you do a gl call when you aren’t within your rendering method. It took some hunting but I found a few calls that were doing this in my Pause pop-up screen. This was simply a job of decrufting my code a bit. (I had OpenGL code that was from the very first version of Galcon for the iPhone that was being called in code that isn’t supposed to have any rendering in it anymore.)

I think I’m getting pretty close to releasing this game. I’m going to run this build by the testers again and see how they like it. I hope to launch soon!

-Phil

Galcon Palm update

Friday, August 13th, 2010

Wow, it’s great to see how many people have been enjoying Galcon for the Palm Pre Plus! I have gotten some really great feedback, so I’ve put together an update! All of the in-game issues are related to the integration with the WebOS features, so I’m documenting the bug report and the solution here.

Item 1: Back gesture quits the app – Resolved, 95%

This was really easy. I just capture the SDL key event for SDLK_ESCAPE and handle that as a “back” button. The nice thing is due to all my work on the Android port where users demanded back button support, I had already added this feature! So coding this only took about 5 minutes. (The Android work I’m building on took a good day, so enjoy the back features, they work throughout the whole game!)

The only shortfall of this fix is that when you use the back gesture from the main menu the app doesn’t minimize, it just sits there. I could have it quit, but I’m not sure that would be better. I’ll have to see what users say. The PDK does not have a PDL_MinimizeApp() function or anything yet, so I’ll just leave it as is now. The user can still tap the gesture area to minimize the app.

Item 2: Reduce idle CPU usage – Minor, no ideal solution

One user noticed Galcon was still using 2% cpu when minimized. This is probably due to OpenGL rendering, which I really don’t need to continue doing when the app is minimized. I considered reducing this to 0%, but if you are paused while in a multiplayer game you might want to be able to see the occasional visual update to the game. And when you are really done playing anyways, it’s best to quit the game anyways. So for now, I’m leaving this issue as-is, since I don’t think it would be an improvement to change how it works now.

Item 3: Respect the phone’s mute switch – Not a bug

I did a bit of searching in the Palm developer forums and found this answer: “No, the mute slider can’t be checked. When I asked our interface team about this, they say that the switch is a “ringer mute” switch, not a general system mute, so it doesn’t affect the volume of game or navigation programs.” So, yeah, sorry, nothing I can do about this.

Item 4: Local multiplayer not working – Minor, no solution found

I got a report from a user that local multiplayer wasn’t working, and it seems that is the case. I tried using “PDL_SetFirewallPortStatus” to enable access to the Galcon port, but that didn’t seem to improve it. From checking in the forums it might be something a bit more complicated relating to how the firewall / networking works on the phone. Fortunately, you can do 1v1 games if you just join a 1v1 server with your friend at the same time, so this is a pretty minor issue in the grand scheme of things.

Item 5: Unable to type numbers – Workaround warning added

This was a known bug from the beginning, due to how the PDK and SDL works, when a user presses the number pad and then presses a number key, a letter is sent to the SDL app. The only way to get a number is for the user to hold down the number pad key and the number key. The Palm developers have told me that my options are to hack in a translation (which wouldn’t respect international keyboards), or wait until a future release for a PDK function that could do a translation for me. Since a hack that would break it worse for some users isn’t any good, and I want to do an update soon, I’ve decided to do the next best thing and prompt the user with a tip at the top of the Settings screen telling them of the physical workaround of not letting up on the number-pad key.

So, not a perfect update, but I’m very happy that I’ve been able to develop a solution for the back gesture .  And I think the addition of the warning with the keyboard issue is a reasonable workaround.  The other items I’ve verified, but not found ideal solutions for.  I also want to add Pixi support, but I hear that 1.4.5 isn’t going to be released to the Pixi, so there isn’t much rush for this to be put out.  Once I get ahold of firmware to dev on the Pixi I’ll try and update Galcon for it though.

-Phil

P.S. I’m just about to submit this update, so it probably won’t hit the store for a couple days.

Galcon for Sixense

Thursday, August 12th, 2010

I spent the first few days this week integrating Galcon with the Sixense motion controllers! It was a nice break from the work on the Android as I waited for a G1 to get shipped to me (I’m not sure if Galcon will work on the low-end phones yet, but I’m going to find out soon!)

galconsixense

Working with the Sixense was very different, the controllers are great, and it really provides a completely unique Galcon experience. I modified the game to allow all modes to be played Co-Op with multiple users (mouse + up to 4 Sixense controllers). And I also added a special Sixense Multi-player mode where you are divided into two teams and can play against each-other.

Like with any interface design I always try and fit Galcon to the device. In this case, I had to modify a few subtle things in the user interface to make it work just right with the Sixense. I also set one of the controller’s buttons to be a “Select-all” and a “Deselect-all” button, which makes it easy to do those common actions. So I think I’ve done a pretty good job matching the Sixense controller interface with the Galcon interface. You can also see in the screenshot that each controller gets a different color for their planet selection / action choices, and the crosshairs contains the Ships % information. The mouse player still goes off the standard Ships % that’s show in the bottom right corner.

All-in-all, I think this variant of Galcon is going to be a ton of fun! I have no idea when it will be available for people to play, but I’m sure it’ll be good times when it is!

-Phil

I have all these cellphones, but I don’t know how to use them!

Saturday, August 7th, 2010

So, turns out I’ve got a lot of cellphones now. But, in fact, I have service for none of them! I just use the Wi-Fi to test my games.

But, I found at GDC earlier this year when I first got the free Droid from Google (with free service for some amount of time) that having a cellphone with 3G in a city is super convenient! I was able to navigate the city and use busses and do all kinds of neat city people stuff. Wow! I even saved myself $50 by taking a bus to the airport instead of taking a taxi! Neat!

Unfortunately, eventually the free service period ended. The trouble is, when I check the Verizon website (which seems to be the carrier for Droid and Palm Pre, etc) they want me to buy a phone for $500 to get cell service. And maybe get a contract, or something. It was all very confusing and sounded pretty expensive.

But I just want to pay for a single month of 3G+voice+text service for one of the phones I already have. Or maybe I’d want to pay for some really basic voice service year-round and upgrade to 3G fancy stuff during the couple of conferences I go to. Or maybe pop on some service for like a weekend once in a while when I go to a city or something. Either way, I’m entirely unsure how to navigate the wide-world of cellphone plans.

Help me!!!
-Phil

P.S. I have a Nexus One, a Droid, a Palm Pre, and soon: a Palm Pixi and a G1. I’m entirely unsure what I can do with all these phones, but I want to be able to make calls and use 3G from time-to-time!

Android Day 8: Bug fixin’

Thursday, August 5th, 2010

Step 1: Handling Back / Menu events.

Several people mentioned that it’s common to respond to pressing the BACK / MENU / HOME / SEARCH buttons on the bottom of your Android device. At least, BACK / MENU. I investigated the options and there are some methods for Activity that can be added doBackPressed, onMenuOpened, onUserLeaveHint, onSearchRequested. However, not all of these are supported in Android 1.6 (doBackPressed). And also, they all seem to work a bit differently.

What I found was a more direct approach to dealing with this was to capture the KeyUp events in onKeyUp. The keycodes are KEYCODE_BACK, KEYCODE_MENU, KEYCODE_HOME, KEYCODE_SEARCH. To capture them you just return “true” from that method and they won’t work anymore, except for HOME which works all the time, so leave that alone. If you really care, you’ll need to use onUserLeaveHint. Ideally you’d check for isCancelled, but again that’s not supported on older devices. I set up Galcon to intercept the BACK and MENU buttons to send an event to my code to fall back to pause screens. And I set it up to ignore the SEARCH button so that a user wouldn’t accidentally bring it up in-game. The HOME button I left alone.

Step 2: Getting OpenGL ES 1.0 compliance

I found that on low-end Android devices like the G1 and the Droid Eris, the visuals were not displaying properly and the log was showing a ton of “E/libEGL ( 494): called unimplemented OpenGL ES API” errors.

This was due to my use of the “glColor4ub” function which apparently isn’t supported. I changed those calls to “glColor4f” and that resolved that issue. I never found a decent way to figure out what function was causing the errors, I just figured it out by guesswork and trial and error. If someone has a tip here, that would be pretty great.

One issue I’m having is that the emulator running 1.6 is not displaying the game at all. I tried it with 2.1 on the emulator and it also does not display the game, so it looks like I might need to quickly attempt to acquire a G1 to do low-end testing on.

I also ran up against the GL stack at some point and had to reduce the number of glPushMatrix and glPopMatrix’s I was doing. A hint here is use glGetError() to find out if you’re getting any errors. This also seemed to clear up the emulator issues, but the emulator is running so slowly that I really can’t use it.

Step 3: Better keyboard support.

I found the soft keyboard input wasn’t always working quite right. This code snippet seemed to work better, maybe. The choice of SHOW_IMPLICITY or SHOW_FORCED is a lesser of two evils decision. Time will tell which decision will give me more tech support issues.

    public void toggle_keyboard(boolean show) {
        InputMethodManager mgr = (InputMethodManager)app.getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow (mGLSurfaceView.getWindowToken(),0);
        if (show) {
            mgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
            // On the Nexus One, SHOW_FORCED makes it impossible
            // to manually dismiss the keyboard.
            // On the Droid SHOW_IMPLICIT doesn't bring up the keyboard.
        }
    }

I wish there was a better way to do this that worked a bit more consistently, but this is the best I’ve come up with so far.

Step 4: Getting the application to quit and restart cleanly

It was requested that the “BACK” button quit the app from the main menu, which is the usual behavior of most apps. I added the call to finish() to force this to happen, but I found that whenever the app was launched again it would crash once, then on a second try it would work.

What was happening was this: the shared library “libigalcon2.so” was not being reloaded, so due to some failure on my part to smartly handle that, there were some critical values that were not being reset when the app relaunched. I had to carefully make sure to initialize those values on each start of my app. Here’s the symptom that clued me in:

D/dalvikvm(21863): Trying to load lib
    /data/data/com.galcon.igalcon/lib/libigalcon2.so 0x447a7048
D/dalvikvm(21863): Shared lib
    '/data/data/com.galcon.igalcon/lib/libigalcon2.so' already loaded in same CL 0x447a7048

Also note that the JNI_OnLoad was not being called each time my app was started up. It was only called the first time the shared library was loaded, so that was why on second launch my app would crash. (The real problem was I was saving the JNIEnv as a global variable, and it was not being reset when my app restarted.) Lesson learned: be very careful with globals!

Whew, that was a long day .. But we’re getting closer and closer to being ready!  The beta testers now report that the game is working nicely on all devices.  But they report that the framerate is awful on the G1 still, so we’re going to investigate improving frame rate yet.

-Phil