Page 1 of 2
Need help making a save file
Posted: Sat Feb 22, 2014 9:23 am
by MikeCraftian
I looked it up and everything just crashes
All I want to do is save a variable
Var = {}
var.number = 0 -- What I want to save
Saving the complete var wouldnt be negative though I lurked here googeled etc everything always comes with (String expected got nil)
Help?
Re: Need help making a save file
Posted: Sat Feb 22, 2014 9:58 am
by Robin
We can't really help you here if you don't upload a .love, because you've not given us enough info to work with.
Re: Need help making a save file
Posted: Sat Feb 22, 2014 12:58 pm
by veethree
My
flappy bird clone keeps track of the players high score by saving and loading a variable from a file. You can look through the code, it might help.
Alternatively, You could use a serialisation library such as
Tserial.
Those basically turn tables into strings, and strings back into tables. So you could store your variable in a table, Serialise the table (tserial.pack()), Save the string to a file, Then to load it just turn it into a table again.(tserial.unpack())
Re: Need help making a save file
Posted: Sat Feb 22, 2014 2:08 pm
by Doctory
Re: Need help making a save file
Posted: Sat Feb 22, 2014 7:26 pm
by Robin
Instead of using Tserial, consider using
Ser. It's very fast, and very stable, and I wrote it to get people to stop using Tserial.
I don't know enough about SLib to either recommend it or recommend against using it.
EDIT: I have looked at SLib and
recommend against using it for the following reasons:
- It produces incorrect results.
- When encountering cycles in a datastructure, SLib enters an infinite loop.
- Related: if the serialised value contains multiple references to a single subtable, that subtable will be serialised separately for every reference. That is incorrect behaviour.
- "Special" numbers (infinity, negative infinity and NaN) are not handled by SLib, making anything that contains one of those values unloadable.
- The code that checks if string keys can use identifier syntax (key = ... instead of ["key"] = ...) is broken. It allows strings like "end", "1", "*#(@" and " " to be used as identifier keys, while they are quite clearly illegal.
- If the second argument to slib.pack, called "drop", is a table value (which is always the case if you're using slib.save), then type errors, like if you use a coroutine as a table key or value, will be ignored, causing slib.pack({coroutine.create(function()end)}, {}) to return "}", for example.
- It is slow.
- SLib uses string concatenation all over the place, which means a table containing N elements will take O(N^2) time, while using table.concat would only take O(N).
- SLib creates a closure for every (sub)table serialised.
- Using the benchmarking code from the serpent project, SLib is 2.37 times slower than Ser for serialising. I had to disable the de-serialising benchmarks, because SLib produced incorrect code that interrupted the benchmarking.
EDIT 2: Also, a list of some more minor things:
- The whole thing's just atrociously indented.
- It exports a global table.
- The third argument to slib.pack is called indend, but in other places is always referred to as indent, which means two things:
- SLib's output never has indentation and newlines, even if you ask for it.
- The author apparently hasn't tested this library at all.
Re: Need help making a save file
Posted: Sat Feb 22, 2014 8:00 pm
by veethree
Robin wrote:Instead of using Tserial, consider using
Ser. It's very fast, and very stable, and I wrote it to get people to stop using Tserial.
I don't know enough about SLib to either recommend it or recommend against using it.
What's wrong with Tserial?
Re: Need help making a save file
Posted: Sat Feb 22, 2014 8:17 pm
by Robin
veethree wrote:What's wrong with Tserial?
It's been a while since I've last reviewed it, but IIRC, it's roughly the same list of problems I have found in SLib (I've updated my post above).
Re: Need help making a save file
Posted: Sun Feb 23, 2014 12:55 am
by Hexenhammer
One of the things I love about Lua(JIT) is that I do not have to have the separation of core engine (e.g. C or C++), scripting (e.g. Lua or Python), and serialized data (e.g. XML, JSON, something custom) anymore. I used to develop in that traditional way, and it was so ugly. Translating between the different "worlds" adds so much unnecessary complexity and code. LuaJIT is fast enough that I can do everything in Lua... including save files.
You could serialize everything to Lua tables but I do not like that. Instead my save files are simply code which rebuilds the world state. My situation is more complex, I need to restore an entire game world, which means my saved game code is mostly calls to functions which do things like creating actors, setting their attributes etc. And of course I use locals. I also use delta encoding to keep the save files small without compression. However ignore all that stuff. If you just want to save some values in a simple way using that basic method, here is how you can do it:
Code: Select all
var = {}
var.number = 0 -- Initial value
var.number = 43 -- The value when the user pressed "save" (or whatever)
-- Saving said value to a file
file = io.open("savedGame.lua", "w")
file:write("var.number = ", var.number)
file:close()
-- Resetting to initial value, simulating the effect of a restart
var.number = 0
-- Loading the saved value from a file
dofile("savedGame.lua") -- Yes, that's it!
print(var.number) -- Will print 43!
Re: Need help making a save file
Posted: Sun Feb 23, 2014 7:04 am
by Doctory
Hexenhammer wrote:-snip-
-important stuff-
Code: Select all
var = {}
var.number = 0 -- Initial value
var.number = 43 -- The value when the user pressed "save" (or whatever)
-- Saving said value to a file
file = io.open("savedGame.lua", "w")
file:write("var.number = ", var.number)
file:close()
-- Resetting to initial value, simulating the effect of a restart
var.number = 0
-- Loading the saved value from a file
dofile("savedGame.lua") -- Yes, that's it!
print(var.number) -- Will print 43!
You sir, just solved my problems.
Re: Need help making a save file
Posted: Sun Feb 23, 2014 5:15 pm
by Ref
Yes!
Trying to generalize your approach finely forced me to figure out how to get the name of a table as a string - something I was always struggling with.
This is the code I ended up with:
Code: Select all
function saveTable( saveto, tab )
local tabname = tableName( tab )
local file = io.open( saveto, 'w' )
file:write( tabname..' = {}\n' )
for I, j in pairs( tab ) do
file:write( tabname..'.'..tostring(i)..' = ', j )
file:write( '\n' )
end
file:close()
end
function loadTable( from )
dofile( from )
end
function tableName( tab ) -- returns table name as a string
assert(type(tab)=='table', "table required")
local n, v
for n, v in pairs( getfenv() ) do
if v == tab then
return n
end
end
return nil
end
Thanks!