Home > Tech Geek > Need to save your game data in Corona SDK? Check out this little bit of code.

Need to save your game data in Corona SDK? Check out this little bit of code.

A very frequent question in the Corona SDK Forums is “How do I save my game data?”.  There are several published solutions in the Community Code and while I they are good, they don’t help you learn how to program or carry extra functions that you may not need.

I (and several other’s) frequently suggest “Just use JSON!”.  But in a recent post in the forums, I realized that as simple as this really is, the language encouraged people to go look up JSON with the concept that they needed to learn JSON.  JSON or JavaScript Object Notation, is a simple syntax for encoding data in a light-weight standard way.  You can dig into the guts of JSON at http://json.org.

The typical JSON file is considerably smaller than the same data encoded in XML and it’s a great way to represent table data like in a language like Lua, which Corona SDK.

If you click through to the json.org links above, you may be immediately intimidated, in fact so intimidated that you are turned off to the concept of using JSON.  But here is the beauty with Lua and Corona SDK, you don’t need to know JSON at all.  In fact it may be a bit better if you just accept that Corona provides you two API calls and assume that everything else is simply magic.

To see just how simple this is, check out this code.  But before I present this code, some of it may still be scary and that is the code to open a file and to read and write files.  However, it’s important to learn this code because as you work on other apps, you will need to read and write files to the file system.

Mobile applications run in a “Sandbox”, which is a protected area.  You can only access files inside your space only.  There are typically four specific locations where files are stored and retrieved from.  They include:

  • The Resource Folder (called a Directory)
  • The Documents Directory
  • The Temporary Directory
  • The Cache Directory

The Resources directory, which Corona SDK,  calls:  system.ResourcesDirectory,  is basically your application files that are “bundled” together and installed on your device.  This frequently referred to as the “app bundle”.  These file can be read only and not written to.  This is for security to prevent malware from infecting your app.

The Documents Directory is where you store your permanent files.  In Corona SDK, this is known as system.DocumentsDirectory.  Any file that your app needs to run that cannot be re-created gets saved here.  It should be noted that Apple with iOS 5 and iCloud, files in this folder get automatically backed up to iCloud.  Corona SDK currently does not give us an option to turn off those backups.  Apple is cracking down on downloaded files, that can be reproduced being saved in this directory since iCloud’s “free” space is limited and they don’t want it full of game code, graphics and other downloaded directory.

Because of this we now have the Caches directory or system.CachesDirectory.  This is a folder to store these downloaded files that can be re-downloaded.  In most senses, you “cache” files that you download that doesn’t change frequently and only download the files when they change.  Web browsers help websites load faster by keeping images, CSS and JavaScript files around on your computer so they don’t have to reload them over the Internet.  You’re app should do the same thing for files that you download.   Files in this folder **CAN** be deleted by the system if the overall file storage gets too low, but they for the most part should remain from session to session, but can be re-downloaded if necessary.

The final location to store files is the Temporary directory or system.TemproaryDiretory.  This is where you put files you don’t care about from session to session.

Files in general require three operations:

  • Open the file
  • Read or write data to/from the file
  • Close the file

Corona SDK uses some syntax for processing files that’s a bit confusing.  After a year of working with the product, I still have to look up the file operation API calls, so don’t worry if you don’t get this code right away.

 Lua |  copy code |? 
01
02
-- load the JSON library.
03
local json = require("json")
04
 
05
-- Function to save a table.  Since game settings need to be saved from session to session, we will
06
-- use the Documents Directory
07
 
08
local json = require("json")
09
function saveTable(t, filename)
10
    local path = system.pathForFile( filename, system.DocumentsDirectory)
11
    local file = io.open(path, "w")
12
    if file then
13
        local contents = json.encode(t)
14
        file:write( contents )
15
        io.close( file )
16
        return true
17
    else
18
        return false
19
    end
20
end
21
 
22
function loadTable(filename)
23
    local path = system.pathForFile( filename, system.DocumentsDirectory)
24
    local contents = ""
25
    local myTable = {}
26
    local file = io.open( path, "r" )
27
    if file then
28
         -- read all contents of file into a string
29
         local contents = file:read( "*a" )
30
         myTable = json.decode(contents);
31
         io.close( file )
32
         return myTable 
33
    end
34
    return nil
35
end
36
 
37

So while we are using JSON to format the data when we save it and read it back in, you have to learn ZERO JSON to use this. It magically turns a Lua table into a string that can be then written to a file. If you read that string back in, then decode it with json.decode you end up with the exact came table you started with.

Then to use this magic, you simply do:

 Lua |  copy code |? 
1
2
myGameSettings = {}
3
myGameSettings.highScore = 1000
4
myGameSettings.soundOn = true
5
myGameSettings.musicOff = true
6
myGameSettings.playerName = "Barney Rubble"
7
saveTable(myGameSettings, "mygamesettings.json")
8

To read your game settings:

 Lua |  copy code |? 
1
2
myGameSettings = loadTable("mygamesettings.json")
3

While you’re getting two very simple, easy to use calls that you really don’t have to think about, please take time to learn what those two functions are doing with regards to opening, reading, writing and closing files. You can save learning the JSON format until another day.

Corona SDK excels in letting you do complex tasks in simple easy ways. We don’t think twice about what’s under the hood of the display.newImageRect() API call. You don’t need to think about what’s under the hood with JSON either.

This code can be downloaded from Github.

Categories: Tech Geek Tags:
  1. February 23rd, 2012 at 18:27 | #1

    Hi Rob!

    As a big fan of your knowledge and your WAY to explain the code (as Mrs. Peach does so well too), I only would like to say a big thank you for posting this great topic and all the awesome helps on CoronaSDK Forums as well.

    Best Regards,
    Rodrigo.

  2. February 23rd, 2012 at 22:45 | #2

    Ha! Glad my forum post could inspire this article. What a great help this is!
    Thanks again!

  3. Guy T.
    February 27th, 2012 at 12:00 | #3

    This will be very helpful. Thanks!

  4. Danny
    March 4th, 2012 at 18:38 | #4

    This was a fantastic help to me! Thanks a bazillion! :-D (Official number! ;-P )

    One little query – shouldn’t the load line be:

    [quote] myGameSettings = loadTable(“mygamesettings.json”) [/quote]

    instead of :

    [quote] mySettings = loadTable(“mygamesettings.json”) [/quote]

    Otherwise it doesn’t work for me. But worked when I changed it as above.

  5. Danny
    March 4th, 2012 at 18:39 | #5

    Sorry, poor quote editing there. ^_^

  6. March 4th, 2012 at 19:45 | #6

    @Danny
    Thanks for the spot Danny! I’ve adjusted the code!

  7. Gary
    March 21st, 2012 at 11:03 | #7

    You missed a “t” in settings in the sample save code

  8. April 18th, 2012 at 16:50 | #8

    Epic sir! Man, you are going straight into my RSS feeds for Corona. I don’t know WHY I haven’t done so already. And looking forward to reading about the RESTful integration too! Thanks Rob!

  9. May 17th, 2012 at 12:57 | #9

    thanks rob for the great lesson.

    how do i go about outputting the highScore onto the screen? and also have it update while moving around the storyboard?

    thanks

  10. Robin Hood
    March 12th, 2013 at 21:15 | #10

    thanks for the awesome post.

    one question here, how can i encrypt the contents saving to json file then decrypt again when read the file.

    thanks in advance.

  11. EHO
    April 4th, 2013 at 11:54 | #11

    This is killer. I set this up and was saving and loading data in about 2.5 minutes flat. I did take the time to better understand the io API. It would have been solvable for me to set up on my own but your solution strikes me as excellent and certainly saved me a number of hours of work.

    For anyone that is new to working with system information, I got some forum help that explained you can use the File -> Show Project Sandbox to find the folder on your machine that keeps the system.DocumentsDirectory content for your Corona Simulator work.

    Thanks for the nice article and the code :)

  12. April 17th, 2013 at 16:29 | #12

    I guess it depends on how you want to encrypt it, but you could take the JSON output which is just a text string, then encrypt the whole thing, then create a new json structure that is just the one variable:


    $data = json_encode($array);
    $edata = encrypt($data);
    echo(json_encode($edata));

    or something similar.

  13. April 18th, 2013 at 11:54 | #13

    hi Rob,
    I asked this in a reply to one of your posts in another forum. I need an answer relatively quickly so I’m trying you here as well. sorry… what I need to know is how one can email the contents of a table (specifically a photo captured by an iPhone in an app). but since I’m here, does json allow you to upload image data as well?
    THANKS!

  1. No trackbacks yet.

%d bloggers like this: