The finding
Originally I was going to make a post about how I couldn't get modules that have a init.lua to work, even though it worked for lua 5.4.
But miraculously, I decided to check the `package.path` and compared love's luajit to lua 5.4's
It just so happed that Löve (or luajit) is missing a certain package path: `./?/init.lua`
Then I also figured out that this issue does not happen if the `main.lua` file is at the root of the project. But I'm making a multiplayer game so I added client/ and server/ folder folders which to run love on.
The issue
If the `main.lua` file isn't at the root of the project folder, (i.e. `love client/` instead of `love .`) then any requires to a module using the module/init.lua scheme will not work and throw an error.
This doesn't happen on lua 5.4.
The workaround
We know that we are missing `./?/init.lua`, so we can just append it to the `package.path` variable:
-- also include a semi-colon!
package.path = package.path .. ";./?/init.lua"
Wrapping up
Why? I do not have the will to go digging for commits and check when this feature was added or removed to lua 5.4 or luaJIT (I checked and yes, it's not Löve's fault but luaJIT's).
I hope that this is helpful to someone in the future. Please suggest any changes or edits to this solution. Even the name of the post so more people can find it.
Oh and, someone let me know if they know why this happens.
Note: I use Linux btw, particularly fedora, but also happens on Ubuntu - I don't know if that's related
The actual solution Don't put two `main.lua`s. Always one on the root of the project. Then parse arguments such as `--server` and run a server script from there.
slime wrote: ↑Sat Feb 01, 2025 10:09 pm
love doesn't use package.path as its primary module searcher, it uses a module searcher from love.filesystem instead which does look for init.lua.
I recommend structuring your project so that main.lua is at the root, and then you pick whether to load client or server files from there based on a command-line parameter parsed from that main.lua (or something similar). It'll save you a lot of confusion and inconsistencies down the road.
Last edited by masakk1 on Sun Feb 02, 2025 12:01 am, edited 1 time in total.
love doesn't use package.path as its primary module searcher, it uses a module searcher from love.filesystem instead which does look for init.lua.
I recommend structuring your project so that main.lua is at the root, and then you pick whether to load client or server files from there based on a command-line parameter parsed from that main.lua (or something similar). It'll save you a lot of confusion and inconsistencies down the road.
slime wrote: ↑Sat Feb 01, 2025 10:09 pm
I recommend structuring your project so that main.lua is at the root, and then you pick whether to load client or server files from there based on a command-line parameter parsed from that main.lua (or something similar).
I see. I investigated how to do so, it means changing some of my code structure, but seems very doable. I'll give it a shot!
Also, can you please allow the post if I tweak it to make that the solution? There isn't any information online about this exact problem unfortunately... so please consider
Edit: I'd also change the title
Edit2: I'm dumb I thought it wasn't approved. My bad!
Last edited by masakk1 on Sun Feb 02, 2025 12:07 am, edited 1 time in total.
slime wrote: ↑Sat Feb 01, 2025 10:09 pm
I recommend structuring your project so that main.lua is at the root
There's only one slight problem. I use a different configuration for the server to disable the display and not show a window. How can I split `conf.lua` in that case?
Specially because `love.conf` runs before `love.load` does...
You can delay window creation by setting the window module to false in conf.lua, and then calling love.window.setMode later (if you want to create a window). At the end of love.load, for example. So, you could just have a separate configuration file, maybe with a boolean field that is checked to use if a window should exist, and you change this field accordingly if setting up a server or client.
MrFariator wrote: ↑Sun Feb 02, 2025 12:56 am
You can delay window creation by setting the window module to false in conf.lua, and then calling love.window.setMode later (if you want to create a window). At the end of love.load, for example. So, you could just have a separate configuration file, maybe with a boolean field that is checked to use if a window should exist, and you change this field accordingly if setting up a server or client.
local function parse_args(args)
for i, arg in pairs(args) do
if arg == "--server" or arg == "-s" then
_G.isServer = true
elseif arg == "--debug" or arg == "-d" then
_G.DEBUG = true
_G._ANTICHEAT_DEBUG = true
end
end
end
function love.load(args)
parse_args(args)
if not _G.isServer then
require("client")
else
require("server")
end
end
The client and server requires are really the previous main.lua's i had.
Works fine on my end. First I ran it with -s, no window was created, and then second run I passed no cli arguments and a window was created.
conf.lua is the same you listed.