(Note this problem is not about SSK2, it is just a warning that there will be SSK2 calls)
Hello, everyone. I am currently working on having my character collect coins and save the data to the phone. However, I have come across an issue, it seems as if an incorrect number of coins is being saved to the phone. I tested this by adding a print statement and found that the number of coins printed in the console and saved to the text file is different. The picture is posted below.
Here is the code:
function coin:collision(event) if event.phase == "began" then if event.other.name == "character" then display.remove(self) print("coin collected") coinCount = coinCount + 1 coinText.text = coinCount if io.exists("coin.txt") then local coinCountInt = tonumber(io.readFile("coin.txt")) + 1 local coinCountString = tostring(coinCountInt) io.writeFile(coinCountString, "coin.txt") print(coinCountString) else local coinCountString = tostring(coinCount) io.writeFile(coinCountString, "coin.txt") print(coinCountString) end end end end coin:addEventListener("collision")
It might be something with how I am counting my coins, but the variable being saved to the file is the same one being printed in the console, so I don’t know why the difference occurs.
That looks like a lot of file operations during a short period (within a second) and I guess there might be some overlapping save attempts - while the file is locked by the previous operation or something like that.
If you have lots of coins close to each other, it’s probably a better idea to save the coins count periodically(at checkpoints) or at certain thresholds (like every 10/20/50 coins).
You want to avoid reading from and writing to persistent memory (the disk) that often.
Aside from possible corruption/data loss you will deplete the battery quickly and needlessly.
Here is an alternate solution to minimize actual i/o traffic.
-- Save mechanism with deferment that cancels last outstanding save local lastSave local function saveCoinCount( count ) count = tonumber(count) or 0 if( lastSave ) then timer.cancel(lastSave) end lastSave = timer.performWithDelay( 100, function() lastSave = nil io.writeFile(count,"coin.txt") end ) end
Next, don’t read the coin count AT ALL in the listener. You should only read that at the beginning of the game and then keep track of it in memory.
Finally, do this in your listener:
function coin:collision(event) if event.phase == "began" then if event.other.name == "character" then display.remove(self) print("coin collected") coinCount = coinCount + 1 coinText.text = coinCount io.writeFile(coinCountString, "coin.txt") print(coinCountString) saveCoinCount(coinCountString) end end end end coin:addEventListener("collision")
What do you mean by saving the file’s read in memory, like in a runtime listener? because right now, this is not working what so ever. (I know I am doing something wrong)
local currentCoinCount if io.exists("coin.txt") then currentCoinCount = tonumber(io.readFile("coin.txt")) else currentCoinCount = 0 end local lastSave local function saveCoinCount( count ) count = tonumber(count) or 0 if( lastSave ) then timer.cancel(lastSave) end lastSave = timer.performWithDelay( 100, function() lastSave = nil io.writeFile(count, "coin.txt") end ) end function M.create(parent, parent2) --coin creation code function coin:collision(event) if event.phase == "began" then if event.other.name == "character" then display.remove(self) print("coin collected") coinCount = coinCount + 1 coinText.text = coinCount local coinCountInt = currentCoinCount + 1 local coinCountString = tostring(coinCountInt) saveCoinCount(coinCountString) end end end coin:addEventListener("collision") end
What happens is that the number from the previous save is written to the file. So, if the previous save is 14, and I delete the file, as soon as I collect a coin the next time, the save will say 15, and won’t change.
That looks like a lot of file operations during a short period (within a second) and I guess there might be some overlapping save attempts - while the file is locked by the previous operation or something like that.
If you have lots of coins close to each other, it’s probably a better idea to save the coins count periodically(at checkpoints) or at certain thresholds (like every 10/20/50 coins).
You want to avoid reading from and writing to persistent memory (the disk) that often.
Aside from possible corruption/data loss you will deplete the battery quickly and needlessly.
Here is an alternate solution to minimize actual i/o traffic.
-- Save mechanism with deferment that cancels last outstanding save local lastSave local function saveCoinCount( count ) count = tonumber(count) or 0 if( lastSave ) then timer.cancel(lastSave) end lastSave = timer.performWithDelay( 100, function() lastSave = nil io.writeFile(count,"coin.txt") end ) end
Next, don’t read the coin count AT ALL in the listener. You should only read that at the beginning of the game and then keep track of it in memory.
Finally, do this in your listener:
function coin:collision(event) if event.phase == "began" then if event.other.name == "character" then display.remove(self) print("coin collected") coinCount = coinCount + 1 coinText.text = coinCount io.writeFile(coinCountString, "coin.txt") print(coinCountString) saveCoinCount(coinCountString) end end end end coin:addEventListener("collision")
What do you mean by saving the file’s read in memory, like in a runtime listener? because right now, this is not working what so ever. (I know I am doing something wrong)
local currentCoinCount if io.exists("coin.txt") then currentCoinCount = tonumber(io.readFile("coin.txt")) else currentCoinCount = 0 end local lastSave local function saveCoinCount( count ) count = tonumber(count) or 0 if( lastSave ) then timer.cancel(lastSave) end lastSave = timer.performWithDelay( 100, function() lastSave = nil io.writeFile(count, "coin.txt") end ) end function M.create(parent, parent2) --coin creation code function coin:collision(event) if event.phase == "began" then if event.other.name == "character" then display.remove(self) print("coin collected") coinCount = coinCount + 1 coinText.text = coinCount local coinCountInt = currentCoinCount + 1 local coinCountString = tostring(coinCountInt) saveCoinCount(coinCountString) end end end coin:addEventListener("collision") end
What happens is that the number from the previous save is written to the file. So, if the previous save is 14, and I delete the file, as soon as I collect a coin the next time, the save will say 15, and won’t change.