Fun facts!

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Fun facts!

Post by Santos »

Here are some things that at some time probably made me go "Wow, I didn't know you could do that! I mean, until just now, that is." Feel free to add your own!


Did you know...

There are languages that have been used with LÖVE other than Lua: Killa (which I think is being used for the new Concerned Joe which is in-development) and Moonscript (used for the Ludum Dare entries Volcanox and Wulcan, by Leafo)


To insert that Ö character you can use Alt+153 in Windows, Ctrl+Shift+u then 00d6<Enter> in Ubuntu (maybe there is an easier way?), or Shift+Alt+V in gVim.


Methods can be used on literal strings and entries can be accessed from literal tables by putting parentheses around the strings/tables:

Code: Select all

({'aquamarine', 'azure', 'auburn'})[math.random(1, 3)]
('This really should be in all caps'):upper()

love.load can take command line arguments. You could use them to specify an input file, or a level to jump to, or to enable debugging mode...


To launch LÖVE games with their compatible version, you could install each version of LÖVE to a separate location (old versions can be found here), change the file extension of your .love files to represent their version number, (e.g. .love072), and change the default application with which they open with to the appropriate LÖVE executable.


Parentheses can be omitted from function calls if it has a single argument which is either a literal string...

Code: Select all

require 'RequireIsAFunction'
love.graphics.setCaption 'Test'
or a table constructor.

Code: Select all

for i, v in ipairs{'a', 'b', 'c'}
end

You can share code with other people using pastebin services such as hastebin.


You can change the icon of Windows executable files using Resource Hacker.


Varargs (...) and the return values from functions can be put into tables using table constructors:

Code: Select all

function f(...)
    args = {...}
    print('The second argument is '..args[2])
end

Code: Select all

positions = {love.mouse.getPosition()}
print('x position is '..positions[1])
print('y position is '..positions[2])

You can make your very own errors using assert, and you can also print error messages to the terminal.


You can reduce the filesize of PNG files using PNG optimization software such as PNGGauntlet.


LÖVE apparently works best with Ogg Vorbis audio, which other formats can be converted to using Audacity or SoX from the command line.


I hope someone knows something now that they didn't know before! ^^ If you have some fun facts which I didn't think of, you could totally post them here (they don't even need to be fun or factual!)

EDIT: Oh yeah, I forgot something!

To easily comment and uncomment a section like this:

Code: Select all

---[[
    The first "-" of ---[[ can be removed or added
    to comment and uncomment these lines.
--]]
Last edited by Santos on Tue Mar 05, 2013 8:46 am, edited 2 times in total.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Fun facts!

Post by Roland_Yonaba »

Well, I already most of the things you cited, about Lua's syntax. Well, probably because I went through the whole book PiL.
However, I learnt some knew stuff. Thanks.
Nice topic.

Well, I'll add my own, a single link : Lua Hacks
I also made two libraries, which provides syntactic sugars for tables and strings handling: Moses and Allen.
Also, If one have ever felt the need to make Lua behave like C, using preprocessing macros, see LuaMacro
And oh, I'll mention Bartbes and Robin's Meta, which provides some extras to Lua scripting.
Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Re: Fun facts!

Post by Santos »

Wow, that Lua Hacks page will require some careful reading!

I was actually inspired to create this more "general" thread after your recent thread which turned out really well I thought. (Although this thread might be too general. :D) I think I'll follow Inny's advice, and actually read PiL cover-to-cover, and more of the lua-users wiki.

Your libraries look really cool, as does Meta, I should read over them sometime to see if I can work out what's going on, and read LuaMacro's readme.

I have so much to learn. :ultraglee:

Thanks for the response!
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Fun facts!

Post by Inny »

Santos wrote:I was actually inspired to create this more "general" thread after your recent thread which turned out really well I thought. (Although this thread might be too general. :D) I think I'll follow Inny's advice, and actually read PiL cover-to-cover, and more of the lua-users wiki.
If you want to get super advanced with Lua, there's a book called Lua Programming Gems. My favorite chapter is the one where an update in the GUI library screwed their startup time so they came up with a way to dynamically require libraries during runtime. It inspired this code snippet of mine:

Code: Select all

-- Class loader
local Origin = {}
function Origin.__index( t, k )
  local f = k:lower():gsub("(_)", "/")
  if love.filesystem.isFile(f..".lua") then
    print( "Require", f )
    require( f )
    return rawget(_G, k)
  elseif love.filesystem.isFile("lib/"..f..".lua") then
    print( "Require lib", f )
    require( "lib/"..f )
    return rawget(_G, k)
  end
end

setmetatable( _G, Origin )
Though I haven't tested this in 0.8.0, and it could use a rewriting.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Fun facts!

Post by Roland_Yonaba »

I've been told that require works best with dots, in other to be compatible on all systems.

Code: Select all

-- Class loader
local Origin = {}
function Origin.__index( t, k )
  local f = k:lower():gsub("(_)", "/")
  if love.filesystem.isFile(f..".lua") then
    print( "Require", f:gsub('/','.') )
    require( f )
    return rawget(_G, k)
  elseif love.filesystem.isFile("lib/"..f..".lua") then
    print( "Require lib", f )
    require( "lib/"..f:gsub('/','.') )
    return rawget(_G, k)
  end
end

setmetatable( _G, Origin )
Well, if the library returns a local var, instead of setting something in the global space, some adjustments need to be made. Maybe set _G[libName] = require (libPath), before returning it with rawget.
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Fun facts!

Post by T-Bone »

I like this thread. These things are so easy to miss even if you use lua for years.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Fun facts!

Post by Nixola »

Ö on Ubuntu: hold down AltGR (or Ctrl+Alt, I think) and shift, press :, then release every key and type O normally, either by using caps lock or holding shift
ö on Ubuntu: it's the same, just type a lowercase "o" after Alt+Ctrl+Shift+:
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Fun facts!

Post by Roland_Yonaba »

Wow.
I came back on variables scoping in Lua, but I didn't find was I was looking for.
It is not even mentionned in he book, it seems. Anayway, I didn't know that was doable.

Code: Select all

function a(b)
b = b or 1
print(b)
end

a() --> 1
a() --> 1
a() --> 1
print(b) --> nil!
I found it strange, because I was pretty sure that this function, when given no arg, creates a global var named b, with value 1, before printing it.
So there's no difference between the snippet above and this one, huh ?

Code: Select all

function a(b)
local b = b or 1
print(b)
end

a() --> 1
a() --> 1
a() --> 1
print(b) --> nil!
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Fun facts!

Post by Robin »

Here's a mostly-correct explanation why: Lua works with lexical scoping, in particular a version where the scope is known at compile-time.

In more details:
There are three kinds of variables:
  • Globals
  • Locals
  • Up-values (that is, locals for a function that encloses the current function)
Arguments are locals.

This:

Code: Select all

x = "global"
local y = "local"
function foo()
   local z = "local"
   y = "y is an up-value here"
end
will get compiled to something like the following:

Code: Select all

get the string "global"
set the global variable "x" to it
get the string "local"
set the local no. 0 to it
create a function with the following code:
    get the string "local"
    set the local no. 0 to it
    get the string "y is an up-value here"
    set the local no. 1 to it
this function should have local no. 1 that is a reference to our local no. 0
set the global variable "foo" to it
I hope that makes it clear how things work.
Help us help you: attach a .love.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Fun facts!

Post by Roland_Yonaba »

Robin wrote:Up-values (that is, locals for a function that encloses the current function)
Yes. Since you mentionned that very word. Thanks. Karma ya.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 2 guests