I'm in the middle of making my first Lua game and I needed a way to save the user's preferences for the game window. If they set my game to fullscreen mode, I think it had better reopen in fullscreen mode. It works by directly editing the conf.lua file instead of using an outside file to save values. It's my first published bit of Lua code, so I'd love any suggestions or recommendations.
https://github.com/acb5649/ConfigManager
ConfigManager - Handy Library for Options Menus
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: ConfigManager - Handy Library for Options Menus
First thing, while using lua io functions isn't a sin, this won't work in many cases, like when you zipped up your project into a .love file.acb5649 wrote:I'm in the middle of making my first Lua game and I needed a way to save the user's preferences for the game window. If they set my game to fullscreen mode, I think it had better reopen in fullscreen mode. It works by directly editing the conf.lua file instead of using an outside file to save values. It's my first published bit of Lua code, so I'd love any suggestions or recommendations.
https://github.com/acb5649/ConfigManager
I'd use love's own filesystem stuff instead. (Though i must admit, i thought io.open needed a full absolute path... if it works for you with only "conf.lua", then that's a surprise for me)
Second issue would be that love.filesystem doesn't allow you to write to the application directory, so even if you tried to write something to conf.lua, it will write that file into your save directory, if you have set an identity for the project, that is.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: ConfigManager - Handy Library for Options Menus
Thank you, I feel a little silly for forgetting Love projects are zipped for distribution.
I guess I'll leave it up while I work on a replacement, since I can't use this code for release either.
EDIT:
New working version is now online, but it does use extra files stored in the LOVE save directory.
It now uses 100% love.filesystem calls instead of io, and does not impact startup speed. See the included conf.lua file for usage example. Basically, if you want to let the user control a configuration, like MSAA, use:
The config file will check the save directory for a file with the MSAA information inside. If such file is not found, is defaults to 0 because of the "or" condition.
Again, any and all feedback is appreciated. Look how well it went last time!
I guess I'll leave it up while I work on a replacement, since I can't use this code for release either.
EDIT:
New working version is now online, but it does use extra files stored in the LOVE save directory.
It now uses 100% love.filesystem calls instead of io, and does not impact startup speed. See the included conf.lua file for usage example. Basically, if you want to let the user control a configuration, like MSAA, use:
Code: Select all
t.window.msaa = loadMSAA() or 0
The config file will check the save directory for a file with the MSAA information inside. If such file is not found, is defaults to 0 because of the "or" condition.
Again, any and all feedback is appreciated. Look how well it went last time!
Re: ConfigManager - Handy Library for Options Menus
Yes, you should always save progress and settings in the appdata/user directory,
writing files to the installation directory is not good practice and might not work depending on the user's permissions.
Having said that, the code needs work.
Saving a separate ".dat" file for each setting is not ideal,
the easiest option is to save everything in a single Lua table or use bartbes "inifile".
Also, note that:
Is the same as:
PS. Subfolders for each "version" of the configmanager is a good idea too, since APIs change over time.
Either that or try to include the savefile version somewhere in there.
writing files to the installation directory is not good practice and might not work depending on the user's permissions.
Having said that, the code needs work.
Saving a separate ".dat" file for each setting is not ideal,
the easiest option is to save everything in a single Lua table or use bartbes "inifile".
Also, note that:
Code: Select all
function loadWindowPosWidth()
local file = "windowwidth.dat"
if love.filesystem.exists(file) then
local size = love.filesystem.getSize(file)
local data = love.filesystem.read(file, size)
return tonumber(data)
else
return nil
end
end
Code: Select all
function loadWindowPosWidth()
local file = "windowwidth.dat"
if love.filesystem.exists(file) then
local size = love.filesystem.getSize(file)
local data = love.filesystem.read(file, size)
return tonumber(data)
end
end
Either that or try to include the savefile version somewhere in there.
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: ConfigManager - Handy Library for Options Menus
And this:
As this, since read tries to read it all if no size is specifiedivan wrote:Code: Select all
function loadWindowPosWidth() local file = "windowwidth.dat" if love.filesystem.exists(file) then local size = love.filesystem.getSize(file) local data = love.filesystem.read(file, size) return tonumber(data) end end
Code: Select all
function loadWindowPosWidth()
local file = "windowwidth.dat"
if love.filesystem.exists(file) then
local data = love.filesystem.read(file)
return tonumber(data)
end
end
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Re: ConfigManager - Handy Library for Options Menus
I think the entire API could be rewritten in 2 functions:
Basically you need a table of default values and you overwrite that:
PS. Haven't tested the code, but I hope the technique is clear.
I used this approach in my games and it works quite well, except that you have to do some extra validation,
in particular with paired values like width/height...
Code: Select all
-- very bad example writing each key to a separate file
function api.loadString(key)
local file = key..".dat"
if love.filesystem.exists(file) then
return love.filesystem.read(file)
end
end
-- load custom values if their type matches the default
function api.load(defaults, destination)
-- overwrites the defaults if no destination table is specified
destination = destination or defaults
-- iterate default values
for k, v in pairs(defaults)
local expected = type(v)
-- convert based on expected type
local custom = api.loadString(k)
if expected == "boolean" then
if custom == "true" then
custom = true
elseif custom == "false" then
custom = false
end
elseif expected == "number" then
custom = tonumber(custom)
end
-- check loaded type vs default type
if type(custom) == expected then
destination[k] = custom
end
end
return destination
end
Code: Select all
local defaults =
{
Width=800,
Height=600,
Borderless=true,
Resizable=0,
MinWidth=0,
MinHeight=0,
Fullscreen=true,
FullscreenType="string",
Vsync=true,
MSAA=0,
Display=0,
HighDPI=true,
WindowPosWidth=0
}
api.load(defaults)
I used this approach in my games and it works quite well, except that you have to do some extra validation,
in particular with paired values like width/height...
Who is online
Users browsing this forum: No registered users and 0 guests