storage.set() not working
I have been trying to add saving to a game I am making. When doing so, I run into a problem
saveGame = function()
save = object
playerSave = player1
enemySave = enemyList
levelSave = level
lightSave = lights
levelNameSave = levelName
end
storage.set("save", save)
end
I called the saveGame()
function in the console. I refreshed the game and called storage.get("save")
. The console returned an object with only two variables. This was the output:
> storage.get("save")
object
playerSave = [object]
levelNameSave = "level1"
end
I called the saveGame()
function again, but it was the same, even without refreshing the game. I tested the actual save object in the console and got:
> save
object
playerSave = [object]
enemySave = [list]
levelSave = [object]
lightSave = [list]
levelNameSave = "level1"
end
So my problem is that some of the data in the save object was lost in the console. Please help me, I'm not sure what is happening.
If I follow your steps, I only can see undefined, undefined, undefined...
After seeing your post, I checked the API, I actually found a bug and fixed it. The bug may explain why some of the values you are trying to save aren't actually saving.
The bug was related to the serialization mechanism used for storing objects. When you store a whole object, try to have in mind that your object will be transformed into text (JSON format), with a few side effects:
- circular structures cannot be saved as such ; if you have a
player
object which retains a reference to an enemy
object, and the enemy
itself holds a reference to player
, that's a circular reference. The storage API will remove such references in the saved objects.
- if you have two references to the same object or array before saving them to the storage, once saved and reloaded, they will be recreated as 2 independant copies of the same object.
Example:
enemy = object
x = 50
y = 0
end
save = object
enemy1 = enemy
enemy2 = enemy
end
if save.enemy1 == save.enemy2 then print("YES") end // => YES, they are equal
storage.set("status",save)
save = storage.get("status")
if save.enemy1 != save.enemy2 then print("NO!") end // => NO, they aren't equal anymore, not the same object, two different copies of the same data
Generally speaking, you should avoid storing your whole structured game data using the storage API as it will certainly lead to many unexpected side effects, due to how serialization works. Instead, you should build a dedicated object which does not hold references to your actual game objects, only to simple numbers or string values. For example:
save = function()
local obj = object
position = object
x = player.x
y = player.y
end
level_num = getLevelNum()
end
storage.set("save",obj)
end
load = function()
local obj = storage.get("save")
player.x = obj.position.x
player.y = obj.position.y
setLevel(obj.level_num)
end