Apr 022011

This tutorial will teach you how to save and load data in your Corona SDK iPhone or Android application.

That’s right! It’s 9 AM on Sunday the 3rd and already I am posting a tutorial I didn’t expect to get done for at least another week.

I know a LOT of you have been eagerly awaiting this one and I figured I would get the month off to a good, productive start by staying up and writing this tutorial for all of you.

Everything you need to know to save and load data from/to your iPhone (or Android) app is right here. It’s a modified version of the code I used in Pocket Pet Rock and works perfectly.

I am very, very excited to have been able to get this done overnight – I think it will help a lot of people make better apps. (I know my next app is shaping up wonderfully thanks to being able to save and load data!)


Enjoy! (*You will want to open menu.lua first.)

I’m off for a well earned rest!

Peach Pellen :)

PS – If this helps you please consider donating. I rely on donations to get by. Although I don’t do this to get paid (I’d charge for email support if I did ;)) I’m able to spend more time helping you and writing tutorials when I make some money doing it – it’s a fine balancing act between this and making my own apps in order to scrape by.

If you cannot afford to donate please consider tweeting this, Facebook-ing it, following me on Twitter or liking Techority using the box in the sidebar.

Thank you!

Like this post? Subscribe to the monthly newsletter!


  55 Responses to “How To Save And Load Data In Your App”

  1. Thanks for the sample code.

    Does this data survive application updates?

    Example: Say I’m using this text file to store which levels in a game a user has passed. If I publish a simple fix to the app store I want to be sure that doesn’t result in the user’s level record being wiped.

    • Hi Jade, recognize the pic – thanks for the Twitter follow :)

      I’d actually recommend using Jon Beebe’s Games Class for saving and loading data. It didn’t exist when this was written but is much easier to use and also easier to update the app and not risk losing any data.

      Peach :)

  2. No worries Robin,

    I did that because I was half asleep, I think ;) Really I should have/could have used tonumber()

    The reason is because it’s a string, but we want to change it to a number – make sense?

    If not check out the tonumber() API on the Corona website for more specific into :)


  3. Hi Peach,

    thank you very much for your great work!

    I havea little question about this:

    in the menu.lua, line 147, you wrote “if _G.twolock-0 == 0 then…” why do we need to add the “-0″ behind _G.twolock? I actually noticed that it doesn’t work without but I don’t understand what it does….

    Thank you,
    Best regards,

  4. No worries, you mean when you resume you app you want to return to the last scene played?

    If so, you’d save a fourth thing after your threelock, like lastScene = “menu” or whatever. Then on each scene you’d do lastScene = “scene1″ or whatever the scene is called.

    Then at the top of the menu, you’d do a function to change the scene to lastScene with director.

    Make sense? :)

  5. sorry about the double post!!

  6. would you know how to load straight from last scene?

  7. would you know how to load straight from last scene?

  8. Haha, no worries :)

    Don’t worry about any sort of donation; I don’t expect kids to donate, just enjoy the tutes :)

    It’s great to see young people (younger than me I mean) getting into Corona – good for you :D


  9. p.s. im 12 and im just getting started (10 weeks kinda)!!
    but im developing a game and i couldnt have done it without your tutuorials so thanks

  10. wooooooooooooooooooooo

    thank you soooooo much it really helped
    i havent yet purchased corona sdk
    because im buying an apple developer acount first but as soon as i have that paid i might just make a donation! :)

  11. OK, it doesn’t work because the error is stopping the rest of it from functioning normally.

    Because you added a value what you need to do is change where we are saving it so it starts fresh, what you have beyond that should be right.

    Try just changing ourdata.txt to ourdata1.txt

    You will need to change it twice in menu.lua and once in saveit.lua

    Let me know how that goes :)

  12. heyyy sorry i just retested it and now it doesnt go black but when i add the function to do the locked button
    and the unlocked button for level 3 nothing works not level 1 or level 2 !

    (if i leave out that function and just add _G.threelock and so on every thing works as yousual)


  13. i added;

    in saveit.lua to file:write(_G.onelock ..”, “.. _G.twolock..”, “.. _G.threelock)

    and in my menu in
    _G.onelock = prevState[1]
    _G.twolock = prevState[2]
    _G.threelock = prevState[3]
    _G.onelock = 1
    _G.twolock = 0
    _G.threelock = 0

    file:write( _G.onelock ..”, “.. _G.twolock..”, “.. _G.threelock)

  14. heyy lovin the tutorials they have been very helpfull,

    just one thing when i tried to add a 3rd but it just displayed a black screen and i added everything right
    I think! :)


    thanks in advance

  15. Hey Justin,

    No worries :) I’m glad.

    I can’t logically put a high score table together in my head right now, but you’d likely use a function to check where the score fits – like if score > highscore3 and score < highscore2 then So then you would know it should be in spot 3, you’d do something like highscore5 = highscore4, highscore4 = highscore3, highscore3 = score Make sense?

  16. Hey Peach
    Thanks for responding to my last comment so quickly I solved a problem that’s been bugging me for weeks! :)
    But I’m kind of stumped on how to save high scores, like if I want to save multiple scores how would I go about it?
    SO, let’s say that there are five high scores already and I beat all of them, but how would I save and display them so the lowest score is removed but the new high score moves to the top?
    Is there some kind of sorter function that can automatically sort them out when the old scores are beat?
    Thanks Justin

  17. Sorry Justin, I was offline for a bit there.

    No worries at all, glad you got it :)


  18. Thanks Peach I just figured it out, Just Like you said it only changes the screens if _G.twolock = 1
    ,but if _G.twolock = 0 then it just displays a Image. Its all in that function!=)

    Wow you’re awesome, but I can’t believe I overlooked that!

    Thanks again Peach :)


  19. that line just says if _G.twolock = 0 then display this lockImage, but if _G.twolock = 1 then display unlockImage. Thats what I’m getting out of this, I’m still confused about how _G.twolock = level 2


  20. Hey Peach

    Your tutorials are great, I’m new to your website, but have learned from your website and enjoy what you teach!

    I recently downloaded your tutorial on how to save and load data, but I can’t seem to understand how _G.onelock = 1 and _G.twolock = 0 act as if they were level 1 and level 2.
    I can’t find anything that says that _G.onelock and _G.twolock = level 1 and level2.

    I must be reading your code wrong or I don’t understand how you are doing it.

    Can you enlighten me?


    • Line 146, Function seticontwo – check that one out. Level 1 is never locked and I don’t know why I included a variable for it :P

      But that function shows how it effects level2/icon2 – and whether or not it goes to level2 when clicked. (Just so we’re clear, this is in menu.lua)

      Peach :)

  21. Hey Luke,

    I don’t use Corona Project Manager, no – I’ve tried it and I liked it, but I didn’t feel like I needed it. (It is cool though, and there’s a trial version as well I believe.)

    Peach :)

  22. Ya, he understands it, but he thinks that downloads are a bad thing. Thanks for the reply so quick, i’ll look at this tutorial and work on making a high score, also I was looking around and found this thing called corona project maneger, do you use it?

    Luke ;-)

  23. Hey Luke,

    Sorry about that – the first time someone new writes a comment it’s automatically put in a cue for me to approve it. Your future posts should, hopefully, just auto approve instantly ;)

    Now, as to what the tutorial does – yes – you could use it for a high score easily. This demo shows locking and unlocking levels but it is the same idea.

    Does your father understand what it is you want to download on this occasion? It’s educational! Also, the file size is tiny – it’s just text and a couple basic images.

    Peach :)

  24. Hi peach,
    I haven’t downloaded this yet because my dad doesn’t like me downloading things, but does this show you how to save things on your app, such as if you got a high score, it would show it the next time that you open up the app? Thanks, I have gotten most of my tutorials from you. I might donate soon if I get a full app completed! Not sure if it submitted soncommenting again

  25. Sorry! Forgot to have it email me when you reply!

  26. Hi peach,
    I haven’t downloaded this yet because my dad doesn’t like me downloading things, but does this show you how to save things on your app, such as if you got a high score, it would show it the next time that you open up the app? Thanks, I have gotten most of my tutorials from you. I might donate soon if I get a full app completed!

  27. Of Course! I’m a fan of you and your show :-)

  28. Haha, thanks :)

    Goodnight! I hope to see you around again.

  29. It works!!!!! You’re a genius. Good Night or Good Morning! Thank you Very Much!

  30. Got it!

    function seticontwo (event)
    if _G.twolock-0 == 0 then
    leveltwoicon = display.newImage ("level2locked.png")
    leveltwoicon.x = 130
    leveltwoicon.y = 40
    elseif _G.twolock-0 == 1 then
    leveltwoicon = display.newImage ("level2icon.png")
    leveltwoicon.x = 130
    leveltwoicon.y = 40
    leveltwoicon:addEventListener("tap", gototwo)

    rect = display.newRect( 100, 100, 100, 50 )
    localGroup:insert( rect )

    function resetData (event)
    _G.onelock = 1
    _G.twolock = 0
    rect:addEventListener("tap", resetData)

    Find where seticontwo() is in the code (near the bottom) and replace it with what I have above. That will add a white rectangle and will do what you were talking about :)

  31. For my sample I think this should work, but test it ;)

    function resetData (event)
    _G.onelock = 1
    _G.twolock = 0

    And just add that to a button somewhere, anywhere, in the app. It should work.

    Let me know :)

    And no worries on the quick response. I will be in bed very soon but when I am awake I try to reply fast :)


  32. Thanks for your super quick response! Impressed!

    Could you share an example of code with us?

  33. Hi Peach!

    Congratulations for the tutorial! You’re my best Corona Teacher. I appreciate your tutorials and you really deserve my small donation.
    One question: ¿What about a buttom to reset the levels? I think it’s quite important to give the player the possibility to choose between the saved version or a new one.
    Thanks for all! You’re great!

    • Thank you very much!

      I saw that you donated to me just now, you did so once before, I believe it was February – but I wasn’t sure who you were so I couldn’t say thanks at the time :)

      I really appreciate it, both in February and tonight – thank you :)

      As to a button to reset them, I agree; this is a good idea.

      You would have a function that set all of your variables back at what they were originally – my example uses 0 for locked and 1 for unlocked – so in a function you’d go through and set level1lock = 0, level2lock = 0, etc. and then on the last line of the function use saveit.save()

      That would clear all the saved data you wanted :)

  34. Great tutorial! I recently found your site while researching saving files in Corona. Could you explain the (“*a”) and (“w+b”) I see in the code? What do these letters mean?

  35. Yes, you would simply replace all the _G.onelock with _G.highScore :)

  36. what if i only want to have one saved thing there like a highscore what whould it be? would it look like


    and than any variable where I put the _g.onelock.. would i put (_G.highScore)

  37. (_G.onelock ..”, “.. _G.twolock ..”, “.. _G.threelock)

    That :)

  38. Thanks for the quick response. How would I properly add _G.threelock to file:write( _G.onelock ..”, “.. _G.twolock)? I guess I’m just not understanding the setup.

  39. Hey guys :)

    @Nathan – Make sure you have added it in all the appropriate areas (setting it to 0 if it doesn’t exist yet, adding it to file:write() Once you’ve done that be sure to change the name of the file where data is being saved, then try it again.

    @Scilance – thank you :) No, there is no easy way to access the file. It’s not impossible, nothing is, but it is certainly not something you need to worry about.

  40. Love the example, thanks much! However, I do have a question. Can users gain access to this file via some external means and edit it? I want to have in-app purchases and store their lock state in a file. But if users can simply hack the file and unlock the items, then doing it via a file is pointless. Thoughts?


  41. I’m having the same problem that David had earlier. How do I add a 3rd or 4th prevState? I tried the exact same code as David but received an error as soon as i added prevState[3]

  42. Sorry Paul,

    Your comment got briefly buried in my mod. que. You should be on auto post approval now :)

    Well done on solving the problem; you’ll end up changing the name of the save file many times when testing; I did it 40 odd times for Pixel Slice :)


  43. Hey,

    Sorry – been totally swamped the past day or so. You can name it anything you want, although _G.highScore makes the most sense (IMHO) as you may use “score” for your normal score?

    Then remove the unneeded parts, as you said :)


  44. Duh. Answered my own question. My solution was to change the name of the file the values were being saved to. With this code, if the file exists, the values are not added. The loop that adds the values only runs when the file is new.

  45. Truly wonderful example. I was able to leap forward very quickly with this code.
    But, I’m having trouble understanding how to add a third (and forth, and fifth) button to the mix. I’m clueless as to the syntax of the
    file:write( _G.onelock ..”, “.. _G.twolock)
    No idea what that means.
    Assumed that I needed to change it to
    file:write( _G.onelock ..”, “.. _G.threelock)
    then did
    if file then
    print(“Loading our data…”)
    local contents = file:read( “*a” )
    – Loads our data

    local prevState = explode(“, “, contents)

    _G.onelock = prevState[1]
    _G.twolock = prevState[2]
    _G.threelock = prevState[3]
    io.close( file )

    _G.onelock = 1
    _G.twolock = 0
    _G.threelock = 0
    But that resulted in threelock being ‘nil’, which caused any reference to it to fail.

    –it’s painful being this ignorant.

  46. So i am guessing that I would just change the _G.onelock to _G.score and remove the _G.two lock from the code right?

  47. Peach can this be used for having a high score in the game that gets updated if I beat the highscore during a game?

  48. This is a great example of saving / loading data! Thanks for the tutorial, Peach! I’ll donate as soon as I get this month’s app money from Apple!

    • Hey Jeff, thrilled you like it :)

      If you can afford a small donation it would of course be most appreciated, but honestly I’m more than grateful enough for the kind words!

      Peach :)

 Leave a Reply



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.