Ice

Posted by GrahamRanson, Posted on September 29, 2011, Last updated November 13, 2011

28 votes
GitHub URL: 
https://github.com/GrahamRanson/Ice

Ice allows you save and load data when using the Corona ® SDK. It is very simple to use and allows you to create as many 'iceboxes' as you like.

Great for storing local high scores, settings and other data.

I hope to update my site here - http://grahamranson.co.uk/lib.php?id=6 - with proper usage instructions but until then you can get the majority of stuff done pretty easily.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require( "ice" )
 
local settings = ice:loadBox( "settings" )
settings( "difficulty", "easy" )
settings( "volume", 0.7 )
settings( "playerPosition", { x = 100, y = 45 } )
settings:save()
 
local scores = ice:loadBox( "scores" )
scores:store( "best", 100 )
scores:storeIfHigher( "best", 65 )
scores:storeIfHigher( "best", 105 )
scores:save()
 
print( scores:retrieve( "best" ) )

Here is some simple code to show how you could initialise some values on first load only:

1
2
3
4
require( "ice" )
 
settings = ice:loadBox( "settings" )
settings:storeIfNew( "volume", 0.5 )

Here is a very simple demo to show incrementing values ( useful for scores ). You are also able to decrement value just as easily.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
require( "ice" )
 
-- Load or Create our Score box
local scores = ice:loadBox( "scores" )
 
local description = display.newText( "Tap each player to increment score.", 0, 0, "Helvetica", 19 )
description.x = display.contentCenterX
description.y = 100
 
-- Increment Player 1 Score
local onPlayer1Tap = function( event )
        scores:increment( "player1", 1 )
        scores:save()
end
 
-- Increment Player 2 Score
local onPlayer2Tap = function( event )
        scores:increment( "player2", 1 )
        scores:save()
end
 
-- Reset both scores
local onResetButtonTap = function( event )
        scores:store( "player1", 0 )
        scores:store( "player2", 0 )
        scores:save()
end
 
-- Create Player 1
local player1 = display.newRect( 0, 0, 150, 150 )
player1:setFillColor( 255, 0, 0 )
player1.x = display.contentCenterX - player1.contentWidth / 2
player1.y = display.contentCenterY
player1:addEventListener( "tap", onPlayer1Tap )
 
player1.text = display.newText( "Player 1", 0, 0, "Helvetica", 30 )
player1.text.x = player1.x
player1.text.y = player1.y - player1.text.contentHeight
 
player1.score = display.newText( "0", 0, 0, "Helvetica", 30 )
player1.score.x = player1.x
player1.score.y = player1.y
 
-- Create Player 2
local player2 = display.newRect( 0, 0, 150, 150 )
player2:setFillColor( 0, 0, 255 )
player2.x = display.contentCenterX + player2.contentWidth / 2
player2.y = display.contentCenterY
player2:addEventListener( "tap", onPlayer2Tap )
 
player2.text = display.newText( "Player 2", 0, 0, "Helvetica", 30 )
player2.text.x = player2.x
player2.text.y = player2.y - player2.text.contentHeight
 
player2.score = display.newText( "0", 0, 0, "Helvetica", 30 )
player2.score.x = player2.x
player2.score.y = player2.y
 
-- Create Reset Button
local resetButton = display.newRect( 0, 0, 200, 100 )
resetButton:setFillColor( 0, 255, 0 )
resetButton.x = display.contentCenterX
resetButton.y = display.contentHeight - resetButton.contentHeight + 20
resetButton:addEventListener( "tap", onResetButtonTap )
 
resetButton.text = display.newText( "Reset Scores", 0, 0, "Helvetica", 30 )
resetButton.text.x = resetButton.x
resetButton.text.y = resetButton.y
resetButton.text:setTextColor( 0, 0, 0 )
 
-- Update the score displays
local onEnterFrame = function( event )
        player1.score.text = scores:retrieve( "player1" ) or 0
        player2.score.text = scores:retrieve( "player2" ) or 0
end
 
Runtime:addEventListener( "enterFrame", onEnterFrame )


Replies

fava's picture
fava
User offline. Last seen 1 day 1 hour ago. Offline
Joined: 21 Feb 2011

Excellent - thanks for sharing!

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Hopefully it's useful to more than just me :-)

rmbsoft
User offline. Last seen 3 hours 22 min ago. Offline
Joined: 5 Apr 2011

Thank you for sharing this!

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Happy to :-)

nicholasclayg's picture
nicholasclayg
User offline. Last seen 13 hours 16 min ago. Offline
Joined: 16 May 2011

I was just looking around for a scoring system, but since i'm lame still they seemed to complicated. I think I'm going to give this a try.

I'd like to see a simple example of a game in use. Something like I don't know take a rectangle, add event listener to it to add 1 to the score, then seeing how this fancy pants score thing works and how it loads and saves data. Or somethin'

I'll be back if I can figure it out and post. Off to coding magic land fun time.

-ng

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Just added a demo to the description to show how easy it is to add 1 to the score on a button press. Could easily be hooked up to any other event as well as add more than just 1 to the value.

nicholasclayg's picture
nicholasclayg
User offline. Last seen 13 hours 16 min ago. Offline
Joined: 16 May 2011

I finally got a chance to check it out.

It's cool!

I noticed, that after I launch it tap a few times on player 1 or 2 that the score stays there. I think that's really cool.

Ok Mr. fancy pants, this is very nice. I also noticed you got away from the package...seeall stuff as well.

I'm going to start with this and put it into my game. Then find a way to send scores to facebook, twitter, openfient, gamecenter etc etc.

I suppose I could also use this and cook up a way to show when a level is complete (something like bubble ball, when you complete a level, it shows it marked). Looks like the logic is there, but I don't know if would be suitable for something like that.

Maybe one day I can have a

"Developed with Corona"
ALSO
"MADE WITH LIME AND ICE"...sounds like a tasty drink to me. Of course you also have "Rum" so if i make a game with all of that, people will think I have a pub or something...lol.

Anyway, great stuff as always!

ng

hsardaryan's picture
hsardaryan
User offline. Last seen 3 hours 45 sec ago. Offline
Joined: 19 Feb 2011

@GrahamRanson is it me or ice cannot save/load table which has more than 2 elements/fields?

code snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- definition
local myTable = {}
-- initialization
for i=1, 351 do
myTable[i] = { x, y, path, isBusy = false }
end
 
-- somewhere inside the code, inside some loop
myTable[i] = display.newImage ( img_path )
myTable[i].path = img_path
myTable[i].x = 10
myTable[i].y = 20
myTable[i].isVisible = true
myTable[i].isBusy = true
 
-- now trying to save that
local myBox = ice:newBox ( "myBox" )
myBox:store( "myTable", myTable )
myBox:save()

console gives me error
1
2
3
4
5
6
7
8
9
10
11
Runtime error
        Encoding of function: 0AABD3B8 unsupported
stack traceback:
        [C]: ?
        [C]: in function '?'
        ?: in function 'WriteError'
        ?: in function 'WriteFunction'
        ?: in function 'Write'
        ?: in function 'WriteTable'
        ?: in function 'Write'
        ?: in funct

what I am doing wrong? O_o

hsardaryan's picture
hsardaryan
User offline. Last seen 3 hours 45 sec ago. Offline
Joined: 19 Feb 2011

ok, I guess I got it!
you can't save this

1
myTable[i] = display.newImage ( img_path )

because it's some kind of object or whatever. You should save only it's field values aka only table.
here is my solution, if someone is interested
1
2
3
4
5
6
7
8
9
10
11
12
local _myTable = {}
for i = 1, #myTable do
_myTable[i] = { x, y, path, isBusy }
_myTable[i].x = myTable[i].x
_myTable[i].y = myTable[i].y
_myTable[i].path = myTable[i].path
_myTable[i].isBusy = myTable[i].isBusy
end
 
local myBox = ice:newBox ( "myBox" )
myBox:store( "myTable", _myTable )
myBox:save()

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

@ nicholasclayg - As long as you call the save function on your box ( or set it to autosave ) then the data will be persistent between app loads etc.

Yup, completely moved away from packaging, and Lime only has Utils really that uses that ( and the actual lime.lua file ) so I am close to being completely rid of it.

I'm actually thinking of putting a generic upload function in just to be able to upload a box to a web server and then you could download it again on another device ( given a unique url and code or something ) allowing basic backing up and syncing possibly.

For level locking it would certainly be suitable, you could do something like this:

1
2
3
4
5
6
7
local levels = ice:loadBox( "levels" )
levels:store( "level1", true )
levels:store( "level2", false )
levels:store( "level3", false )
levels:store( "level4", true )
levels:store( "level5", false )
levels:save()

And then you can just change their values to true/false when unlocking/locking and then change the graphic of a level icon to be locked or not depending on their values.

@ hsardaryan - You won't be able to save out the displayObject ( display.newImage ) using Ice as I have now idea how to serialise / deserialise those. You could just save out the path to the image and then recreate / destroy the image when loading / saving.

hsardaryan's picture
hsardaryan
User offline. Last seen 3 hours 45 sec ago. Offline
Joined: 19 Feb 2011

@GrahamRanson yes! I already figured it out, thank you for such a great module!

p.s.
pls make some documentation/how-to on it :)

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Yea you beat me to it well done :-)

Documentation is next on the to-do list, I didn't want to spend ages on docs if it turned out no one actually wanted the module but as atleast 2 people are using it without the docs I can only assume that atleast 4 would use it with :-)

hsardaryan's picture
hsardaryan
User offline. Last seen 3 hours 45 sec ago. Offline
Joined: 19 Feb 2011

I confirm ICE is working EXCELLENT on iDevice!!
Thanks again @GrahamRanson

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Woooo! Glad to hear it, thank you for checking. *In theory* it should work on Android as well, but you never know :-)

Naomi's picture
Naomi
User offline. Last seen 51 min 59 sec ago. Offline
Joined: 6 Jun 2011

Thank you for sharing, Graham.

I just downloaded the ice.lua and main.lua package to take a quick look, and I noticed there is no mention of MIT license in ice.lua, or any mention of it being free to use (for commercial or personal purposes). I'm wondering if it's just an oversight, or it is indeed copyrighted material with reserved rights, and if so I feel I shouldn't really include it in my game project...

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Oops this was a silly oversight on my side. Please assume anything I put on my GitHub account to be MIT licensed. I will get round to adding in the licences when I get a chance but you are free to do whatever you like with it.

Naomi's picture
Naomi
User offline. Last seen 51 min 59 sec ago. Offline
Joined: 6 Jun 2011

That sounds great! Thank you, Graham!

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

No worries, hope it helps. I can confirm that it does work on devices and I currently have two apps on the app store that use it. So far no issues :-)

photiscta
User offline. Last seen 2 hours 12 min ago. Offline
Joined: 16 Feb 2011

Thank you very much Graham for this! It's great and very - very useful.
A simple documentation would be also nice.
Thank you!
:)

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Documentation is coming, when I find some time :-) In the mean time, is there anything specific you would like explained?

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Hey Graham, I'm finally able to start incorporating ice.lua to my game project, replacing the simple json based save/load functions I've worked out a few months ago.

I have a quick question (and let me know if I should email you directly from your website for questions like this). I have:

1
2
-- in my main.lua
json = require("json")

Since ice.lua requires json and sqlite3, I'm replacing the above with requiring ice, but I'm not sure which way I should go:

1
2
3
4
5
6
-- should I simply require like this:
require( "ice" )
 
-- or... can I require like this?
-- could there be any harm in doing so?
ice = require( "ice" )

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Hey, you will be fine with the first line and should be fine with the second, I can't see any reason why it wouldn't like that.

Feel free to either post on here with questions or email me, whichever you prefer.

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Thank you Graham. I'm a real newbie, and if I'm asking too many things that I should know already, please just let me know.

Anyhow, as I mentioned, I have save/load system using json. I'm going to keep it in place as I establish a new ice based system.

So, after I require ice, what do I do next? How do I initialize the icebox? I'm guessing, my code must first check if any icebox is already saved, and if it is saved, load the icebox, if not I can safely create and save it at run time.

When using json, I initialize the data table and then, after that, I call load function like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
-- initialize data
local myData = {}
local numLoop;
local maxDataEntry = 100 -- this is just for example, and in this case, it assumes there are 100 data entry
 
-- initializing the variables
for numLoop=1,maxDataEntry
        myData[numLoop] = 0;
end
 
--this is how I load data
local function loadData()
        -- io.open opens a file at path. Returns nil if no file is found
        file = io.open( path, "r" );
        -- nothing is loaded if there's no file found
        if file then
                -- read all contents of file into a string
                contents = file:read( "*a" );
                scoreList = json.decode( contents );
                io.close( file );
        end
end
loadData();
 
-- during the game play, myData table will be modified
-- every time any data value changes, I call saveData function like this:
local function SaveGame()
        file = io.open( path, "w" );
        if file then
                contents = json.encode( myData );
                file:write( contents );
                io.close( file );
        end
end

How do we do this using ice? How can I find out if there is icebox already saved? If icebox is found, I'd want to load it after I initialize the data. Or should I be thinking differently?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

When you call "loadBox" ice will either load an existing one if it is there or create a new empty one for you and then load that, so you don't need to check if it exists already to use it, you simply call this line, probably in main.lua:

1
data = ice:loadBox( "data" )

So for your code as above but with Ice you could do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
require( "ice" )
 
data = nil
 
function loadData()
     data = ice:loadBox( "data" )
end
 
function saveData()
     data:save()
end
 
function addOrChangeData( name, value )
     data:store( name, value )
end
 
loadData()
 
-- during gameplay
addOrChangeData( "score", 20 )
addOrChangeData( "lifes", 4 )
addOrChangeData( "playerPosition", { x = 30, y = 100 } )
 
-- then after gameplay like at the end of the level or something
saveData()

The reason I only call save once is that that function will do the actual file access, which is something you don't really want happening during gameplay as it can cause slowdown. But Ice will still store all your changes during gameplay fine and can be retrieved and edited fine throughout the whole time the app is running, you just need to save it to disk before the app closes.

Technically if you just wanted persistant data while the app is running, say between director screens etc, you wouldn't even need to save the data as it would then just get wiped on app reload.

Hope that helps!

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

A quick note, about how to require ice.

ice = require( "ice" ) gave me run time error: attempt to index global 'ice' (a boolean value) when I added the following in main.lua:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ice = require("ice")
 
print( "" )
print( " -- BOX: credits -- " )
local box1 = ice:loadBox( "credits" )
box1:print()
print( "" )
 
print( " -- BOX: food -- " )    
local box2 = IceBox:new( "food" )
box2:load()
box2:print()
print( "" )
 
print( " -- BOX: player -- " )  
local box3 = IceBox:new( "player" )
box3:load()
box3:print()
print( "" )

Changing ice = require("ice") to simply require("ice") worked just fine.

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Thank you, Graham, for the post #24 above. OMG, your ice class sounds sooooo incredibly easy to use! I feel like I now know all I need to know to convert my save/load system using ice!

This is an awesome class!!

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

Very happy to hear it's going well. Any more questions just ask and feel free to tell your friends about Ice :-)

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

I sure will mention ice class to anyone who might be looking to save/load data. This is just too amazing not to use.

By the way, can anyone simply edit the .ice file using text editor and manipulate the saved data? How is the saved data protected?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

It is first encoded into json and then saved into a single field in an sqlite database and given the extension of .ice, naturally if someone first realised what type of file it is they would then have to open it up in an sqlite viewer and then copy out the data and decode it from json, so it's not overly complicated to get it out and edit it but it will stop the opportunists. Other ways if needed would be to obfuscate the data ( tricky but doable ) or encrypt it ( not possible in Corona at present and also brings in a whole lot more paperwork ).

One thing I am going to possibly do is allow for the .ice file to be easily saved, uploaded to a server and then deleted on app finish, and then re-downloaded, parsed and deleted on app start etc so that it is only ever held in memory on the phone however haven't had time to do this yet.

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

That sounds great, Graham! Thank you!!

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Hey Graham, I'm wondering how I might wipe clean the saved data after it's been saved.

I have Reset Game button, which enable users to revert the game back to original/initial state, i.e., all high score wiped, all unlocked levels go back to locked, etc. Is there a magic function I could call to wipe out all saved data? If not, how might I delete each individual data entry, i.e., what syntax do I use for individual data entry to remove it?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

You can call "clear()" on your box and then you will want to save it, like so:

1
2
box:clear()
box:save()

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Awesome! That's the magic function I was looking for. Thank you Graham!!!

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

No worries :-)

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

A quick note to newbies like me who are interested in using ice library, here are basics that should get you going. (Graham, please correct me if I haven't gotten this right.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
---------------------------
-- in main.lua
---------------------------
myData = nil -- I believe myData should be a global variable
 
-- load previously saved data
-- if no data has been saved, it will simply return nil
myData = ice:loadBox( "myData" )
 
---------------------------------------------------------
-- in main.lua or in any module where you want to work with myData
---------------------------------------------------------
myData:clear() -- clears all saved data from disk
myData:save() -- saves all data in memory to disk
myData:store( name, value ); -- add or modify data entry in memory at runtime 
myData:retrieve( "saved_data" ) -- retrieves the data entry (from disk?)
 
-- Example:  
-- if you want to save high score, and you want to name the high score entry as highScore
-- and if it is 10000, then:
myData:store("highScore", 10000)
 
-- Example:
--  you use variable bestscore for high score then:
local bestscore = 10000;
myData:store("highScore", bestscore)
 
-- Example (edited):
-- if you want to retrieve previously stored highscore
-- and assign the value of the retrieved highscore to a local variable:
local highScore = myData:retrieve( "highScore" ) 

This is all I needed to know to use this library. So amazing.

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

That all looks good to me, who needs documentation? :-)

Actually one small thing, this line:

1
myData = ice:loadBox( "myData" )

If a box with that name hasn't already been created it won't return nil, it will first create an empty box and then return that.

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Graham, thanks for the clarification. I think Asnca should include this library with Corona SDK. It's so easy to use, and it would immensely benefit users with very little coding/programming background.

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

You're welcome to suggest it to them :-)

If anyone from Ansca is reading this, it's all yours if you want to include it.

elbowroomapps's picture
elbowroomapps
User offline. Last seen 16 hours 52 min ago. Offline
Joined: 8 Jun 2011

When I downloaded ICE, there was also a main.lua file with examples. In that file you use both ice:newBox and IceBox:new.

Are those 2 functionally the same or is there some reason to use one or the other?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

They will both result in a box just the same however the small difference ( that I really should have explained but will do when I write proper docs ) is that the ice:newBox function also stores that box in a table owned by Ice which allows you to create them at anytime ( rather than just in main.lua ) and access them from anywhere via Ice:getBox( name ).

You can also do most of the other functions through helper functions on Ice, it really just depends on how you like to work.

m.riebesehl
User offline. Last seen 28 weeks 3 hours ago. Offline
Joined: 26 May 2011

Brilliant work Graham. Keep it going ... :-)

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

I intend to :-)

r.pudlowski's picture
r.pudlowski
User offline. Last seen 1 week 6 days ago. Offline
Joined: 9 Mar 2011

Hi Graham, excellent code :)
i have a question. In my game, i have 5 levels and i want to keep a different highscore for each of them.
So in each level, at the end of the game, i have a code like this:

1
2
3
4
5
6
7
8
9
10
11
12
myData = ice:loadBox( "myData" )
myData:retrieve( "highscore1") 
if highscore1 == nil then
highscore1 = points;
myData:store("highscore1", points)
myData:save()
end
if highscore1 < points then
highscore1 = points;
myData:store("highscore1", points)
myData:save()
end

So in theory i have 5 highsocres in "mydata". (highscore1, highscore2...)
On each level, for the comparison of the score with the highscore, it works well, but i have a problem in the "score" menu (i'm using director).
i have a code like this:
1
2
3
4
5
6
7
require( "ice" )
myData = ice:loadBox( "myData" )
myData:retrieve( "highscore1") 
myData:retrieve( "highscore2")
myData:retrieve( "highscore3")
myData:retrieve( "highscore4")
myData:retrieve( "highscore5")

but all the datas are "nil", instead of reading well on the level... :(
What i am doing wrong?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

In your first code block the separate "highscore1" variable will never be anything as you aren't assigning it. You would want instead to do this:

1
highscore1 = myData:retrieve( "highscore1")

You could instead do something like this:

1
2
3
local myData = ice:loadBox( "myData" )
myData:storeIfHigher( "highscore1", points )
myData:save()

And then in your second block again you have the same issue, you are not assigning the retrieved variables to anything you are just calling the functions, you would want to do something like this:

1
2
3
4
5
6
local myData = ice:loadBox( "myData" )
local highscore1 = myData:retrieve( "highscore1") 
local highscore2 = myData:retrieve( "highscore2")
local highscore3 = myData:retrieve( "highscore3")
local highscore4 = myData:retrieve( "highscore4")
local highscore5 = myData:retrieve( "highscore5")

You then have all the scores that you can display in your menu.

r.pudlowski's picture
r.pudlowski
User offline. Last seen 1 week 6 days ago. Offline
Joined: 9 Mar 2011

worked like a charm :) thank you a lot Graham, you are the best! :)
when you use myData:save(), it saves the myData to the "disk"?
Wouldn't it be better to check if the score is better than the highscore before saving to disk, because it uses more battery?

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

True, you could change to this:

1
2
3
4
5
local myData = ice:loadBox( "myData" )
local wasAdded = myData:storeIfHigher( "highscore1", points )
if wasAdded then
     myData:save()
end

Joe Kool
User offline. Last seen 5 weeks 20 hours ago. Offline
Joined: 1 Jun 2011

This isn't working, like at all. Its acting like it isn't even registering the
first:store() : (

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
require( "ice" )
        system.activate( "multitouch" )
    local scores = ice:loadBox( "scores" )
    local first = ice:loadBox("first")
         
    
   local function setScore()
         --first:increment("data", 1)
         first:store("value", 0)
                 first:save()
                
                   print (first:retrieve("value"))
 
                
                
                 print "setScore called"
                --  print (first:retrieve("data"))
        if (first:retrieve("data"))==1 then
                savedPts=2000
                --print "first =" .. " ".. (first:retrieve("data"))
                print "this should only happen once"
                scores:store("best", 5000)
                        scores:save()
                print "this worked"
        --              print "savedPts =" .. " " .. (savedPts)
                --  once = (first:retrieve("data"))
        end
    end
   timer.performWithDelay( 1000, setScore, 1)
 <text>
 
Can anybody shed some light on the subject. (sorry its such a mess... LOL)

Naomi's picture
Naomi
User offline. Last seen 52 min ago. Offline
Joined: 6 Jun 2011

Hey Joe, on line#9, you've stored "value". On line #18, you're trying to retrieve "data" -- but when did you store "data"?

If you have not stored "data", first:retrieve("data") will return nil. Maybe "data" was a typo? Did you want first:retrieve("value") instead?

As for first:retrieve("value"), it would return 0, because you've stored it on line #9.

Naomi

GrahamRanson's picture
GrahamRanson
User offline. Last seen 6 days 7 hours ago. Offline
Joined: 29 Mar 2010

As Naomi has pointed out, you seem to have got a copy and paste error on line 18 and you are always saving "value" as 0 on line 9.

Joe Kool
User offline. Last seen 5 weeks 20 hours ago. Offline
Joined: 1 Jun 2011

Oh... oops. That was a typo. They all should say "data".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
require( "ice" )
        system.activate( "multitouch" )
    local scores = ice:loadBox( "scores" )
    local first = ice:loadBox("first")
         
    
   local function setScore()
         --first:increment("data", 1)
         first:store("data", 0)
                 first:save()
                
                   print (first:retrieve("data"))
 
                
                
                 print "setScore called"
                --  print (first:retrieve("data"))
        if (first:retrieve("data"))==1 then
                savedPts=2000
                --print "first =" .. " ".. (first:retrieve("data"))
                print "this should only happen once"
                scores:store("data", 5000)
                        scores:save()
                print "this worked"
        --              print "savedPts =" .. " " .. (savedPts)
                --  once = (first:retrieve("data"))
        end
    end
   timer.performWithDelay( 1000, setScore, 1)
 
It wasn't working like this either.
They don't return 0, They don't even return nil... the terminal doesn't show anything