Add mod live reload ability

Allow mod to reload script files while Noita is running.
This commit is contained in:
David Vogel 2022-07-27 18:17:26 +02:00
parent a2f5efc9e6
commit 6ca93b54d7
3 changed files with 66 additions and 17 deletions

View File

@ -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

View File

@ -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

View File

@ -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")