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.


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.
Ha! Glad my forum post could inspire this article. What a great help this is!
Thanks again!
This will be very helpful. Thanks!
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.
Sorry, poor quote editing there. ^_^
@Danny
Thanks for the spot Danny! I’ve adjusted the code!
You missed a “t” in settings in the sample save code
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!
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
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.
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 :)
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.
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!