May 152012

I’ve been using Ansca’s Corona SDK for almost a year. I made the decision to use Corona because it allowed rapid development via Lua, and the SDK met almost all of my needs at the time I chose it.

I’ve made numerous contributions to the Corona Community, and even donated my time in solving other people’s issues. Because of my strong belief in the SDK I signed up to be a Corona Ambassador.

Over the past few months something has become painfully obvious to me and a number of other Corona developers. Corona just doesn’t have the support it should. The software development process is flawed and because of this they keep pushing out Daily Builds that are buggy and cause any of a number of issues for developers.

Just go into the Corona Forums and you will see what I mean. One common thread goes something like this:

“I’ve had lots of problems with Corona. I write up the issues on the Forums and hear nothing back from Ansca. If I do get support it’s almost always from another developer who has gone down the same road and run into the same issue. It seems like the community is figuring out solutions to more of the problems than Ansca is. What gives?”

The above isn’t an exact quote, but it is a compilation of a number of complaints developers have had. As a Corona Ambassador I try and jump in and solve the issue whenever possible, but that doesn’t work when it is a fundamental issue with Corona.

For instance, recently I submitted 3 apps to the Barnes and Noble Nook store. All 3 passed for Nook Tablet, but all 3 were rejected for the Nook Color. I searched high and low for differences between the platforms, but other than the Color having half the memory of the Tablet and some differences in the video card and clock speed, they are supposed to be identical. Our apps only use 80MB of memory so it shouldn’t have been due to memory. After spending days trying to figure out what might be happening, I contacted Ansca and asked them about any issues they might know regarding the Nook Color. This was Ansca’s response:

yes we are aware of this issue. We think it’s due to some rendering changes a week ago on Android

On the one hand, I was glad to hear it was a known issue. However, why didn’t they post something in the Corona Developer Forum letting people know to hold off on Nook Color submissions? I mean really, if you know there is an issue, then why keep it a secret?

One typical response goes something like this: “the daily builds are NOT stable and we make that very clear”. Sure, that is very true. However, since the stable builds only come out a few times a year, and because there are KNOWN crash bugs that have been fixed ONLY in the Daily Builds what is a developer to do? What until the next stable build? That could be weeks or months away and we have no idea when it will occur.

Here’s another example of the instability of Corona. We recently submitted 3 apps to iTunes. All 3 were accepted and are now available in the iTunes store. Almost immediately we started getting complaints in our reviews from users that the game wouldn’t load. These negative comments materially affect our business. Having people make comments that our games are crap or that our company sucks is NOT good for business.

So we posted an update to our description asking people who experience the problems to let us know what device and OS they are using. The response so far is iPhone 4, OS 5.1.1. Of course we had tested on this device, but we believe the user is having an issue so we do some more testing. Our app runs fine for us. If you know much about software development then you can probably guess that the issue is almost certainly an uninitialized variable. That would cause it to work fine sometimes and not other times.

Guess what? Any uninitialized variables have to be in the Corona SDK as it uses Lua for the developer coding and Lua sets all variables to “nil” unless you explicitly set them to some other value. That means that our code will run the same way from one run to another, unless you are past the load and into the game where random numbers get used. Since the app just gets a black screen at start-up for the user, it is clear this is not in our code, but something in Corona.

Ansca, PLEASE fix these issues. PLEASE stop with the Daily Unstable Builds. PLEASE put out regular stable builds every 2 weeks, every month, whatever period works for your team size.

I want to continue using Corona as it is a very nice solution when it works. However, if these issues aren’t resolved soon I will be forced to move to another SDK (and there are a number of them now).

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 5:32 pm
Oct 132011

This example demonstrates a progress bar that updates while assets are being loaded.  The typical use is when your assets are large enough that the user might think your app has frozen if there isn’t some sort of feedback.

A few notes about the code below:

  • Because of the way that the Corona SDK scopes modules, I chose to have a global “World State” variable declared in main.lua so I can share values between modules. The name I chose for that variable is: gWS.  So if you see values prefaced with “gWS.” they are global values declared in main.lua
  • The gWS.nScaleX and gWS.nScaleY values are used to let me switch devices and have everything scale properly.
  • This example uses the “ui” and “director” modules from Ansca (included in the complete code on GitHug
  • The code is under the MIT license so feel free to use, modify, etc the code to your hearts content.

You can get the full source code along with assets from GitHub here

-- Date: October 12, 2011
-- Version: 1.0
-- File name: cSceneLoad.lua
-- Code type: Example Code
-- Author: Ken Rogoway
-- Update History:
-- Comments: The space images used are from NASA and are in the public domain.
--           The horse image sheets are from the horse demo provided by Ansca.
-- Sample code is MIT licensed:
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:

-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.

-- Copyright (C) 2011 Ken Rogoway. All Rights Reserved.

module(..., package.seeall)

local bUseListener = false
local nMeterX = 272     -- final X position of the meter bar when at 100 percent
local nMeterY = 562     -- Y position of the meter bar
local nMeterW = 480     -- Width of my meter bar image
local nMeterH = 30      -- Height of my meter bar image

-- This is set to 1/2 second (500 ms) so let it go slow enough to
-- see the bar advance since we are using a very small set of data
-- You would want to set this to a much smaller value, so there is
-- minimal delay between chunks, but probably at least 1/30 of a
-- second (33 ms) so there is time to update the display.
local nDelayBetweenChunks = 500

-- Main function - MUST return a display.newGroup()
function new()
    local splashGroup = display.newGroup()
    local loadingImage, loadingBar, loadingMask

    loadingImage = display.newImageRect( gWS.pImageDir.."load_bkgd.png", display.contentWidth, display.contentHeight )
    splashGroup:insert( loadingImage )
    loadingImage.x = display.contentCenterX
    loadingImage.y = display.contentCenterY

    loadingBar = display.newImageRect( gWS.pImageDir.."load_bar.png", math.floor( nMeterW * gWS.nScaleX ), math.floor( nMeterH * gWS.nScaleY ) )
    splashGroup:insert( loadingBar )

    loadingBar:setReferencePoint( display.TopLeftReferencePoint )
    loadingBar.x = math.floor( (nMeterX-nMeterW) * gWS.nScaleX )
    loadingBar.y = math.floor( nMeterY * gWS.nScaleY )

    loadingMask = display.newImageRect(	gWS.pImageDir.."load_mask.png", display.contentWidth, display.contentHeight )
    splashGroup:insert( loadingMask )

    loadingMask.x = display.contentCenterX
    loadingMask.y = display.contentCenterY

    -- Update the percent complete bar
    function updateBar()
        local nPercent = math.floor( 100 * (gWS.nLoadIndex-1) / gWS.nLoadCount )
        --print( "Percent = ", nPercent )
        loadingBar.x = math.floor( (nMeterX-nMeterW + (nMeterW*nPercent/100)) * gWS.nScaleX )
        if ( nPercent >= 100 ) then
            -- final resting place at 100 percent
            loadingBar.x = math.floor( nMeterX * gWS.nScaleX )

    function myLoadChunk()
        -- Load a chunk of data

        if ( bUseListener == false ) then
            -- update the loading bar.  See the comments above
            -- regarding using a event to trigger this

        -- Are there any chunks remaining?  If so, set a timer to
        -- load the next one.
        if ( gWS.nLoadIndex <= gWS.nLoadCount ) then
            timer.performWithDelay( nDelayBetweenChunks, myLoadChunk )
            -- Done, so finish any data stuff

            if ( bUseListener == true ) then
                Runtime:removeEventListener( "enterFrame", updateBar )

            -- Onward and outward
            director:changeScene( "cSceneGame" )

    -- Set everything up so we can start going

    updateBar()	-- update it once for 0 percent

    -- Start it going
    timer.performWithDelay( nDelayBetweenChunks, myLoadChunk )

    if ( bUseListener == true ) then
        Runtime:addEventListener( "enterFrame", updateBar )

    clean = function()

        if loadingImage then
            display.remove( loadingImage )
            loadingImage = nil

        if loadingBar then
            display.remove( loadingBar )
            loadingBar = nil

        if loadingMask then
            display.remove( loadingMask )
            loadingMask = nil

    -- MUST return a display.newGroup()
    return splashGroup


P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 5:50 am
Oct 132011

I wanted to work on an iPhone/Android port of Arrow Antics; one of my older games. The original game was written using SDL, but the current state of SDL 1.3 is still a bit flaky and not ready to release products with.

I started looking at various 2D iPhone solutions. The two most popular 2D iPhone SDK’s appear to be Corona by Ansca, and Cocos2D.

Cocos2D has an Objective-C based API. Personally, if I wanted to use Objective-C I would just code directly to the iOS SDK. However, for less experienced programmers there is a lot of value in not having to write the functionality included in the Cocos2D SDK. So, for me, I quickly ruled out Cocos2D.

Corona SDK is a Lua based solution that supports iOS based apps (iPhone/iPad) and Android based apps (Droid, NexusOne, myTouch, GalaxyTab). Since all of the app logic is written in Lua, it is a “write once, run anywhere” type solution; at least for iOS and Android based systems.

Corona Pros
Obviously the biggest strength of Corona is that it is a cross platform solution. If you are only targeting iOS then you can go with the iOS SDK or Cocos2D. However, if you think that you might want to deploy your app on other platforms then you will want a solution like Corona. There are a lot of nice features that Corona supports, including physics using Box2D, Facebook Connect, OpenFeint support, and most importantly native device features.

Corona Cons
The most obvious drawback to Corona is the lack of a UI Layout tool. If you want to place images, buttons, widgets, etc on the screen you have to do it all in Lua like this:

local helpGroup = display.newGroup()
local backgroundImage = display.newImageRect( "Background.png", 480, 320 )
backgroundImage.x = 240; backgroundImage.y = 160
thisGroup:insert( backgroundImage )

Sure, this is only a few lines of code. However, it means you have to do something like this for EVERY display object in your app. Why not have a layout tool that writes out a layout file in XML or JSON? Then for each screen in your app you could just load the data file and it would create your display objects and add them to the display group.

I will no doubt find other strengths and weaknesses with Corona as I continue the port of Arrow Antics. Look for more info soon.

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 3:15 am