Some useful things I have learned about Corona

Here are some things I have learned over the last couple of years of using Corona.

  1. Use moses.lua. It’s like underscore.js, and will save you many for loops. It’s 

   just better lua. https://github.com/Yonaba/Moses

 local \_ = require("moses")
  1. If you need consistent random numbers from a seed (I sometimes do), you need your own function. 

   Random numbers are not consistent across iOS and Android. Here’s one:

   

 local function make\_lcg(seed)         local m, a, c = 2^32, 1103515245, 12345         local function rand()             seed = (a\*seed + c) % m;             return seed/2^32         end         return rand     end          local function fisher\_yates\_shuffle\_inplace(atable, seed)         local rand, floor, j = make\_lcg(seed), math.floor, nil         for i=#atable,2,-1 do             j = 1+floor(rand()\*i)             atable[i], atable[j] = atable[j], atable[i]         end     end
  1. Don’t bother making graphics in lots of sizes. I used to have @2x, @3x, @4x, etc. 

   and it was a pain to write scripts to create all the sizes.

   If you are starting with a base 320x480 app, then just use two sizes, equivalent to 

   @2x and @4x. Use @4x graphics for any resolution >2x, and let Corona scale the rest down.

   Downscaling usually looks fine, plus nobody has 320x480 resolution anyway.

   (If you are starting with a higher base resolution then all the better – I’m just used

   to using 320x480.)

   During the development phase I just use the highest resolution version of every graphic.

  1. Save game settings etc. in JSON using the loadsave.lua module. 

   Don’t use SQL, it’s too much hassle.

    local loadsave = require("loadsave.lua")     local settings\_file = "settings.json"     local settings = loadsave.loadTable(settings\_file)     if settings == nil then         settings = {username="default", volume=50, }     loadsave.saveTable(settings, settings\_file)     else         username = settings['username']         volume = settings['volume']     end
  1. Be careful with canceling timers and transitions if you are planning to remove scenes

   from memory. This can cause bugs that crop up infrequently and unpredictably…

  1. Use a lock function to keep the user from tapping buttons while your app is doing 

   important business. Here’s an example using moses:

&nbsp; &nbsp; -- lock("new round animation"); \<do something\> ;unlock("new round animation") &nbsp; &nbsp; -- Check if all\_unlocked() before responding to inputs.&nbsp; &nbsp; &nbsp; local locks = {} &nbsp; &nbsp; local function lock(k) locks[k] = true end &nbsp; &nbsp; local function unlock(k) locks[k] = false end &nbsp; &nbsp; local function all\_unlocked() return \_.count(locks, true)==0 end
  1. Keep track of the memory your app is using to see if there are leaks:

      local memtext = display.newText("", 250, 8, “Helvetica”, 15)     local monitorMem = function()         collectgarbage()         local textMem = system.getInfo( “textureMemoryUsed” ) / 1048576         memtext.text = " mem: “…math.floor(collectgarbage(“count”))…” "…math.floor(textMem)…“M”     end     Runtime:addEventListener( “enterFrame”, monitorMem )

  2. Place sprites onscreen relative to the center of the play area. This is not strictly necessary

   but I find it helps with adapting to different resolutions and aspect ratios.

&nbsp; &nbsp; local CX, CY = display.contentCenterX, display.contentCenterY

Some nice tips. Thanks! Will check out Moses.

Regarding point 3 (and point 8, sort of), I would go even further:

in a lot of circumstances just one set of graphics is enough, and you can downscale these when needed. Specific reasons why this could be a problem is because of the size of textures (e.g. older devices that might not work with 2048 x 2048 px images) or total size of graphics in memory. But so far, even for my graphics-intensive projects, the single set of graphics is enough!

Thomas6, good point. In many cases I am sure that even two sets of graphics is overkill.

I think the conclusion is that downscaling works really well.

I am so stealing those lock functions.  I did lock out the user actions when necessary but my implementation was incredibly cumbersome compared to that.  Appreciate the tips.

Josh

Some nice tips. Thanks! Will check out Moses.

Regarding point 3 (and point 8, sort of), I would go even further:

in a lot of circumstances just one set of graphics is enough, and you can downscale these when needed. Specific reasons why this could be a problem is because of the size of textures (e.g. older devices that might not work with 2048 x 2048 px images) or total size of graphics in memory. But so far, even for my graphics-intensive projects, the single set of graphics is enough!

Thomas6, good point. In many cases I am sure that even two sets of graphics is overkill.

I think the conclusion is that downscaling works really well.

I am so stealing those lock functions.  I did lock out the user actions when necessary but my implementation was incredibly cumbersome compared to that.  Appreciate the tips.

Josh