In this tutorial we’re going to take a look at a pretty interesting feature of the TI-Nspire framework in Lua : save and restore any kind of data directly in Lua, that lets us playing around with a high score for a game or any other configuration data for a more complex program.
Example : You just released a wonderful game. You’d like to share it with your friends, that way they can challenge you thanks to your high-scores system. But how is that working?
The first way you could think of is to use the var API. Therefore, we save the high score in the document as a global variable (math variable).
Your high score system is done ! Hum … wait a second, one of your friend managed to score 10 000 000 points to your game ! What the heck ? He simply modified the global variable you’re using as an high score, since it’s freely accessible via a Calculator application. Here, it is not hard to cheat !
A second way is to protect the first one by using math.eval() which lets us launch any TI-Basic instruction, as the Lock one for example. Then, if we do like so :
math.eval("Unlock highscore") var.store("highscore", highscore) math.eval("Lock highscore") |
our high score variable will be write protected. But, since Lock is a TI-Basic command, it can be launch outside the Lua program. Things aren’t going to be better.
What about looking for a specific Lua command ? Actually, there is var.monitor() that probes a specified variable and checks if this variable will be changed. If so, on.varChange() event is called. This lets us to control any variable changes.
Here is an example :
function on.create() if not var.recall("highscore") then highscore = 0 var.store("highscore", highscore) end var.monitor("highscore") end function on.varChange(list) for k, v in pairs(list) do if k == "highscore" then if var.recall(k) ~= highscore then return 1 -- it is an external change, block modifications else return 0 -- it is an internal change, allow modifications end end end return 0 -- allow modifications of other monitored variables if any end |
This code will disallow any external modification of the highscore variable, with the following error message :
Cannot accept change : Invalid input
Obviously, if you have to do this for multiple variable, for example configuration data, don’t do this since it is a heavy and repetitive method …
It is at this moment that we take a look to the documentation. We can see two trivial events : on.save() & on.restore().
In fact, this event couple does exactly what we expected to do from the beginning !
Actually, when the widget get closed (when we close the document, or copy/cut the widget) the on.save() event is called. You have to define on.save() to make it return any kind of value (boolean, number, string, table etc …). The next time the widget will open (when we open the document, or paste the widget), the on.restore() event will be called, with the data returned by on.save() as the parameter !
Here we are, easy-going :
function on.save() return highscore end function on.restore(data) if type(data) == "number" then highscore = data end end function on.create() if not highscore then highscore = 0 -- first time we initialize highscore end end |