User:TheHorscht/Info about dofile

Written by Zatherz: https://discord.com/channels/453998283174576133/632303734877192192/774017369113886730

...it is essentially require yes

require also executes the target script in the current environment

except that standard lua require is based on the package.path load system (where paths like foo.bar.baz get turned into foo/bar/baz.lua or foo/bar/baz/init.lua etc)

dofile_once is the closest you get to require in noita

the difference between dofile and dofile_once is that everytime you call dofile, it accesses and reads the file at the specified path (like in standard lua), then loads it as a script and executes it

noita replaces standard dofile with this:

__loaded={} dofile=function(filename) local f=__loaded[filename] if f==nil then f,err=loadfile(filename) if f==nil then return f,err end __loaded[filename]=f end local result = f do_mod_appends(filename) return result end

therefore the file is cached by filename, and if dofile was called earlier with the same filename, you will get the cached result if __loaded[filename] exists within the calling lua state

as for dofile_once, it's defined as

__loadonce={} dofile_once=function(filename) local result=nil local cached=__loadonce[filename] if cached~=nil then result=cached[1] else local f,err=loadfile(filename) if f==nil then return f,err end result=f __loadonce[filename]={result} do_mod_appends(filename) end return result end

as opposed to the dofile implementation, this caches a single result of loading the specified file by filename

in a global

noita uses multiple lua states due to making some use of parallelism/multithreading, and the lua states share no information between eachother (with the exception of functions that do access global data and are exposed to lua states like GlobalsSetValue/GlobalsGetValue)

tldr dofile_once guarantees that for the same path, the file will only be executed once within a single lua state (assuming dofile/loadfile isn't used for the same path)

while dofile guarantees that for the same path, the file will only be loaded once within a single state (with the same assumption as above) but will be executed for every call to dofile