Knight’s Puzzle Free in the App Store

June 9th, 2010

The free version of Knight’s Puzzle is now available in the App Store. This version has only the 5 x 5 game board and contains ads. The advertising was implemented using the method detailed my previous post about Admob ad support in Corona apps.

(Of course, if ads aren’t you’re thing, you’re more than welcome to purchase the full version of Knight’s Puzzle, which includes the 7 x 7 game board and none of that pesky advertising. :)

Admob ad support in Corona

June 3rd, 2010

(June 3, 2010 Update: Matt Pringle sent me an email to let me know that the sample files I provide in this post don’t work with beta 5 of the Corona SDK. It turns out that as a result of some bugs that were fixed in recently-released beta 5 of the Corona SDK, it’s necessary to include the following line of code in the html document:

<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

I’ve updated the html file in the zip package to include this code.)

Yesterday I spent some time trying to integrate Admob ads into a Corona application, and I thought I’d share the code required to make it work.
I’ve implemented this in a free version of Knight’s Puzzle that I’ve submitted for approval to the App Store, so there should be a real-life working version of this out there soon (knock on wood). There’s a bit of hackery involved since the Corona SDK does not have native support for any kind of ad model at the moment, but the results are quite good and the actual process is quite simple. You can download this zip file to see the code required to make this work.

Right now, Admob provides support for two methods of serving ads: one is Objective-C-based, for apps built in Xcode, and the other is html/javascript-based, for web apps. This method actually uses the html/js code, even though your app may be distributed through the App Store. In a nutshell, the method is to display html ads inside your Corona app using the native.webPopUp() method. A new feature in the Corona SDK is the ability to specify a custom size/location for the web pop-up, rather than having it take over the entire screen. We can use this feature to create a pop-up that is the same size as the mobile ads that Admob serves, and position it wherever we want in our app.

To get this working, you’ll need to sign up with Admob and create a new ‘site or app’ – you want to create is an ‘iPhone web’ site/app. Once you’ve done that, Admob will provide you with a chunk of html code that you’ll need – I won’t walk you through this process, but it’s very straightforward. You can see an example of the code that’s generated in the html document that’s in the zip package; the only thing that will be different for you is the value of ‘pubid’ (I’ve removed mine).

Next, the code to create the actual web pop-up and to handle the ‘clicks’ on the ad. This is all contained in the main.lua file provided in the zip package:

local adSpace

local function showAd(event)
     -- Is the url a remote call?
     if string.find(event.url, "http://", 1, false) == 1 then
          -- Is it a call to the admob server?
          if string.find(event.url, "c.admob.com", 1, false) == nil then
               adSpace.url = event.url
          else
               -- an actual click on an ad, so open in Safari
               system.openURL(event.url)
          end
     else
          adSpace.url = event.url
     end
end

adSpace = native.showWebPopup(0, 432, 320, 48, "ad.html", {baseUrl = system.ResourceDirectory, urlRequest = showAd})

The basic code to create the web pop-up and show an ad is the very last line. It creates a pop-up that’s 320 pixels wide by 48 pixels high, which is the size of an Admob iPhone web ad, and positions it at the very bottom of the screen. The return value of the native.webPopUp() call is stored in the adSpace variable for later reference. It displays the ad.html file in the pop-up. The baseUrl value is set so that the app knows to look for the html document in the app bundle. The urlRequest value is where the hackery comes in.

If urlRequest were not set, this would all work fine and the ad would load as it should. However, when the user clicked on the ad, the resulting web page would be opened inside the pop-up, which is only 48 pixels high. This, as you can imagine, is not an optimal browsing experience. So, the showAd function is called to see whether the requested url needs to be loaded in Safari, or whether it can be loaded inside the pop-up.

The basic logic is to check whether the url requested is a remote url (begins with http://). If it is, the next check is whether the request is going to c.admob.com; if it is, then it’s a request for the ad, and so the url gets sent back to the pop-up. If it’s not going to c.admob.com, then it’s an actual click on an ad, so the url gets redirected to Safari, using system.openURL(event.url). Finally, if the requested url does not being with http://, we can redirect the url back to the pop-up.

The code is generally pretty straightforward, so you shouldn’t have any problems following it. One neat thing I discovered while figuring this out, which I don’t think is in the Corona documentation, is that after you’ve created a web pop-up, you can provide a new url to that pop-up, rather than having to dismiss the current one and create a new one.

Also, although I used Admob for this example, the basic concept should work fine with any ad provider that serves mobile ads. You would have to modify the urlRequest listener to account for the different urls, and the size of the web pop-up would have to change, but those are pretty basic changes.

Ludicrous Software in the App Store

May 29th, 2010

I’m happy to announce that as of a couple of weeks ago (yes, I know I’m writing this a little late – it’s been a crazy month!), two Ludicrous Software games have been approved for sale in Apple’s App Store and are available now for the iPhone and iPod Touch (click the images to go to the App Store page for that game):

Knight's Puzzle for iPhonePoker Solitaire for iPhone

Both games started life as Flash Lite games, and were ported to the iPhone using the Corona SDK from Ansca Mobile. In case you were following all the hubbub around 3.3.1 (i.e., if you know what I’m referring to when I write “3.3.1”), then to answer an immediate question: both games were submitted after I had agreed to the new Terms of Service from Apple.
In terms of the porting process, I’m happy to say that it was entirely painless – there are a large number of similarities between Lua and ActionScript, so if you have a handle on AS then making the jump to Lua is not at all difficult. There are a couple of quirks that you don’t have to deal with in ActionScript – from relatively trivial ones like having a different use for curly braces to trickier ones like having to forward-declare local variables – but once you get the hang of those then writing Lua is easy and fun.
The Corona SDK is also a pleasure to work with. The sample code is very handy and well-documented, and the documentation that comes with the SDK, although it still has a few holes here and there, is very clear. If you’re used to debugging Flash Lite code using trace() commands, then making the switch to using print() is painless – and you get the added bonus of a very robust debugger on top of that (I’m still get used to working with the debugger, so at this point I’ve found print() to be faster; this will undoubtedly change as I work with the debugger more).
Over the next little while I’m planning to write some tutorial posts on various aspects of the Flash-to-Corona workflow, but if you have any specific questions or if there’s anything in particular you’d like more information about, please let me know in the comments!

Playing with Pixels

April 4th, 2010

I did a user group presentation yesterday on getting started with Pixel Bender. I’m pretty new to Pixel Bender, having played around with it a little bit over the course of only the last couple months. Nevertheless, I’m pretty pleased with the results of my experimentation, and I think this is largely due to two things.

First, there’s the relative ease of entry into filter writing – the basic concepts driving Pixel Bender are pretty straightforward, but don’t limit you at all. So while you can use PB to craft some really impressive effects, you can also do some pretty neat things when you’re first starting out and still in more a learning mode.

Second, Pixel Bender provides a satisfying and immediate sense of feedback. Because you have an image in front of you as you’re working on a filter, you get an immediate visual sense of how things are going. As a result, even the screw-ups – bugs in PB code can result in some pretty whacky unintended results – are motivating. I’ve written a couple of filters that I’ll probably end up putting on-line, but I have a lot more filters sitting on my hard drive that I’ve saved precisely because I made a mistake in the code somewhere. I’m saving them so I can go back and figure out what I did, because at some point in the future I may want to do intentionally what I did unintentionally.

That said, here are two of the demos from last night. The first is a comparison of execution speed of Conway’s Game of Life, first as a straight AS3 implementation, and then offloading the heavy lifting to a Pixel Bender filter. It’s a pretty good example of the speed gains Pixel Bender can provide when used for data processing.

Here’s the non-Pixel Bender version (roll over it to start it going, roll off to stop). The number in the top-right corner is the average time required to calculate the next generation of automata:

This movie requires Flash Player 9

And here’s the same version with the Life logic implemented via Pixel Bender (again, roll over to start, off to stop):

This movie requires Flash Player 9

The second demo is a more straightforward visual effect. I wanted to create a “vacuum” effect, which could be animated in Flash (and/or After Effects, although I haven’t played around with the After Effects/Pixel Bender integration yet). This produced some spectacular mis-steps, I must say. You can see the working version of this below (the ship gets clip if you try the negative vacuum strength because it reaches the bounds of the image). Use the sliders underneath the image to play around with the shader parameters. As you can imagine, it’s dead simple to animate this in an ENTER_FRAME event listener.

This movie requires Flash Player 9

So all in all, I’m finding this pretty encouraging. I’m glad I finally took the time to dig into Pixel Bender a little bit. Now all I need to do is find more time to keep at it – and read a book or two on vector mathematics.

2009 in Review

December 31st, 2009

I thought I’d try to revive the blog by posting a little year-in-review summary. It was an odd year for Ludicrous Software, one in which I probably did less mobile development than in previous years. While working in Flash Lite took up the majority of my working time, 2009 was the first year in which I didn’t actually start any new personal projects. This wasn’t necessarily for lack of ideas – a lot of factors contributed to that being the case. 2009 also saw me doing more desktop development than in previous years – kind of ironic, given Adobe’s focus on mobile, namely the recent announcement of iPhone support in Flash CS5 and the upcoming release of Flash Player 10.1.

Most of my ‘personal’ development time involved porting existing work to new phones/platforms. First, this involved getting content ready for Nokia’s Ovi Store, which amounted in a large number of headaches. It’s too bad that Ovi launched with such problems – it seemed like the first light at the end of the tunnel for a lot of Flash Lite developers, who were looking for opportunities to monetize their content. But those problems seem to have soured a number of people on Ovi – me included – such that I find it hard to justify the amount of work that would be involved in developing new content to distribute there. The second opportunity came when Sony Ericsson asked me to ‘panelize’ some content for their soon-to-be-released Xperia X2 device. We’ll see what happens with that!

Interestingly, 2009 was the first year in which I did not work on any Flash Lite 1.1 projects. My client work is entirely for a company that develops for the Japanese market, and this was the first year in which Flash Lite 2+ phones were a viable target for development. A little something to keep in mind as you wait for the release of Flash Player 10.1! Hopefully the distribution of FP 10.1 will be different, and will enable a quicker uptake, but that remains to be seen. (For the record, I don’t miss developing for 1.1, although it holds a soft spot in my heart – it enabled me to quit my ‘day job’ and make Ludicrous Software a full-time concern. Regardless of what happens to Flash on mobile, I’ll always be thankful for tellTarget() and its antiquated friends.)

I’m going to spend the next day or two working up a list of goals for the coming year – I think it’ll be an exciting one, whatever it brings. Happy New Year!

Device Central Error: "Pool Capacity too low"

October 21st, 2009

I ran across an error in Device Central a few weeks ago, and in the intervening time, I’ve also encountered a few other people who have suddenly run into the same error, so I thought I’d post the fix. The error occurs when you try to use the Snapshot feature in Device Central CS4 to take screenshots of your application running in the emulator. Device Central fails to take the snapshot and reports that it failed because the “pool capacity” is too low.

To fix this, all you need to do is open the Preferences in Device Central, and increase the pool capacity. Here you can see that the pool capacity on my machine is set to 500 MB:

pool

It had previously been set to 5 MB; given that there’s a “Clear Pool Now” button in the preferences panel, presumably Device Central does not automatically clear the pool when you close it down. I don’t think it’s possible to retrieve old images from the pool, so I’m not sure why it’s necessary to keep that old data. And if there is some advantage to keeping it, I don’t know why the button’s hidden in the preferences panel rather than being placed inside the Log window, where you view the screenshots that you’ve taken.

The other odd thing is that Device Central CS4 has been out for a while now, and this error has only started popping up within the last few weeks: it happened to me right before MAX, and at MAX I found out that two other Flash Lite devs had also encountered it recently, and then Mariam ran into this bug recently as well (indeed if you Google “pool capacity too low“, the only relevant result is Mariam’s post to the Adobe Forums). It also makes me wonder if some settings were changed in a recent update that’s causing this problem to start cropping up.

Mobile at MAX

October 12th, 2009

I arrived home from MAX a few days ago, and thought I’d share my thoughts on the event, especially the mobile side of things. In general, as always, MAX was a fantastic few days. The sessions, the events, but most of all the people you get to reconnect with and the ones you get to meet for the first time make it so incredibly worthwhile. If you’ve never been, you should make a point of going – pretty much everybody who goes to MAX says that, but only because it’s true. In particular, it was great to see Dale, Evan, Max, and Scott again.

Anyway, mobile. You likely already know the two big mobile-related announcements from this year’s MAX: Flash Player 10.1 for mobile and devices, and publishing native iPhone apps from Flash CS5. I think Dale’s post about MAX nailed things, but I’ll add a few other random thoughts – it’s Thanksgiving today, so if this is a little scattershot, bear in mind that I’m suffering a turkey hangover…

iPhone

Not much to say about this that hasn’t already been said. The games that are on the App Store now were built with an early version of the software, and there’s definitely room to improve performance. Some of the demos that were shown in sessions seemed to run much better, but I’m not sure if that’s a reflection of better compiling, or better code to compile from (or perhaps both). In one session the presenters stated that a simple “Hello World” app would end up at about 8 MB; this seems incredibly large to me, but this may also be because I still do lots of work for a mobile market in which there are 100 KB limits on SWF (or other) files and data. Hopefully there are improvements in that area.

Flash Player 10.1

The other big announcement is, in the long term, a much more important one: Flash Player 10.1 in the browser on mobile and devices. The Open Screen Project has signed on pretty much everybody but Apple, so it has the potential to achieve what Flash Lite hasn’t been able to do outside of Japan: create a consistent runtime with a uniform method of getting content onto phones. In Japan, Flash Lite has been incredibly successful, for two main reasons: 1) a reasonably consistent runtime, with 2) a uniform implementation of the player. For years, practically every Japanese phone came with Flash Lite 1.1 installed as a browser plug-in. In a market used to consuming data on their devices, this created the perfect set of conditions for Flash Lite to be successful.

I think this is what Flash Player 10.1 could do. Of course, this is all long-term thinking, so it’s speculative at best – a FP 10.1 beta will be released soon, and we’ll start seeing devices with it pre-installed at least by this time next year. But, as I’m overly fond of pointing out, up until a few months ago I was still writing a ton of Flash Lite 1.1 code for the Japanese market, and we’ve only recently switched to projects targeting Flash Lite 2+. Things don’t change overnight in the mobile world, and it may be a while before there are enough devices out there with 10.1 installed to make it a viable target for development. Of course, that doesn’t mean I’m not looking forward to playing with the beta; I want to find out just how consistent that runtime will be!

Going to MAX?

September 23rd, 2009

If you’re planning to attend Adobe MAX this year: I’ll be getting in on Saturday afternoon, and was wondering if any other Flash Lite folks would be interested in getting together for drinks on Saturday night.

If you’re interested, email me directly (darren at ludicroussoftware dot com) and let me know when you get in and what hotel you’re staying in. I’ll figure out a decently central meeting point, let you all know the when and the where, and we can head out from there. And if you know of a good place in the area of the conference centre for drinks, let me know that too! Or we can make that part up as we go along.

Teaching at Red River College this fall

August 17th, 2009

I’m going to be teaching a course in the Digital Multimedia Technology (DMT) program at Red River College this fall! The course, which has the rather daunting title of “Visual Explorations 1“, is actually an introduction to Flash; I’m not sure where that title came from. It looks like I’ll be teaching two sections, with about 20 students each. I just found out today, and classes begin the first week of September, which means I need to put together some teaching materials in a hurry!

Of course, this also means that if you hire a DMT grad in a few years time and they don’t have the Flash skills they need, then you know who to blame!

Travel plans for MAX

July 20th, 2009

My travel plans for Adobe MAX are all set. I’ll be arriving in L.A. on the Saturday (October 3) before MAX and heading back to Winnipeg on the morning of Thursday the 8th. I’m booked at the Millennium Biltmore Hotel, which is about a mile away from the conference site. It would’ve been nice to stay a little closer, but the rates at the conference hotels were so much higher than the rate I’m paying at the Biltmore, I could travel back and forth by cab about 5 times a day if I wanted to and still save money.

Looking forward to seeing the Flash Lite diehards once again! It’s been an interesting year so far, and there will no doubt be a good deal of discussion about how things are going in the various corners of the mobile Flash world.

Now I just need to register for the conference itself!