Page 1 of 1

setRequirePath() correct usage

Posted: Sat Dec 07, 2019 3:09 pm
by Taffer
I'm new to Love and Lua, but I'm learning both by following along with Harvard's CS50's Introduction to Game Development on edx.org.

Their code targets an older version of Love, so I figured I'd clean things up while I'm at it.

The code uses some 3rd party Lua (such as https://github.com/Ulydev/push), so I wanted to drop the third party code into a common directory and just reference it from each project rather than leaving copies everywhere.

My directory structure is like this:
  • common/push - Ulydev's push repo, so common/push/push.lua exists here
  • pong/pong-0/main.lua - Initial version of the Pong implementation
  • pong/pong-1/main.lua - next iteration
  • ...
I'm modifying main.lua so it can require('push') and load it from the common directory:

Code: Select all

-- Can't find push.lua at the require() call.
love.filesystem.setRequirePath(love.filesystem.getRequirePath() .. ';../../common/push')

-- Also doesn't work.
love.filesystem.setRequirePath(love.filesystem.getRequirePath() .. ';C:/cygwin64/home/Chris/git/harvard-game50/common/push')

-- This works, but I don't really understand why I have to include the filename, push.lua.
package.path = package.path .. ';../../common/push/push.lua'

push = require 'push'
If love.filesystem.setRequirePath() isn't able to access files outside of the game's directory for sandboxing reasons, that makes sense. Is there a "proper" way for me to do this?

Re: setRequirePath() correct usage

Posted: Sat Dec 07, 2019 8:36 pm
by steVeRoll
Hi and welcome!

setRequirePath is not needed to do this - indeed, you can make this work by modifying package.path, albeit a little different than what you wrote.

package.path is a string that contains paths separated by a ';'. When you call require, Lua will go through each one of those paths, replace the '?' with the name you gave to require, and when it finds that file, it runs it.

Assuming that any other libraries that you will add will follow the same naming format as you did with push.lua - a directory that contains the file itself - you can do this with each project:

Code: Select all

package.path = package.path .. ";../../common/?/?.lua"
And if you also want to support multi-file libraries, such as CPML, you can add this too:

Code: Select all

package.path = package.path .. ";../../common/?/init.lua"
This means that when you call require, the name you give it must match the name of the library's folder.

(Note that when you want to share your game with someone else, you must put the required libraries together with the other files.)

Re: setRequirePath() correct usage

Posted: Sat Dec 07, 2019 9:39 pm
by raidho36
Basically, you shouldn't touch require path, you should instead organize your project to work with default settings. This way you avoid ridiculous scenarios where the user has to install specific package managers to install specific Lua libraries in specific filesystem locations. Yes this means you will carry around all of your dependencies - and you ABSOLUTELY SHOULD for more reasons than I care to list but starting with "there will be no version mismatch errors".

As noted above, require path is more of a wildcard expression than a filesystem path.

Require itself doesn't accept file paths - it accepts module names. So make habit of specifying "require"d modules using dot notation, just to make this immediately clear.

Re: setRequirePath() correct usage

Posted: Sun Dec 08, 2019 12:47 pm
by Taffer
Thanks folks! Using package.path properly has done the trick, and I've included comments indicating that this isn't the best way to set up real projects:

Code: Select all

-- Don't do this in a "real" project, I've only done this so we don't need
-- to have copies of the extra libraries in every directory. Best practice is
-- to set things up so your project works with the default package.path, or
-- to only add paths that are inside your package directory.
package.path = package.path .. ';../../common/?/?.lua;../../common/?/init.lua'
Cheers!