I was wondering if it is possible to lock and unlock levels using storyboard. I saw a post from Peach Pellen talking about a way to easily lock and unlock levels but her example was taken down. Basically I was looking for a way/code that when you beat level 1, it unlocks level 2, and so on. [import]uid: 72845 topic_id: 34528 reply_id: 334528[/import]
Hi @FL,
Level “unlocking” should be managed using a data file stored in the app’s Documents directory, as either a text file, JSON file, or local SQLite database. The reason is, you want this data to persist after the app is closed and again when the user returns. A file in the Documents directory persists as long as the app is installed on the device, and thus it remains as a way to read and write aspects of the game like high score, levels unlocked, awards earned, etc.
Here’s are 3 tutorials that you can read:
http://www.coronalabs.com/blog/2012/02/14/reading-and-writing-files-in-corona/
http://www.coronalabs.com/blog/2011/08/03/tutorial-exploring-json-usage-in-corona/
http://www.coronalabs.com/blog/2012/04/03/tutorial-database-access-in-corona/
Let me know if you have any specific questions,
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137302[/import]
Looks like I need to get my SQL guru to help me out with this one. From what I gather Peach Pellen is no longer with Corona but their were posts that I saw stating “Level unlocking made easy with Ego”. Is that something that still exists or that all archaic now? And after seeing the tutorials I feel like an idiot for using the words Lock and unlocking being that its just calling info from data tables. Gotta start somewhere though right?
[import]uid: 72845 topic_id: 34528 reply_id: 137310[/import]
Hi @FL,
“Ego” was just one module method based on the same practices I mentioned to you, and there are actually better and more efficient modules. I can walk you through the process step-by-step with code examples from my own projects. You certainly don’t need an SQL guru to accomplish this. 
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137312[/import]
If you have examples that would be awesome. I feel like Neo going down the rabbit hole right now lol [import]uid: 72845 topic_id: 34528 reply_id: 137314[/import]
The first thing for you to consider here is, “how much” data do you need to save between app sessions? Only the unlocking of levels and maybe high score? Or, do you plan for an app with a huge slew of data like multiple “products”, properties, player profiles, etc.? This determines the approach we’ll use going forth, either text, JSON, or SQLite.
As for the “blue pill”, I think I lost it… I dropped it and it rolled under the virtual sofa or something. Looks like you’re stuck with the RED pill. 
Brent
[import]uid: 200026 topic_id: 34528 reply_id: 137317[/import]
Woohoo red pill ftw! Basically I want to have 140 levels set across 7 worlds. Beat level 1 world 1 and unlock Level 2 World 1, and so on until you unlock the next world etc. I eventually want to have it so a user can “Like” a page on facebook and unlock and extra 20 levels in the Demo (not sure if that matters right now or not). I want my “locked” levels to have a lock icon or something on them until they beat they previous level. Hopes this helps put into perspective where I’m trying to go with this. Thanks a ton Morpheus er Brent
[import]uid: 72845 topic_id: 34528 reply_id: 137318[/import]
My email is fakemode@gmail.com
Thanks for reaching out. [import]uid: 72845 topic_id: 34528 reply_id: 137321[/import]
Hi @FL,
In your case, I think reading and writing a text file will suffice nicely (because you’re going for a fairly simple level/world unlock method).
The first thing you’ll need to do is create the text file when the app loads… because it won’t exist on the first run. This involves merely opening an IO connection, checking that the file doesn’t already exist (because obviously you don’t want to overwrite it later), then writing to the text file, and finally closing the IO connection.
Here’s the basic code for that… let’s start with your “world” data file, which we can keep separate from your “level” data file, at least for the moment (we can combine them later if you prefer). Place this in your main.lua.
local filePath = system.pathForFile( "worlddata.txt", system.DocumentsDirectory )
local file = io.open( filePath, "r" ) --check if the file already exists
--if it doesn't exist, let's create it!
if not ( file ) then file = io.open( filePath, "w" ) --open the IO for file writing ("w")
for i=1,7 do --create 7 lines, for your 7 worlds
local unlocked = "false" ; if ( i==1 ) then unlocked = "true" end --ensure that the first world is unlocked on creation
file:write( "world",i,": unlocked=",unlocked,"\n" ) ; unlocked = nil
end
end ; io.close( file ) ; filePath = nil ; file = nil
That’s basically it for the first stage of the process! It should create a text file in your app’s Documents directory by the name of “worlddata.txt”. To view this file and ensure it was created, go into the Corona Simulator, File > Show Project Sandbox, then open the folder for your app (it should be selected). In that folder, open the “Documents” subfolder, and you should see your text file there.
Its contents should simply be this:
world1: unlocked=true
world2: unlocked=false
world3: unlocked=false
(etc.)...
world7: unlocked=false
Later, you can add other parameters to each line if you need, i.e. if you want to store other information about each world. We’ll deal with that later though.
Let me know how this goes, and you’ll see just how deep this “rabbit hole” goes. 
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137388[/import]
It did just as you said it would. By the way, mind blown about the whole sandbox thing, I haven’t seen that before. Should I be storing all of my files in the sandbox? assets, etc… [import]uid: 72845 topic_id: 34528 reply_id: 137453[/import]
Hi FL,
Don’t worry too much about the “sandbox” concept at this point… and don’t move your assets or lua files in there specifically when developing. Those files should remain in your project directory and subdirectories. The “project sandbox” in regards to the Simulator is where you can find those things stored in the app’s Documents folder (as it would relate to the device build).
Go ahead and study over the text file code I gave you, and let me know if any lines are complete “gibberish” at this time. I can help explain them better if so.
Then, we move on to the text file read and update procedures. Those are fun! (really, they are, when the core procedure starts to make sense).
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137455[/import]
Makes sense to me for the most part, only bit of confusion for me is here:
file:write( "world",i,": unlocked=",unlocked,"\n" ) ; unlocked = nil
end
end ; io.close( file ) ; filePath = nil ; file = nil
If you could explain this a bit more I think we’re good to move on. My main question is about the “nil” values, and the “,unlocked,”\n" )". Other than that it all makes sense. [import]uid: 72845 topic_id: 34528 reply_id: 137456[/import]
OK cool. So basically, you’ll see that I create a local variable “unlocked” during each iteration of the loop (and then discard it at the end of the loop). It begins as “false” each time. Only on the first iteration… i=1… do I change it to “true”, because I want only the first world to be set as unlocked=true when the text file is created. All of this is done on line 6.
Now, line 8. What you see in the parentheses is what gets written to the line in the text file. Sections of that line are written in a series of things separated by commas. Everything within quotes gets written as an absolute text value. Everything else is the value of a variable… you see the ,i, part is writing the current iteration of the loop. And the ,unlocked, part refers to the local variable I described above, either true or false.
The last part is the "\n", which indicates a new line break. Put that anywhere you want to break to a new line when writing a text file.
Last line, I basically just nil out both “file” and “filePath”, the local variables I created at the start. This makes sure all of that file stuff and IO references I opened are all removed from memory.
Tomorrow (Saturday) I’ll post the read process. 
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137469[/import]
Awesome thanks for clearing that up. I can’t wait for the next step.
[import]uid: 72845 topic_id: 34528 reply_id: 137472[/import]
Moving on! The next step is to READ your text file. We’re going to do this in a few steps.
- First, you need to just read the entire thing into a Lua string. Once it’s there, you can cherry-pick aspects of it. Here’s the code for reading it all in:
local filePath = system.pathForFile( "worlddata.txt", system.DocumentsDirectory )
local contents = "" --create empty string for the contents that will be read in
local file = io.open( filePath, "r" ) --IO open the file ("r" argument = "read" )
if ( file ) then
contents = file:read( "\*a" ) --set "contents" to text file contents ("\*a" gets everything)
io.close( file ) ; file = nil ; filePath = nil --close the IO and nil out file references
end
Reference on io.read is here, if you want to check it out:
http://docs.coronalabs.com/api/library/io/read.html
- Now, you have a Lua string “contents” which contains the entire text file contents. You can confirm that it read everything properly by just saying
print( contents )and looking at the Terminal to see its output.
Let that soak in, then let me know when you’re ready for the next step: cherry-picking and reading just one tiny element (or line) of the contents.
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137511[/import]
Works like a charm. Seems like I’ll be battling agents in no time! [import]uid: 72845 topic_id: 34528 reply_id: 137567[/import]
Go ahead and look at the woman in the red dress.
I’ll answer the next part tomorrow (Sunday).
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137589[/import]
Hi FL,
Let’s move on to reading that “content” file in a loop. This might look a bit weird at first, but it’ll soon make sense.
Lua has several string find/manipulate functions which you can read about here:
http://docs.coronalabs.com/api/library/string/index.html
In this case, I’ll deal with string.gmatch. This will search through a big block of text and return a series of matches based on the string “patterns” you define. It makes sense to use that in your case, because you probably want to loop through the entire text document at once and determine which of your 140 levels (or which of the 7 worlds) are unlocked. You could do it one by one, but that would be incredibly tedious!
Here’s the basic code we’ll use here. What this does is search through your entire “contents” string looking for a common “pattern” that will reveal, to you, the status of each world (locked or unlocked)
for worldNumber, isUnlocked in
string.gmatch( contents, "world(%d+):%sunlocked=(%w+)\n" ) do
print(worldNumber,isUnlocked)
end
You can read all about string matching here (under “Patterns”), but it’ll probably be like looking at the Matrix. Just concentrate on the simple usage for now; as you practice it’ll become clearer.
http://developer.coronalabs.com/content/strings
Let’s go through line by line. Remember, the common line in your text string looks something like this:
world1: unlocked=true
So…
for worldNumber, isUnlocked in
This tells Lua that you want to search for two “matches” in each line, so you can use them in your code. You’ll need the world number and its unlocked value (true or false).
Next is the string matching, which looks nutty.
string.gmatch( contents, "world(%d+):%sunlocked=(%w+)\n" ) do
contents: the first argument: your text string that you read from the file.
world: here, you’re reading a constant value “world”, because each of your lines in the file start with the constant “world”.
code[/code]: now this is focal! By putting this in parentheses, you’re defining it as one of your wildcard pattern matches. %d means that you only want to search for digits, not letters or other characters. This is fine because all of your worlds end with a number. + following the %d means that you want to search for at least one number in the match… so it could be 1, 2, or 2022033 and return a match.
: is another constant, just a colon following your world number, as you see in the text file.
%s[/code] is a reserved wildcard for a _space_, which lies between the colon and the next constant bit [code]unlocked=
code[/code]is your second wildcard match, the part following “unlocked”. It’s either “true” or “false”, so you want to use %w as the matching pattern, which seeks all alphanumeric characters. As before, the + says that you want to look for multiple characters… if you omit that, the search will fail because “true” and “false” are obviously not just one letter in length!
\n tells Lua that a line break has been found, so you stop searching on that line.
print(worldNumber,isUnlocked) prints out your matches. See the Terminal!
I think that’s more than enough for now… I suspect this will need some follow-up Q&A, so let me know what you get from this.
Brent
[import]uid: 200026 topic_id: 34528 reply_id: 137630[/import]
Took me an extra day to process all this but I think I understand.
My terminal now shows:
2013-01-07 13:47:52.339 Corona Simulator[35179:903] 1 true
2013-01-07 13:47:52.340 Corona Simulator[35179:903] 2 false
2013-01-07 13:47:52.340 Corona Simulator[35179:903] 3 false
2013-01-07 13:47:52.340 Corona Simulator[35179:903] 4 false
2013-01-07 13:47:52.340 Corona Simulator[35179:903] 5 false
2013-01-07 13:47:52.340 Corona Simulator[35179:903] 6 false
2013-01-07 13:47:52.341 Corona Simulator[35179:903] 7 false
which if I’m not mistaken is where I want to be right now. [import]uid: 72845 topic_id: 34528 reply_id: 137736[/import]
Hi @FL,
Level “unlocking” should be managed using a data file stored in the app’s Documents directory, as either a text file, JSON file, or local SQLite database. The reason is, you want this data to persist after the app is closed and again when the user returns. A file in the Documents directory persists as long as the app is installed on the device, and thus it remains as a way to read and write aspects of the game like high score, levels unlocked, awards earned, etc.
Here’s are 3 tutorials that you can read:
http://www.coronalabs.com/blog/2012/02/14/reading-and-writing-files-in-corona/
http://www.coronalabs.com/blog/2011/08/03/tutorial-exploring-json-usage-in-corona/
http://www.coronalabs.com/blog/2012/04/03/tutorial-database-access-in-corona/
Let me know if you have any specific questions,
Brent [import]uid: 200026 topic_id: 34528 reply_id: 137302[/import]