Share your favourite helper functions

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
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Share your favourite helper functions

Post by kikito »

Ref wrote:
Robin wrote:FYI,B, D, D, h, S, j and R are all globals here.
Thanks Robin for pointing out my error.
Question:
Are a,b,c local if you use local a,b,c = {},{},{} or do you have to specify each one local separately?

Code: Select all

local a,b,c = 1,2,3 -- a,b,c are local
local a = 1 b = 2 c = 3 -- a is local, b and c are global
This is because the second line is equivalent to this:

Code: Select all

local a = 1
b = 2
c = 3
So, be careful :)
When I write def I mean function.
User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Share your favourite helper functions

Post by AntonioModer »

LOVE 0.8.0 has a hidden function love._openConsole() (open console).
User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Share your favourite helper functions

Post by AntonioModer »

Wrap LOVE functions for your code.

Code: Select all

do -- wrapCall
	
local function wrapCallGraphics(name1, name2)
  local func = love[name1][name2]
  love[name1][name2] = function (...)
    -- your code !!!
    return func(...)
  end
end

-- examples
wrapCallGraphics("graphics", "draw");
wrapCallGraphics("graphics", "drawq");
wrapCallGraphics("graphics", "print1");
wrapCallGraphics("graphics", "printf1");
wrapCallGraphics("graphics", "rectangle");
wrapCallGraphics("graphics", "arc");
wrapCallGraphics("graphics", "circle");
wrapCallGraphics("graphics", "point");
wrapCallGraphics("graphics", "polygon");
wrapCallGraphics("graphics", "triangle");
wrapCallGraphics("graphics", "line");
wrapCallGraphics("graphics", "quad");

end
Thanks "Bart van Strien" and "vrld". (https://bitbucket.org/rude/love/issue/5 ... count-in-c)
User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Share your favourite helper functions

Post by AntonioModer »

Path to game folder.

Code: Select all

function love.load()
  -- (arg[1] = path to main.lua) 
  -- game.love - the game name 
  path = string.gsub(arg[1], "game.love", "")           -- (game run in *.love file)
  path = arg[1]            		                 -- (game run not in *.love file)
end
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Share your favourite helper functions

Post by Inny »

So, this isn't so much a helper function, but rather a -style- for organizing code modules that may be helpful to people. When you want to do a kind of "hard reset" for a game, a neat way of doing it is to call love.load again. When you load everything from there, it kind of makes it easy, following a basic assumption that you put all of the loading code there. So, here's a way to organize modules in code for that purpose:

Code: Select all

-- In this style, assume that we're loading modules that return a table of functions,
-- and we will put them in the global state rather than locally to every where they're needed.
-- Because of dependencies, ordering is important and we can't use a regular table.
-- Each subtable is { global name, module filename }
game_libraries = {
  { "Graphics", "lib.graphics" },
  { "Audio", "lib.audio" },
  { "Sprite", "lib.sprite" },
  { "Game", "lib.game" },
}

function load_libraries()
  for _, v in ipairs(game_libraries) do
    local global = v[1]
    package.loaded[global] = nil
    _G[global] = nil
  end
  garbagecollect("collect") -- give all finalizers a chance to run
  for _, v in ipairs(game_libraries) do
    local global, filename = v[1], v[2]
    _G[global] = require(filename)
  end
end

function love.load()
  load_libraries()
  Graphics.init()
  Audio.init()
  Game.init()
end
If you keep everything clean and don't litter your global table, this works out pretty nicely.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Share your favourite helper functions

Post by Robin »

AntonioModer wrote:Path to game folder.

Code: Select all

path = string.gsub(arg[1], "game.love", "")           -- (game run in *.love file)
Yeah, not a very good idea:

Code: Select all

print(arg[1]) -- "/tmp/game.love/game.love"
print(path) -- "/tmp//"
print(arg[1]) -- "/tmp/somegame.love/game.love"
print(path) -- "/tmp/some/"
print(arg[1]) -- "/tmp/gameXlove/game.love"
print(path) -- "/tmp//"
print(arg[1]) -- "/tmp/other.love" --hey, our user can rename a .love!
print(path) -- "/tmp/other.love"
print(arg[1]) -- "/tmp/game.lovegame.love"
print(path) -- "/tmp/"
A better idea might be:

Code: Select all

path = arg[1]:match('.+[/\\]')
Note that this version goes wacky if you have a backslash in the name of your .love (but only then).
Help us help you: attach a .love.
User avatar
markgo
Party member
Posts: 190
Joined: Sat Jan 05, 2013 12:21 am
Location: USA

Re: Share your favourite helper functions

Post by markgo »

A function to force fixed timestep

Code: Select all

return function(timestep,maxBuffer)
	local stepBuffer = 0
	timestep  = timestep or 1/60 -- 60 updates per second
	maxBuffer = maxBuffer or 1/10
	assert(maxBuffer >= timestep, 'Max time step must be greater than or equal to desired time step')
	return function(dt,func)
		stepBuffer = stepBuffer + dt
		stepBuffer = stepBuffer > maxBuffer and maxBuffer or stepBuffer
		
		while stepBuffer >= timestep do
			stepBuffer = stepBuffer-timestep
			func(timestep)
		end
	end
end
Require all modules in a directory to a table

Code: Select all

-- LOVE only
local lfs = love.filesystem

local requireAll = function(dir,moduleTable)
	moduleTable     = moduleTable or {}
	local filelist  = lfs.enumerate(dir)
	for i = 1,#filelist do
		local filepath = dir .. '/' .. filelist[i]
		if lfs.isFile(filepath) then
			local moduleName = filepath:match'(%a+)%.lua$'
			if moduleName then
				moduleTable[moduleName] = require(dir .. '/' .. moduleName)
			end
		elseif lfs.isDirectory(filepath) then
			local folder        = filelist[i]
			moduleTable[folder] = {}
			requireAll(filepath,moduleTable)
		end
	end
	return moduleTable
end

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

Re: Share your favourite helper functions

Post by Robin »

Minor nitpick:

Code: Select all

require(dir .. '/' .. moduleName)
should (pedantically) be

Code: Select all

require(dir .. '.' .. moduleName)
Help us help you: attach a .love.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Share your favourite helper functions

Post by kikito »

On the subject of requiring stuff easily, I merged a couple functions I had scattered around while I was doing the last Ludum Dare. And then I forgot about those.

https://github.com/kikito/fay/blob/mast ... equire.lua

Usage:

Code: Select all

require 'require'

local foo = require 'foo' -- require works as before

local bar = require.tree('bar') -- if bar is a folder, require everything inside bar, recursively (bar/one.lua becomes bar.one, and so on)
local baz = require.relative(..., 'baz') -- baz.lua is 'in the same folder' as the current file. The ... param is mandatory.
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 10 guests