Mini Functions Repository

General discussion about LÖVE, Lua, game development, puns, and unicorns.
pedrosgali
Party member
Posts: 107
Joined: Wed Oct 15, 2014 5:00 pm
Location: Yorkshire, England

Re: Mini Functions Repository

Post by pedrosgali »

Hey ZBoyer, those functions reminded me of my first data serializer:-

Code: Select all

-- Returns a single string gathered recursively from the table 't' The spacing value is for indentation as I am a stickler for human readable serialization just leave it as nil when you call the function and it'll indent at every new table it finds.

function serialize(t, spacing)
  if spacing == nil then spacing = "" end
  local str = "{ \n"
  spacing = spacing.."  "
  for k, v in pairs(t) do
    local key = k.." = "
    if tonumber(k) then
      key = ""
    end
    if type(v) == "string" then
      str = str..spacing..key.."'"..v.."',\n"
    elseif type(v) == "number" then
      str = str..spacing..key..tostring(v)..",\n"
    elseif type(v) == "table" then
      str = str..spacing..key..serialize(v, spacing)..",\n"
    end
  end
  str = str..spacing.."}"
  return str
end

--To save the data to a file then I tend to just add "return" to the start of the string so it can be loaded as a pure lua file.
function save(data, folder, label)
  love.filesystem.createDirectory(folder)
  local save = love.filesystem.newFile(folder.."/"..label..".lua", "w")
  save:write("return "..serialize(data))
  save:close()
end

This works recursively on any table and will ignore function values, not great for saving objects but I use ECS so objects shouldn't have functions associated with them. Works great for save games though it can make some pretty large files.
(Does anyone else keep opening the 'save as' window when adding code on here? It seems I now instinctively hit Ctrl + s every time I finish typing a line! :crazy: )

Code: Select all

if not wearTheseGlasses() then
  chewing_on_trashcan = true
end
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Scissor the scissor!

Post by Positive07 »

pgimeno wrote: I created it for Gspöt, which aims to remain compatible with 0.9, so unfortunately I can't take advantage of it for that project.

Code: Select all

local intersectScissor = love.graphics.intersectScissor or function (nx, ny, nw, nh)
    local ox, oy, ow, oh = love.graphics.getScissor()
    if ox then
        -- Intersect both rects
        nw = nx + nw
        nh = ny + nh
        nx, ny = math.max(nx, ox), math.max(ny, oy)
        nw = math.max(0, math.min(nw, ox + ow) - nx)
        nh = math.max(0, math.min(nh, oy + oh) - ny)
    end
    -- Set new scissor
    love.graphics.setScissor(nx, ny, nw, nh)
    -- Return old scissor
    -- return ox, oy, ow, oh --Intersect scissor doesn't return this values
end
This may be faster, performs less C calls, works on both 0.8.0 and up and has support for the newest native functionality defaulting to slower Lua code when not available
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
alloyed
Citizen
Posts: 80
Joined: Thu May 28, 2015 8:45 pm
Contact:

Re: Mini Functions Repository

Post by alloyed »

here's a debugging/repl thing I've been using. it takes all the modules you've already required and sticks them in the global table so you can just refer to them directly inside your repl environment. It won't load a module if you shadow its name with a local or have a global with the same name but different contents, so don't do that :p

Code: Select all

function the_button(print_loaded)
	local function import_module(name, module)
		local names = {}
		for n in name:gmatch("[^.]+") do table.insert(names, n) end

		local t = _G
		local partial, sep = "", ""
		for i=1, #names-1 do
			local n = names[i]

			if t[n] == nil then
				t[n] = {}
			elseif type(t) ~= 'table' then
				return false
			end

			t = t[n]
			partial = partial .. sep .. n
			sep = "."
		end

		local n = names[#names]
		if t[n] == nil or t[n] == module then
			t[n] = module -- success!
			return true
		end

		return false
	end

	local loaded = {}
	for name, module in pairs(package.loaded) do
		if import_module(name, module) then
			table.insert(loaded, name)
		end
	end

	if print_loaded then
		table.sort(loaded)
		for _, n in ipairs(loaded) do
			io.stderr:write(string.format("%s\n", n))
		end
	end
	io.stderr:write("ok\n")

	return loaded
end
Trebgarta
Prole
Posts: 33
Joined: Mon May 23, 2016 5:21 pm

Re: Mini Functions Repository

Post by Trebgarta »

Here is a function/module that returns a cube. So that noone else has to write this monstrosity.

Code: Select all

local function cube(s,uv,col)
  local s = s or 1
  local uv = uv or {0,0, 1,0, 0,1, 1,1}
  local col = col or {255,255,255,255}

  return {
    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s, -0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s, -0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},

    {-0.5 * s, -0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s,  0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s,  0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},

    {-0.5 * s,  0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s, -0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s,  0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},

     {0.5 * s,  0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s, -0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s, -0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s,  0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},

    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s, -0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s, -0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s, -0.5 * s, -0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},

    {-0.5 * s,  0.5 * s, -0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s, -0.5 * s,  uv[7], uv[8], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
     {0.5 * s,  0.5 * s,  0.5 * s,  uv[5], uv[6], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s,  0.5 * s,  uv[1], uv[2], col[1], col[2], col[3], col[4]},
    {-0.5 * s,  0.5 * s, -0.5 * s,  uv[3], uv[4], col[1], col[2], col[3], col[4]},
}

end


return cube
ZBoyer1000
Prole
Posts: 39
Joined: Sat Nov 28, 2015 10:13 am

Re: Mini Functions Repository

Post by ZBoyer1000 »

Here is a more useful delete function for tables.

Code: Select all

function delete(a,b,c) 
local d={{false,nil},{}}  
for e,f in next,a do 
 if f~=c and b=="val" or e~=c and b=="key" then 
  d[2][e]=a[e]
 else
  d[1][1]=true
  d[1][2]=a[e]
 end 
end 
return d[2],d[1][1],d[1][2]
--"a" is your table
--"b" can be either "val" or "key"
--"c" is the value or key you wish to delete in a table
--(table without found key or val), (is found), (found key or val)
end 
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Mini Functions Repository

Post by Inny »

Something I like to do is muck with the global environment a little bit before loading everything. For instance, this is a handy thing to do with table.unpack and table.pack

Code: Select all

  -- Make unpack and table.unpack be the same function, regardless of version
  if table.unpack then
    unpack = table.unpack
  else
    table.unpack = unpack
  end

  -- table.pack taken from penlight
  if not table.pack then
    function table.pack (...)
      return { n = select('#',...); ... }
    end
  end
Another thing I find very useful is mucking with the print function to make it more debug friendly, like showing me the name and line number in the module where I printed something. This makes use of the debug global table, and looks for a __TESTING global var before moving forward, otherwise it silences all output.

Code: Select all

  if __TESTING then
    local old_print = print
    print = function(...)
      local info = debug.getinfo(2, "Sl")
      local source = info.source
      if source:sub(-4) == ".lua" then source = source:sub(1, -5) end
      if source:sub(1,1) == "@" then source = source:sub(2) end
      local msg = ("%s:%i"):format(source, info.currentline)
      old_print(msg, ...)
    end
  else
    print = function() end
  end
The output ends up looking like this:

Code: Select all

funky/funky_tests:287   Funky unit tests.
tests/util_tests:25     utils unit tests.
graphics:21     ImageQuads      table: 0x3e9b60b8       tileset8x8.png  0       8       8
graphics:21     ImageQuads      table: 0x3e9f1408       CGA8x8thin_trans.png    0       8       8
graphics:86     !**     false
input:18        loadGamepadMappings     gamecontrollerdb.txt
input:24        JOYSTICK        1       Logitech Dual Action    true
As you can see here, I have a not very useful piece of spam in graphics.lua line 86 I can go remove.

As an aside, I know "__x" style variables are supposed to be reserved for Lua internal usage, in which case it probably should change this to "TESTING__" (underscores at the end).
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Mini Functions Repository

Post by HugoBDesigner »

I wrote a simple array organizer for numerical entries. I know these things come with Lua already, but after I wrote one for strings (long ago, dunno where to find it), I figured I'd give numbers a try:

Code: Select all

function order(t) --input table
	local ret = {} --returning table
	local first = true
	for i, v in pairs(t) do --main loop
		if first then --first item
			ret = {v}
			first = false
		elseif v >= ret[#ret] then --skip ahead
			table.insert(ret, v)
		elseif v <= ret[1] then --put it first
			table.insert(ret, 1, v)
		else
			local pos = 1
			for j = 2, #ret-1 do --secondary loop
				if v >= ret[j] then
					pos = j
				else
					break
				end
			end
			table.insert(ret, pos+1, v)
		end
	end
	return ret --output table
end
Image

And a small program to test it:
ArrayOrganizer.love
(1.11 KiB) Downloaded 209 times
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Mini Functions Repository

Post by HugoBDesigner »

My bosses asked me to include Facebook and Twitter sharing stuff, and while they're mostly easy to do, I figured I'd share here so you guys can use it in your own games (they don't know I'm sharing this code shhhhh :rofl: ).

Code: Select all

function string:urlFormat()
	local s = string.gsub(self, " ", "%%20")
	s = string.gsub(s, "/", "%%2F")
	s = string.gsub(s, "'", "%%27")
	return s
end

function facebook_share(title, url)
	local t = {}
	
	t.title = title:urlFormat()
	t.u = url:urlFormat()
	
	local amp = ""
	local url = "http://www.facebook.com/sharer.php?"
	
	for i, v in pairs(t) do
		url = url .. amp .. i .. "=" .. v
		amp = "&"
	end
	
	love.system.openURL(url)
end

function twitter_share(text, link, hashs)
	local t = {}
	
	t.text = text:urlFormat()
	t.url = link:urlFormat()
	
	if hashs then
		t.hashtags = table.concat(hashs, ",")
	end
	
	local amp = ""
	local url = "http://twitter.com/share?"
	
	for i, v in pairs(t) do
		url = url .. amp .. i .. "=" .. v
		amp = "&"
	end
	
	love.system.openURL(url)
end
Add this to any file. Usage is simple:
twitter_share("Your Text's Here!", "http://example.com", {"hashtag", "otherTag", "cool"})
First the text of your tweet, then the url, then a table with your hashtags (this one is optional).

facebook_share("Your post's title", "http://example.com")
First the title of your post, then the url.

Credits are not even needed, I made this real quick :P
@HugoBDesigner - Twitter
HugoBDesigner - Blog
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Mini Functions Repository

Post by davisdude »

That's great! Thanks for sharing! :rofl: I'm sorry, I couldn't resist
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Zireael
Party member
Posts: 139
Joined: Fri Sep 02, 2016 10:52 am

Re: Mini Functions Repository

Post by Zireael »

Inny, I like your print() functions! *grabs it and runs* :)
Post Reply

Who is online

Users browsing this forum: No registered users and 63 guests