-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
The primary diagnostic file is BepInEx/LogOutput.log in the game directory. Search for How to Lua, the Lua mod ID, Cannot read, Cannot load, or a Lua exception. The Lua Mods panel shows loaded mods and runtime errors; some manifest and dependency failures are logged before a panel entry can be created.
Confirm BepInEx itself loads and both HowToLua.dll and MoonSharp.Interpreter.dll are together in the plugin folder. Restart after replacing DLLs. Host a session and open the gameplay Pause menu; this beta does not add a main-menu launcher.
Check the log for the framework startup line and any Harmony patch errors. A successful build does not prove compatibility with a changed game version.
If the log instead contains Table:m_Values or missing System.Collections, Version=4.0.10.0, follow the interpreter update below.
Each mod must be a direct child of the mods folder beside HowToLua.dll. Check that Windows has not named your files main.lua.txt or manifest.json.txt. The bundled example remains optional under the ZIP's examples folder until you move it into mods.
Check the exact logged error and the manifest rules: valid JSON, supported lowercase ID, nonempty name, existing entry file, correct dependency IDs, and file-size limits. A missing or cyclic dependency blocks loading. Only one folder can use each ID.
The 0.1.0 package selected MoonSharp's netstandard1.6 build. That binary references facade assemblies that the game's Mono runtime cannot resolve. This fails when constructing a Lua table, before the example script can run.
- Close the game completely.
- Install both
HowToLua.dllandMoonSharp.Interpreter.dllfrom the 0.3.0 package intoBepInEx/plugins/HowToLua/, replacing the old copies. - Start the game again and check for
How to Lua 0.3.0and the Lua mod load messages inBepInEx/LogOutput.log.
Reload Lua Mods cannot replace an interpreter DLL already loaded into the process. Preserve your scripts and saved data. Use the packaged interpreter rather than adding unrelated System.* DLLs to the game.
For framework developers, MoonSharp.Reference.props pins the net40-client asset. Both plugin and smoke-test projects import that file. Build-Package.ps1 checks the staged binary under Windows .NET Framework before creating the ZIP.
Use the host's local chat input and include the slash, such as /bonus. A client typing the same message does not invoke a command on the host. The command's owning mod must be loaded and free of runtime errors.
Two Lua mods cannot register the same command. Names are normalized to lowercase; the callback receives only the argument table, not a player object. Check logs for registration conflicts.
Both actions need an active host. Startup code may run before hosting, so prefer event, timer, command, or button callbacks. Money also requires a local player and initialized economy. htf.money(amount) returns false when these conditions are not met.
Rewards change the shared server balance. Other players do not need the Lua mod to receive normal game money/chat updates.
Switch from the mod list to Mods / Actions and check the remaining pages. Host-only buttons are disabled on clients. Runtime failures remove the mod's actions; fix the script and reload. Registration allows up to 16 buttons per mod with 1-48 character labels.
The entry script and each callback may execute up to 50,000 Lua instructions. Infinite loops and sufficiently long callbacks are stopped. Divide work into short callbacks scheduled with htf.after; callbacks cannot yield and coroutine is unavailable.
Use the functions in Lua API. The current API uses htf.chat(message), htf.money(amount), and htf.command(name, callback), not nested functions such as htf.chat.broadcast or htf.command.register.
io, os, debug, require, dofile, loadfile, and coroutine are not exposed. There is no arbitrary C# access or custom network API. Bounded ordinary-item spawning is available through htf.items.spawn in 0.3.0; boss spawning and arbitrary object editing are not.
Values are strings: use tonumber(value) for arithmetic. Files are keyed by mod ID and shared across this installation's worlds. Lua-only reloads preserve those files but reset ordinary Lua variables. Stop the game before manually editing saved data and back up the file first.
The player/world namespaces and the first 21 additional events require 0.2.0. The catalog/item/inventory/combat/server/boat/NPC/boss APIs, extended player/world/economy actions and 23 further events require 0.3.0. Restart after replacing DLLs; Lua reload alone cannot upgrade the framework. Check the version in the startup log. server_save_requested is the supported save event, not server_saved, because native disk failures are handled internally.
Run it on the host with a connected, living player. Pass the exact string steam_id returned by htf.players.list(); do not convert it to a number. Zero-ID/LAN players cannot be addressed by these APIs. Teleports need an active owner connection and refuse to send during island loading. Invalid arguments raise an error instead of returning false; see Player and World API.
Check for feedback loops, such as a money grant inside every money_changed callback. Callback-generated events wait until a later Update. Delivery is capped at 128 per Update; the queue drops new events beyond 1024 and logs a warning. Snapshots are captured at hook time, not delivery time. Use current-state queries when needed. Reload clears pending events but does not fix a script that recreates its feedback loop.
Check that you are hosting a loaded island. items.spawn expects a numeric definition ID, while items.get/despawn expect a canonical decimal network-ID string. Network IDs can be reused after despawning and should not be saved as persistent identities. Catalog and player snapshots show the correct IDs.
Spawning refuses protected prefabs and shares an 8-attempt/second window and a 128-live-item cap across all Lua mods. Reloading scripts does not bypass the live-item cap. Despawning refuses held/stored/attached/protected objects. Save requests share a 5-second cooldown; travel shares a 2-second cooldown and refuses during loading. A true return means the native request was made, not guaranteed disk persistence, a safe destination, or remote acknowledgement.
Upgrade functions are free grants with native index limits, not shop purchases. Native damage also respects game immunity rules. Query updated state after requests; some host-visible fields reflect network/client processing and may lag. See Gameplay API for per-function conditions.
Include the framework and game versions, whether you are hosting, the manifest, the smallest failing Lua snippet, and the relevant exception with its stack trace. Remove private notes, Steam IDs, and unrelated server data before posting logs.