Saving settings between sessions?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
mrklotz
Prole
Posts: 17
Joined: Mon Jan 25, 2010 1:53 pm

Saving settings between sessions?

Post by mrklotz »

Okay, I'm currently working on a simple gamemenu and was thinking how to store settings between sessions;
Let's take a look at setting resolutions, this is basically what I'd do but if you quit the game the resolution would be back to what is set in the conf.lua or if the entry is missing to the default value.

Code: Select all

function love.draw()
   if state == 'aspr43' then                --aspect ratio 4:3
          setres(800,600)
	elseif state == 'aspr169' then           --aspect ratio 16:9
          setres(960,540)
	elseif state == 'aspr1610' then          --aspect ratio 16:10
          setres(1024,640)
   end

end
Don't mind the syntax, let's call this a "conceptual"- function ;)

Code: Select all

function setres(x1,y1)
    set t.screen.width = x1
    set t.screen.height = y1
end
So either I have to store the state somehow or overwrite 't.screen.width' & 't.screen.height' inside the conf.lua, any insights?
I know you can add text to a file, but lets assume we do that, then the text would be at the end of conf.lua outside of the 'function love.conf(t)' and thus not applied.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Saving settings between sessions?

Post by bartbes »

You could read conf.lua, change it and write it back, or a more sane solution would be setting t.screen to false in love.conf and running setMode manually.
You'd store the arguments in a file, something like settings.txt or settings.lua (anything else will do as well), then you are left with 2 choices, either write it in some form you can easily parse, or generate lua code that you can require.
User avatar
mrklotz
Prole
Posts: 17
Joined: Mon Jan 25, 2010 1:53 pm

Re: Saving settings between sessions?

Post by mrklotz »

bartbes wrote:You could read conf.lua, change it and write it back, or a more sane solution would be setting t.screen to false in love.conf and running setMode manually.
You'd store the arguments in a file, something like settings.txt or settings.lua (anything else will do as well), then you are left with 2 choices, either write it in some form you can easily parse, or generate lua code that you can require.
Creating an additional config file via the filesystem sure is interesting but I doubt I'm ready to mess arround with that, also I'd prefer to not clutter the setting over multiple files, I guess that means I'll take a look at r/w conf.lua way. :/
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Saving settings between sessions?

Post by bartbes »

Why not?

Code: Select all

f = love.filesystem.newFIle("settings.txt")
f:open("w")
f:write(state)
f:close()
and

Code: Select all

f = love.filesystem.newFile("settings.txt")
f:open("r")
state = f:read()
f:close()
Easy enough, and if you need more settings there are several ways to do it, easiest is probably using multiple lines, 1 line per setting. (btw, not sure about the read() call)
And, if you modify conf.lua it isn't in the .love, it'd be in the save folder as well.
User avatar
mrklotz
Prole
Posts: 17
Joined: Mon Jan 25, 2010 1:53 pm

Re: Saving settings between sessions?

Post by mrklotz »

bartbes wrote: And, if you modify conf.lua it isn't in the .love, it'd be in the save folder as well.
I didn't even think about that, well I'll give it a shot later.

But for now I habe a new question to pester you with :P
I'm currently using button.lua from the NO demo to create buttons.

Code: Select all

-----------------------
-- NO: A game of numbers
-- Created: 23.08.08 by Michael Enger
-- Version: 0.2
-- Website: http://www.facemeandscream.com
-- Licence: ZLIB
-----------------------
-- Handles buttons and such.
-----------------------

Button = {}
Button.__index = Button

function Button.create(text,x,y)
	
	local temp = {}
	setmetatable(temp, Button)
	temp.hover = false -- whether the mouse is hovering over the button
	temp.click = false -- whether the mouse has been clicked on the button
	temp.text = text -- the text in the button
	temp.width = font["large"]:getWidth(text)
	temp.height = font["large"]:getHeight()
	temp.x = x - (temp.width / 2)
	temp.y = y
	return temp
	
end

function Button:draw()
	
	love.graphics.setFont(font["large"])
	if self.hover then love.graphics.setColor(unpack(color["main"]))
	else love.graphics.setColor(unpack(color["text"])) end
	love.graphics.print(self.text, self.x, self.y)
	
end

function Button:update(dt)
	
	self.hover = false
	
	local x = love.mouse.getX()
	local y = love.mouse.getY()
	
	if x > self.x
		and x < self.x + self.width
		and y > self.y - self.height
		and y < self.y then
		self.hover = true
	end
	
end

function Button:mousepressed(x, y, button)
	
	if self.hover then
		if audio then
			love.audio.play(sound["click"])
		end
		return true
	end
	
	return false
	
end
So I can create buttons fine with that, but I'd like to be able to create "small" buttons too, something like this:

Code: Select all

Button = {}
Button.__index = Button

function Button.create(text,x,y,font) -- example Button.create("This is a test", 100, 100, font["small"])
	
	local temp = {}
	setmetatable(temp, Button)
	temp.hover = false -- whether the mouse is hovering over the button
	temp.click = false -- whether the mouse has been clicked on the button
	temp.text = text -- the text in the button
	temp.width = font:getWidth(text)
	temp.height = font:getHeight()
	temp.x = x - (temp.width / 2)
	temp.y = y
	return temp
	
end

function Button:draw()
	
	love.graphics.setFont(font["large"])
	if self.hover then love.graphics.setColor(unpack(color["main"]))
	else love.graphics.setColor(unpack(color["text"])) end
	love.graphics.print(self.text, self.x, self.y)
	
end
Is a function possible like this? (I'm pretty sure what I did above doesn't work)
Also if it is, how do I hand the font to be used over to the Button:draw() function?
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Saving settings between sessions?

Post by bartbes »

This should work:

Code: Select all

    Button = {}
    Button.__index = Button

    function Button.create(text,x,y,font) -- example Button.create("This is a test", 100, 100, font["small"])
       
       local temp = {}
       setmetatable(temp, Button)
       temp.hover = false -- whether the mouse is hovering over the button
       temp.click = false -- whether the mouse has been clicked on the button
       temp.text = text -- the text in the button
       temp.width = font:getWidth(text)
       temp.height = font:getHeight()
       temp.x = x - (temp.width / 2)
       temp.y = y
       temp.font = font
       return temp
       
    end

    function Button:draw()
       
       love.graphics.setFont(self.font)
       if self.hover then love.graphics.setColor(unpack(color["main"]))
       else love.graphics.setColor(unpack(color["text"])) end
       love.graphics.print(self.text, self.x, self.y)
       
    end

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Saving settings between sessions?

Post by Robin »

Something you might not know (judging your code):

Code: Select all

t["key"] == t.key
And it works the other way around as well:

Code: Select all

love["graphics"]["draw"]
Help us help you: attach a .love.
User avatar
mrklotz
Prole
Posts: 17
Joined: Mon Jan 25, 2010 1:53 pm

Re: Saving settings between sessions?

Post by mrklotz »

bartbes wrote:This should work:
Indeed it does, thank you very much and I wasn't even that far off.
Robin wrote:Something you might not know (judging your code):

Code: Select all

t["key"] == t.key
And it works the other way around as well:

Code: Select all

love["graphics"]["draw"]
Yes you are right, I didn't know that, should save same time on tablecalls ;)

So for

Code: Select all

love.graphics.setColor(unpack(color["main"]))
love.graphics.setColor(unpack(color.main))  -- why do I need the unpack anyway?
Well back to work on the load/save- system, I'll post the whole thing when it's done, it's probably not well coded at all but you could just alter the used resources, modify the draw sections of the diffrent menu pages pop the states for the "new game" and "load" in and would have a working titlemenu for someones game. ;)
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Saving settings between sessions?

Post by Robin »

mrklotz wrote:

Code: Select all

    love.graphics.setColor(unpack(color.main))  -- why do I need the unpack anyway?
That's because love.graphics.setColor doesn't take a table as argument: it takes three or four numbers:

Code: Select all

love.graphics.setColor(255, 0, 0) -- red
unpack() unpacks a table into an argument list:

Code: Select all

love.graphics.setColor(unpack({255, 0, 0})) -- red
The table constructor {} can do the reverse (although it is much more powerful):

Code: Select all

{unpack({255, 0, 0})} -- gives {255, 0, 0}
--or perhaps more relevant:
{love.graphics.getColor()}
Help us help you: attach a .love.
User avatar
mrklotz
Prole
Posts: 17
Joined: Mon Jan 25, 2010 1:53 pm

Re: Saving settings between sessions?

Post by mrklotz »

Robin wrote:That's because love.graphics.setColor doesn't take a table as argument: it takes three or four numbers:

Code: Select all

love.graphics.setColor(255, 0, 0) -- red
unpack() unpacks a table into an argument list:

Code: Select all

love.graphics.setColor(unpack({255, 0, 0})) -- red
The table constructor {} can do the reverse (although it is much more powerful):

Code: Select all

{unpack({255, 0, 0})} -- gives {255, 0, 0}
--or perhaps more relevant:
{love.graphics.getColor()}
Thanks for the explanation Robin, and back to the original question at hand.
I already asked a bit about it in the IRC where some kind people tried to explain it to me but still I failed to graps it in its entirety.

What bartbes posted helped quite a bit, but just as he wrote I'd like to store more things in the file, and I have no idea how I can read/write to specific lines in a file.
Just as bartbes posted this is what I'd use for writing a single entry to a file

Code: Select all

if love.filesystem.exists("data.txt") = true then
	f = love.filesystem.newfile("data.txt")
        f:open("w")
        f:write(resolutionstate)
        f:close
Also I'm a bit stumped on how to create the file if it does not exist; according to the docs: love.filesystem.newfile - "Creates a new File object. An error will occur if the specified file does not exist. "
So how do I create the file then in the first place? f = love.filesystem.newfile("data.txt") should return an error if the file isn't existant, meaning I can't define the file thus preventing me from opening it/creating it. (some peeps on IRC meant when you open a non existant file it would be created, but I'd have no fileobject to open in this case?)

Any help would be appreciated, on that Note since I started here I got awesome help, thank you very much for that.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest