highscoreOne frequently-asked question in the forums, especially from those developers new to Corona SDK and Lua, is “How do I keep score?”. Today’s tutorial will walk you through the entire process, including:

  1. Setting up a variable to hold the score.
  2. Displaying the score.
  3. Saving (and retrieving) the score for future use.

The Score Module

Corona does not have a built-in score module, so let’s build one which you can implement in your apps, beginning with a basic “initialization” function:

As you can see, the options we support are:

  • fontSize — The size of the displayed score text.
  • font — The font used for the displayed score text.
  • x — The x location to draw the score display.
  • y — The y location to draw the score display.
  • maxDigits — The estimated number of the max score.
  • leadingZeros true or false: do you want leading zeros?
  • filename — The local filename to save the score to.

Most of these are straightforward, but we could extend this with alignment properties and other settings. For example, we could add options to control the anchor points for left- or right-aligned score text.

The score text uses the string.format() API call to format the number, and the string will either be prefixed by spaces or by zeros, depending on the settings. This format setting (M.format) is also saved to the module for usage in other functions. If any settings aren’t specified, then we fall back to the reasonable defaults, in this case, 24-point Helvetica, centered at the top of the screen, with a maximum of 6 digits. By default, the local save file target is scorefile.txt, but this can be changed to another file name.

Set and Get Functions

Next, let’s write some functions for settinggetting, and adding to the score:

If we set the score, the display will update and overwrite the current value with the new one. The get method simply returns the current score for some other use. Finally, the add function allows us to add to the current score and update the display. This could be extended to a subtract function, but it’s more efficient to just pass a negative value to the add function.

Saving and Loading the Score

The last thing our module needs is the ability to save and load the score to a file. This is required so that the score can be saved and retrieved between app sessions.

As seen on lines 40 and 54, the score file exists in the system.DocumentsDirectory. We cannot write it to system.ResourceDirectory since it’s read-only, and both system.TemporaryDirectory and system.CachesDirectory are prone to automatic cleanup by the system. So, logically, we create and keep this file inside the documents directory so it persists between app sessions.

Let’s quickly inspect the load() function in more depth. This function opens the file, reads the value into a local variable, and returns it. It does not, by design, update the text value on the screen. In many cases, this function will be used to load the last saved score, compare it to the current score, and check if we have a new “high score.” However, if we need to both load the score and display the last saved value, we can simply call the set() function using the value we just retrieved from the load() function.

Finally, on line 68, we return the module’s M table back to the caller, thus making the functions and data available to the caller.

Putting it to Use

With our module created and the basic functions written, we can now use it within our app.

The first line is the mandatory require line which includes the module in our project, providing access to all of the functions we wrote above. The second block calls the init() function with a series of basic parameters. This creates the text display, centers it at the top of the screen, and sets it to a zero-filled seven-digit score.

From this point, the following actions can be executed with just one line:

  • score.set( value ) — sets the value.
  • local myscore = score.get() — gets the current value.
  • score.add( value ) — add value to the current score.
  • score.save() — save the score.
  • local highscore = score.load() — load the previously-saved score.

To see our code in action, please download a version of the ManyCrates sample app that has been modified to work with this module. When an object is touched, the score increases and the object is removed from the display. For variety, each object has a value set for it: 50 points for a small crate, 100 points for a large crate, and 500 points for a green container. Click on each object and watch the score increase. Two buttons have been added to showcase the save() and load() functions. To test it, save the score, reload the app (Control-R or Cmd-R), and then load the score that was just saved. Notice that the text display updates to that value!

Hopefully this tutorial exhibits just how easy it is to work with scores in Corona SDK, including saving and loading scores to the device for persistence between app sessions.

Read article here:

Tutorial: Displaying/Saving/Loading Scores