diff --git a/files/libraries/noita-api/compatibility.lua b/files/libraries/noita-api/compatibility.lua index 793e7b5..6f977f5 100644 --- a/files/libraries/noita-api/compatibility.lua +++ b/files/libraries/noita-api/compatibility.lua @@ -5,8 +5,6 @@ -- Some code to make Noita's lua conform more to standard lua. --- TODO: Make Noita-API module to work with several mods using it - -- Stupid way to prevent this code from being called more than once per sandbox. -- Calling this lua file with dofile_once would still cause the setup function to be called multiple times. if _NoitaAPICompatibilityWrapperGuard_ then return function(dummy) end end @@ -123,7 +121,7 @@ local function setup(libPath) package.path = package.path .. "./" .. libPath .. "?/init.lua;" -- Add the library directory of Noita itself. - package.path = package.path .. "./data/scripts/lib/?.lua;" + package.path = package.path .. "./data/scripts/lib/?.lua;" -- TODO: Get rid of Noita's lib path, create replacement libs for stuff in there end return setup diff --git a/files/libraries/noita-api/live-reload.lua b/files/libraries/noita-api/live-reload.lua new file mode 100644 index 0000000..808c842 --- /dev/null +++ b/files/libraries/noita-api/live-reload.lua @@ -0,0 +1,50 @@ +-- Copyright (c) 2022 David Vogel +-- +-- This software is released under the MIT License. +-- https://opensource.org/licenses/MIT + +-- Allows Noita mods to reload themselves every now and then. +-- This helps dramatically with development, as we don't have to restart Noita for every change. +-- To accomplish this, we need to override the default behavior of dofile and some other things. + +local LiveReload = {} + +local oldDofile = dofile +---Overwritten dofile to execute a lua script from disk and cirumvent any caching. +---Noita for some reason caches script files (Or loads them into its virtual filesystem)(Or caches compiled bytecode), so reloading script files from disk does not work without this. +--- +---This is not fully conform the the standard lua implementation, but so isn't Noita's implementation. +---@param path string +---@return any result +---@return string|nil err +function dofile(path) ---TODO: Consider moving dofile into compatibility.lua + local func, err = loadfile(path) + if not func then return nil, err end + + local status, res = pcall(func) + if not status then return nil, res end + + return res, nil +end + +---Reloads the mod's init file in the given interval in frames. +---For reloading to work correctly, the mod has to be structured in a special way. +---Like the usage of require and namespaces. +--- +---Just put this into your `OnWorldPreUpdate` or `OnWorldPostUpdate` callback: +--- +--- LiveReload:Reload("mods/your-mod/") -- The trailing path separator is needed! +---@param modPath string +---@param interval integer +function LiveReload:Reload(modPath, interval) + self.Counter = (self.Counter or 0) + 1 + if self.Counter < interval then return end + self.Counter = nil + + local res, err = dofile(modPath .. "init.lua") + if err then + print(string.format("Error reloading mod: %s", err)) + end +end + +return LiveReload diff --git a/init.lua b/init.lua index 402021d..1101ff4 100644 --- a/init.lua +++ b/init.lua @@ -20,9 +20,10 @@ end -- Load library modules -- -------------------------- -local Coords = require("coordinates") local CameraAPI = require("noita-api.camera") +local Coords = require("coordinates") local DebugAPI = require("noita-api.debug") +local LiveReload = require("noita-api.live-reload") local Vec2 = require("noita-api.vec2") ----------------------- @@ -47,6 +48,14 @@ dofile("mods/noita-mapcap/files/ui.lua") ---Called in order upon loading a new(?) game. function OnModPreInit() + -- Override virtual resolution and some other stuff. + --ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/64.xml") + --ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/fast-cam.xml") + --ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/no-ui.xml") + --ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/offset.xml") + + -- Remove hover animation of newly created perks. + ModLuaFileAppend("data/scripts/perks/perk.lua", "mods/noita-mapcap/files/overrides/perks/perk.lua") end ---Called in order upon loading a new(?) game. @@ -83,6 +92,11 @@ end function OnWorldPostUpdate() -- Draw UI after coroutines have been resumed. UI:Draw() + + -- Reload mod every 60 frames. + -- This allows live updates to the mod while Noita is running. + -- !!! DISABLE THIS LINE AND THE CORRESPONDING REQUIRE BEFORE COMMITTING !!! + LiveReload:Reload("mods/noita-mapcap/", 60) end ---Called when the biome config is loaded. @@ -111,16 +125,3 @@ end ---Please be careful with this, as not everything will behave well when called while the game is paused. function OnPausePreUpdate() end - ---------------- --- Overrides -- ---------------- - --- Override virtual resolution and some other stuff. ---ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/64.xml") ---ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/fast-cam.xml") ---ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/no-ui.xml") ---ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/offset.xml") - --- Remove hover animation of newly created perks. -ModLuaFileAppend("data/scripts/perks/perk.lua", "mods/noita-mapcap/files/overrides/perks/perk.lua")