Page 1 of 3

Saving Data

Posted: Thu Jul 04, 2013 5:30 am
by Lemony Lime
I'm having a heck of a time figuring out how to create savegames. There's far too little info on the love filesystem module (or maybe I just haven't been able to find it.) and there's almost no info about binary files with lua. I know this is a very broad question, but how do I save?

The game I'm working on has a tile based map, which I would like to save in 16x16 chunks, and just keep 4 of these loaded at any given time, which will cut down on memory requirements. Of course, that means I need to have them all stored in a binary file or something similar to be able to retrieve/write them when necessary. (Also just general savegames are important, but that's not what I'm actually working on atm. lol)

Re: Saving Data

Posted: Thu Jul 04, 2013 5:51 am
by micha
The filesystem provides you functions to write strings into files. That's the way to go.

You can either come up with your own fileformat, for example just a list of numbers.
Or you can save the map as lua code. Then the loading is relatively simple: You can use love.filesystem.load(filename)() to run the saved code. So you don't need to write an input parser. On the other hand, some people pointed out that this can possibly harmfull, if you blindly run code from a file and if users are allowed to contribute content.

Re: Saving Data

Posted: Thu Jul 04, 2013 5:59 am
by Lemony Lime
Well, I've used C++ binary files in the past, and was just trying to do that, but it seems to refuse to write to binary files. I've actually got my map saving system up and running, but it will only write to text files (which I'd rather not have since players can edit them) even though I've told it to do binary files. I suppose this is okay though, since the entire map will just be saved as one continuous line of numbers, which certainly won't be easy for players to read/edit. lol

I have run into one problem though. It doesn't work in my game, but it does if I run it as a non love2d lua file by itself. Here's the working non-love2d script:

Code: Select all

function Fill2DArray( arr, fill, sizeX, sizeY )
	for x = 1, sizeX do
		arr[x] = {}
		for y = 1, sizeY do
			arr[x][y] = fill
		end
	end
	
	return arr
end

function writeChunk( chunk )
	for y = 1, #chunk do
		for x = 1, #chunk[y] do
			output:write( chunk[x][y] )
		end
	end
end

function writeMap( map )
	for y = 1, #map do
		for x = 1, #map[y] do
			writeChunk( map[x][y] )
		end
	end
end

map = {}
chunk = {}

Fill2DArray( chunk, '5', 8, 8 ) --fill the entire map with 5s for testing
Fill2DArray( map, chunk, 8, 8 )

output = assert( io.open( "save.bin", "wb" ) )
writeMap( map, 8 )
assert( output:close() )
(Btw, are you the person that just edited the title of my post on stackoverflow? You have the same name, if not. lol)

Re: Saving Data

Posted: Thu Jul 04, 2013 6:25 am
by Lemony Lime
Yeah, I've done some more testing, and tried a few extra things and nothing is happening at all. I'm guessing you must be required to use love.filesystem... so I'll give that a shot instead.

Do you know of any more extensive tutorials on love.fileystem other than this? http://love2d.org/wiki/love.filesystem

Re: Saving Data

Posted: Thu Jul 04, 2013 1:51 pm
by T-Bone
You do know that the files you write don't end up in the same directory as the game files, don't you?

I've never had any issues with love.filesystem so you're doing something wrong somewhere. Mind posting your code?

Re: Saving Data

Posted: Thu Jul 04, 2013 3:58 pm
by Eamonn
Ok, maybe this isn't them most efficient way to do it, but here is how I do my writing in Mr. BallGuy(feel free to look into there) to save stuff like highscores or deathcount's or whatever.

Code: Select all

deathcount = {}

if love.filesystem.exists('deathcount.lua') then -- Checks if the deathcount.lua file exists
    love.filesystem.read('deathcount.lua') -- Read's the deathcount.lua file
 elseif not love.filesystem.exists('deathcount.lua') then -- Checks if the deathcount.lua file does not exist
    file5 = love.filesystem.newFile('deathcount.lua') -- Make's the deathcount.lua file
    love.filesystem.write('deathcount.lua', 'player.deathcount\n=\n' .. player.deathcount) -- Writes the deathcount to the deathcount.lua file
 end
  
 for lines in love.filesystem.lines('deathcount.lua') do -- Iterates through the deathcount.lua file
    table.insert(deathcount, lines) -- Inserts all the lines from deathcount.lua file into the deathcount table
  end
  
 player.deathcount = deathcount[3] -- Sets the value of player.deathcount equal to the 3rd element in the deathcount table
What we do in English:

We check if the file we want exists already, which in my case it is deathcount.lua. If it does, read the contents of the file. If not, make the file and write to it. We write on different lines in the file, and this is for how my game works. You could probably do this differently, but it was 5 days of trail on error. So once we've done file checking, we go on to the for loop. The for loop checks through all the lines in the deathcount.lua file(this is in the appdata/Application Support directory) and inserts them into a table called 'deathcount', which we created at the top of the code. So we set player.deathcount equal to the 3rd element in the deathcount table. This works, but I have no idea how. Maybe the index or something is screwed up...?

Anyway, hope I helped!

Re: Saving Data

Posted: Thu Jul 04, 2013 5:03 pm
by micha
Your code is a bit redundant. You can replace the top part by this:

Code: Select all

 if not love.filesystem.exists('deathcount.lua') then -- Checks if the deathcount.lua file does not exist
    file5 = love.filesystem.newFile('deathcount.lua') -- Make's the deathcount.lua file
    love.filesystem.write('deathcount.lua', 'player.deathcount\n=\n' .. player.deathcount) -- Writes the deathcount to the deathcount.lua file
 end
Because the filesystem.read is useless, if you don't catch the value it returns. Also a construction of the form "if X then ... elseif not X then ... end" is a bit redundant, because if X is not true then X is not true.

Re: Saving Data

Posted: Thu Jul 04, 2013 6:31 pm
by Lemony Lime
T-Bone wrote:You do know that the files you write don't end up in the same directory as the game files, don't you?
Then where is it writing it? If you look at the code that I posted, I'm not actually using love.filesystem yet, just the standard Lua file I/O.

Re: Saving Data

Posted: Thu Jul 04, 2013 8:08 pm
by Plu
Wherever the game's savedirectory is. Usually something like /users/%yourname%/AppData/Love/%nameofgame%.

Re: Saving Data

Posted: Thu Jul 04, 2013 8:12 pm
by Lemony Lime
I see mari0 there and that's it.