Saving a High Score


LiveCode Files for this Project

Saving data from one session to another

Saving data will become an essential part of most projects. LiveCode has many functions and commands related to saving and using data, including the use of databases, such as mySQL. However, there are a variety of relatively simple ways to also save small amounts of data without needing to use a full-fledged database.

This example shows how to save data generated during one project session and then use it the next time the project is run. We'll use the common example of saving a high score during a game and updating it only when a new high score has been achieved.

Version 1: Simple, but only works when opened in LiveCode

The first version demonstrates a standard way of saving data -- creating a text field and saving data to it. This example shows a wonderful feature of LiveCode, namely that data currently in a text field will automatically be saved when the file is closed. But, this example is severely limited in that it only works while opening the file with LiveCode. It will not save the data once the file has been saved as a standalone application.

The example file consists of only two cards: a game card and a data card. The game is played on game card and saves data to the data card. The idea is that the user never sees the data card. Instead, the game card puts and gets data onto the data card.

The "game" in this example is simply two fields, one for the user to enter his/her name and the other to enter a score. (Yes, it's an easy game!) When you enter the information and click the "Save Data" button, the score entered is compared to the current high score in the field "datafield" on the card "dataCard." If the score is higher, the new score (and the user's name) is put into line 1 of "datafield" in this form:

name, score (example: Lloyd, 88)

The script to compare and then potentially rewrite this data is in the "Save Data" button:

on mouseUp

global varName, varScore

put line 1 of field "getname" into varName
put line 1 of field "getscore" into varScore

if line 1 of field "datafield" on card "datacard" is empty then
put varName&", "&varScore into line 1 of field "datafield" on card "datacard"
end if

if item 2 of line 1 of field "datafield" on card "datacard" < varScore then
put varName&", "&varScore into line 1 of field "datafield" on card "datacard"
end if

openCard

end mouseUp

(Recall that the symbol "&" is used to concatenate (or join) two or more segments of information.)

As shown in this script, segments contained in a string of information separated by commas can be identified by LiveCode using "item 1," "item 2," etc.

The following script is contained on the card "Game":

global varName, varScore, varHighScore, varHighScoreName

on openStack

put empty into field "getname"
put empty into field "getscore"
end openStack

on opencard

if line 1 of field "datafield" on card "datacard" is empty then
put "No high score yet" into line 1 of field "showhighscore"
else
put item 1 of line 1 field "datafield" on card "datacard" into varHighScoreName
put item 2 of line 1 field "datafield" on card "datacard" into varHighScore
put "High score: "&varHighScore&" (by "&varHighScoreName&")" into line 1 of field "showhighscore"
end if

focus on field "getname"

end opencard

Notice that when the stack is first opened, the two text fields on the card are cleared.

The "on Opencard" script first looks to see if there is any data on the field "datafield" on card "datacard." If not, this means that the game has never been played and a placeholder message ("No high score yet") is displayed.

If there is data in "datafield," then the score and the player's name are stripped out and put into two variables ("varHighScoreName" and "varHighScore"). This makes it easier to work with the data in later scripts.

Finally, the information is displayed on the game card using this code:

put "High score: "&varHighScore&" (by "&varHighScoreName&")" into line 1 of field "showhighscore"

The field "showhighscore" is at the top of the card. (Note: When a field is identified on the card containing the script, LiveCode assumes the field in question is on the card. Otherwise, one would need to identify on what card exactly the field can be found, as shown in the earlier code.)

So, the act of opening the card performs the comparison of high score data and then displaying the data on the card. This is the reason the command "opencard" is the last line of code in the script for the button "Save Data."

Version 2: For Standalone Applications, including iPhone, iPad

Version 1 works great while creating and testing a file with LiveCode, but it will not work after the file has been saved as a standalone application. Likewise, it will not work on mobile projects using an iPhone, iPod, or iPad. The reason is that the application itself cannot be altered, which saving new data to a text field would do.

The solution is to create another layer in which the data is stored in-between sessions: a text file stored in a "documents" folder. All iPhone/iPad/iPod applications are stored in their own compartments on the device with a variety of subfolders automatically created, one of which is "documents." You never actually get to see this folder, so you have to just trust that it is there.

Version 2 works basically the same as version 1 but stores the data in a text file in the documents folder called "data.txt."

The card script and the button script shown above have been slightly modified, as shown in bold below

Script for button "Save Data":

on mouseUp

global varName, varScore

put line 1 of field "getname" into varName
put line 1 of field "getscore" into varScore

if line 1 of field "datafield" on card "datacard" is empty then
put varName&", "&varScore into line 1 of field "datafield" on card "datacard"
end if

if item 2 of line 1 of field "datafield" on card "datacard" < varScore then
put varName&", "&varScore into line 1 of field "datafield" on card "datacard"
end if

set the defaultFolder to specialFolderPath("Documents")
put field "datafield" of card "datacard" into line 1 of URL ("file:data.txt")


openCard

end mouseUp

Script for the card "Game":

global varName, varScore, varHighScore, varHighScoreName

on openStack

put empty into field "getname"
put empty into field "getscore"
end openStack

on opencard

set the defaultFolder to specialFolderPath("Documents")
put URL ("file:data.txt") into field "datafield" of card "datacard"


if line 1 of field "datafield" on card "datacard" is empty then
put "No high score yet" into line 1 of field "showhighscore"
else
put item 1 of line 1 field "datafield" on card "datacard" into varHighScoreName
put item 2 of line 1 field "datafield" on card "datacard" into varHighScore
put "High score: "&varHighScore&" (by "&varHighScoreName&")" into line 1 of field "showhighscore"
end if

focus on field "getname"

end opencard

Here is a description of the key code from the button script:

The following code tells LiveCode to make the default folder the "Documents" folder:

set the defaultFolder to specialFolderPath("Documents")

This means that all file exchanges will be directed to this folder.

This line puts data from the LiveCode datafieldinto a text file called "data.txt":

put field "datafield" of card "datacard" into line 1 of URL ("file:data.txt")

Note: If the text file does not exist, it will first create it.

So, when the file is closed, the high score data is stored save and sound in this text field.

When the file is opened the next time, this line of code from the openCard script goes and gets the data from the text field and puts it into the field "datafield" of card "datacard"

put URL ("file:data.txt") into field "datafield" of card "datacard"