Saving Game State on Corona With Ice

| Comments

I have been looking closely at the Corona SDK and so far I like most of what I see. It is very easy to put together simple 2D games using sprites and even game physics. Scripting in lua is an interesting alternative to Objective C and has the potential to allow for much more rapid game development.

There are, of course, some drawbacks. First among those is that Corona is strictly 2D (for now, at least). For most mobile games this is not a drawback, but it does limit the kinds of things you can do. Another drawback, for me, is that you currently cannot work with OpenGL ES 2.0 shaders. This makes it difficult to do some cool effects, but shaders are on the roadmap for Corona so hopefully they will be available soon.

This is actually a special case of a larger tradeoff with Corona. Since Corona provides wrappers to basic APIs like OpenGL, OpenAL, etc., you are limited to the level of detail that Corona’s developers provide when accessing those APIs. If the Corona developers have chosen not to expose certain elements of an API to you (usually for sake of simplicity) then you are not able to access them.

Similarly, certain lua functions have been purposely left out of Corona due to limitations (usually security related) of mobile devices. In particular, methods like loadfile() and loadstring() that dynamically load and execute code are not implemented. This has big implications for the way certain things can be done.

One area of particular importance is in saving game state. Surprisingly, despite being game focused, Corona does not offer a built in solution for saving and restoring game state. The official documentation suggests this site for various solutions to serializing/deserializing lua tables. The problem with this is that all of the solutions listed on that page utilize loadstring() (or similar) to deserialize the tables, which is not implemented in Corona.

I looked around and was beginning to think I was going to have to write my own serialization using low level IO, but then I stumbled across Ice. Ice handles the job for you by serializing lua data as JSON and writing it to an sqlite database, then reading it back and returning lua code during deserialization.

The following is an example of using Ice to save simple game state:

Saving Game State
1
2
3
4
5
6
7
8
9
10
11
-- Save some state stored in x,y (initialized earlier)
local savedGame = ice:loadBox("savedGame")

local gameState = {}
gameState.x = x
gameState.y = y

serializeScene(gameState)     

savedGame:store("gameState", gameState)
savedGame:save()

And to read state back in

Retrieving Game State
1
2
3
4
5
6
7
8
9
10
11
12
13
local savedGame = ice:loadBox("savedGame")

local gameState = savedGame:retrieve("gameState")

local x = nil
local y = nil

if gameState then
  x = gameState.x
  y = gameState.y
else
  -- initialize x and y to appropriate values
end

Ice can store key value pairs for tables or simpler objects like strings or numbers. And it provides methods to increment/decrement a value already stored (useful for scores). It also provides methods to only store values under certain conditions, such as checking to see if a value has increased (useful for high scores). All in all, a very useful plugin.

Comments