Help calling Love functions from a module

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.
Post Reply
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Help calling Love functions from a module

Post by milon »

EDIT - Mods, thanks for not posting both threads. I didn't catch the message the first time around that it needed manual verification first.

Hi all, I'm a super new to Love (and to Lua in general). This is probably a super-simple issue and I'm just missing something obvious, but I can't figure it out even though I've searched the forum and Google quite a bit.

I'm generating heightmaps using the Lua diamond-square heightmap generator found at https://github.com/mlepage/heightmap. I load it in main.lua using heightmap = require "heightmap" on the first line of function love.load() . I can get output from it just fine, but I want to be able to re-create the same heightmaps, so I need to seed a deterministic function, rather than the random() function (line 92 of https://github.com/mlepage/heightmap/bl ... ghtmap.lua). I'm seeding with 2 integers (Seed & ID, which are global variables), so I changed line 92 to read:

Code: Select all

return h + (love.math.noise(x,y,Seed,ID)-0.5)*d
That results in the following error:

Code: Select all

Error: heightmap.lua:92: attempt to index global 'love' (a nil value)
stack traceback:
	heightmap.lua:92: in function 'f'
	heightmap.lua:60: in function 'diamondsquare'
	heightmap.lua:100: in function 'create'
	main.lua:19: in function 'load'
	[string "boot.lua"]:440: in function <[string "boot.lua"]:436>
	[C]: in function 'xpcall'
>Exit code: 1
For some reason, it's not using the love library and is looking for a global, and not finding it. I have no idea what "boot.lua" or "xpcall" are, but I assume they're a part of Lua's backend. Anyway, I wanted to ensure that my global variables are being passed correctly, so I added some print() statements and the defaultf function of heightmap.lua is now:

Code: Select all

function defaultf(map, x, y, d, h)
    --return h + (random()-0.5)*d
    print(x)
    print(y)
    print(Seed)
    print(ID)
    return h + (love.math.noise(x,y,Seed,ID)-0.5)*d
end
... and Lua can't find the print() function now. -_-

Code: Select all

Error: heightmap.lua:128: attempt to call global 'print' (a nil value)
stack traceback:
	heightmap.lua:128: in function 'f'
	heightmap.lua:95: in function 'diamondsquare'
	heightmap.lua:140: in function 'create'
	main.lua:19: in function 'load'
	[string "boot.lua"]:440: in function <[string "boot.lua"]:436>
	[C]: in function 'xpcall'
>Exit code: 1
Note that the change in line-numbers is because I added a number of comments to the start of heightmap.lua (notes to self, MIT license, etc), but otherwise haven't changed anything else.

Go ahead and have a good laugh at this newbie, but when you catch your breath can someone tell me why the basic love functions are failing?
Last edited by milon on Fri Jan 19, 2018 5:53 pm, edited 1 time in total.
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
erasio
Party member
Posts: 118
Joined: Wed Mar 15, 2017 8:52 am
Location: Germany

Re: Help calling Love functions from a module

Post by erasio »

Nothing to laugh about. I just sat here and wondered for quite a while myself.

It's not that obvious.

The source of this issue is this line:

Code: Select all

module(...)
The module function encapsulates the following code. Such that it's public functions can be used when required but that the file itself has no access to any of the global variables. Including print, love and more. All of which are just global variables.

You have two options to solve it.

1. Add a "seeall" parameter to your module function call like this:

Code: Select all

module(..., package.seeall)
2. Declare the variables you need locally before calling module like this:

Code: Select all

local print = print
local love = love
module(...)
Or more compact:

Code: Select all

local print, love = print, love
module(...)
Cheers!
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Help calling Love functions from a module

Post by zorg »

Also, do be aware that the module keywordfunction(ality) is deprecated.
Edited
Last edited by zorg on Fri Jan 19, 2018 5:40 pm, edited 1 time in total.
Me and my stuff :3True 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.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Help calling Love functions from a module

Post by milon »

Thanks so much!! I put some local declarations ahead of the module(...) bit and it works!

Zorg, thanks for the tip. Is there a preferred keyword over module()? I tried commenting out the module line, and it seems that it fails to import the module (even with the require line).

Code: Select all

Error: main.lua:19: attempt to index global 'heightmap' (a boolean value)
EDIT - Figured it out. I read the Lua Module Function Critiqued article and followed the suggestion to skip the module(...) line and instead return the whole thing as a variable. Pretty ingenious, and I'm also starting to wrap my head around variables being anything, even functions! (Or pointers to functions? I dunno, but it works!) :)
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
Post Reply

Who is online

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