A small module that uses LuaJIT's FFI to bypass the restrictions on love.filesystem so you can read and write files and folders anywhere.
PhysFS is the underlying C library that powers love.filesystem. It offers some filesystem features that Lua's standard io
library does not, such as: listing all files & folders in a directory, and creating new directories (in a cross-platform way).
Unfortunately, Löve hamstrings these features by restricting their use to only a few possible locations:
- The "save directory" (such as: C:\Users\bob\AppData\Roaming...).
- The folder that your main.lua is in.
- The folder containing your .love file, if the game is fused.
- Folders that the user drag-and-drops onto the game window while it is running.
Also Löve only ever allows write access to the save directory.
Usually this is fine, if you're making a normal, small game, but if you want to make any kind of editor or tool, custom file dialogs, add certain modding capabilities, or anything else that would require greater filesystem access, then you are out of luck.
"URFS" uses LuaJIT's FFI to call PhysFS functions directly, bypassing Löve's added restrictions so you can do what you want.
Since PhysFS is already included in Löve, you don't need to add any .dlls or .sos or install anything else on your system. Everything in love.filesystem will work without modification; URFS only gives alternatives to the functions that are restricted (mount & unmount) or nonexistent (get/setWriteDir) to give the love.filesystem functions access to other directories.
Add urfs.lua to your project and require it.
-- Example:
local urfs = require "urfs"
Add a directory or archive (.zip) to the list of search paths for reading files. This means the files and folders inside of archive
will be accessible to the "reading" functions from love.filesystem, such as love.filesystem.getInfo, love.filesystem.getDirectoryItems, and love.fileSystem.getRealDirectory, among others. They will also be accessible to the asset loading functions like love.graphics.newImage and so on.
PARAMETERS:
archive
- string - The path of the directory or archive to mount.mountPoint
- string - Optional - The virtual path thatarchive
will be mounted to. This can overlap existing virtual paths. The default ofnil
(equivalent to an empty string) will add the files fromarchive
to the root of the virtual filesystem.appendToPath
- string - Optional - Pass intrue
ifarchive
should be searched after already-mounted archives when reading files. By default the archive path is prepended, meaning newly-mounted files will be accessed if paths overlap.
RETURNS:
isSuccess
- bool -true
ifarchive
was mounted successfully, false if not.errorMsg
- string | nil - The error message if mounting failed, ornil
if it was successful.
See: PHYSFS_mount for more info.
Remove a directory or archive that was previously mounted from the search path.
PAREMETERS
archive
- string - The original path of the directory or archive to unmount. This must equal thearchive
parameter previously passed tourfs.mount
.
RETURNS:
isSuccess
- bool -true
ifarchive
was unmounted successfully, false if not.errorMsg
- string | nil - The error message if unmounting failed, ornil
if it was successful.
See: PHYSFS_unmount for more info.
Get the mount point used to mount an archive path, or nil
if it's not mounted. PhysFS does not allow you to mount the same archive to multiple mount points; subsequent calls to urfs.mount() will do nothing (and give no error) and the archive will stay mounted at its first mount point.
PAREMETERS
archive
- string - Thearchive
path parameter previously passed tourfs.mount
.
RETURNS:
mountPoint
- string | nil - The lastmountPoint
ofarchive
, ornil
if it is not mounted. Returns an empty string ifarchive
was mounted without specifying a mount point.
PhysFS (and love.filesystem) always has a single directory that is used to write files and directories. This function lets you change that directory. This affects all love.filesystem functions that modify or create files and directories, such as: love.filesystem.createDirectory, love.filesystem.newFile, and love.filesystem.write. By default, Löve sets the write dir to the save directory.
PARAMETERS:
dir
- string - The new absolute path to the directory that will be used to write files and directories.
RETURNS:
isSuccess
- bool -true
if the write dir was set successfully, false if not.errorMsg
- string | nil - The error message ifsetWriteDir
failed, ornil
if it was successful.
See: PHYSFS_setWriteDir for more info.
Get the current directory used by love.filesystem to write files and directories.
RETURNS:
writeDir
- string - The current absolute path to the directory used to write files and directories. If you have not already usedurfs.setWriteDir
to change the write dir, this will return the same value aslove.filesystem.getSaveDirectory()
.
See: PHYSFS_getWriteDir for...not much more info.