Troubleshooting
Common problems and how to fix them.
Mod doesn’t show up in Mod Manager
Symptom: You placed a folder in Mods/ but the editor doesn’t list it.
Checklist:
-
Folder location is correct:
- Project:
<gameRoot>/Plugins/MakerStudio/003_Editor/Mods/<your-mod-id>/ - Global:
%APPDATA%/maker-studio/Mods/<your-mod-id>/ - The folder must be inside
Mods/, not next to it.
- Project:
-
manifest.json exists and is valid JSON. Required fields:
id,name,version,apiVersion,main. Common mistake: missing comma or trailing comma in JSON. -
apiVersion matches. Must be
"1.0.0". A wrong version like"2.0.0"will be rejected. -
Entry file matches
mainfield. Ifmainis"index.js", the fileindex.jsmust exist in the mod folder. -
Re-open the project or click Reload in Mod Manager. The editor only scans on project open or manual reload.
Mod shows “error” status
Symptom: Mod appears in the list but its status is red/errored.
- Open the Mod Manager, click on the mod row to expand its log. The error message is there.
- Check the browser console (
Ctrl+Shift+Iin the editor window) for the full stack trace. - Common causes:
- Syntax error in
index.js— validate with a linter. - Missing
export function activate(ctx) { ... }— this is required. - Importing external packages — mods run in a sandboxed context. Only bare ESM syntax works. Use
window.__TAURI__for Tauri commands instead of importing@tauri-apps/api. - Runtime error inside
activate()— wrap in try/catch to narrow down.
- Syntax error in
Mod loads but does nothing
Symptom: Status shows “active” but toasts/events/menu items don’t appear.
- Check the mod log in Mod Manager — did
activate()actually run? Addctx.log.info("activate called")as the first line. - Check event names — they are case-sensitive.
"map.loaded"not"Map.Loaded". - Menu items need a menu —
menu: "Mods"places it under the Mods menu. A typo creates a new top-level menu you might not notice. isEnabledreturning false — if yourisEnabledcallback returns false, the menu item is grayed out.
Changes to mod files don’t take effect
Symptom: You edited index.js but the behavior didn’t change.
- Click Reload on the mod row in Mod Manager. The editor reads files once on load.
- Check you’re editing the right file — if the same mod id exists in both project and global locations, the project version shadows the global one. Check the source badge (blue = project, purple = global).
- Clear browser cache — unlikely but possible if you changed the manifest.
”Permission denied” on file operations
Symptom: ctx.fs.readProjectFile(...) or ctx.fs.writeModFile(...) throws PermissionDeniedError.
- Path traversal is blocked — paths containing
..or absolute paths are rejected. Use relative paths. readProjectFile/writeProjectFile— scoped to the game root. You can only access files within the project.readModFile/writeModFile— scoped to your mod’s own folder. You can’t write outside it.
Mod’s panel doesn’t show up
Symptom: ctx.ui.registerPanel(...) was called but no panel is visible.
- Panels start in the default position — check the edges of the editor window. It may be docked but collapsed.
- Use
defaultPosition— set it to"left","right","below", or"above". - Check the console — if
render(host)throws, the panel content is empty but the tab should still appear. - Unique id required — if another mod (or the same mod reloaded) registered the same panel id, the second registration is silently ignored.
- “Panel provided by mod … — not loaded” placeholder — the panel’s slot persists in the user’s layout while your mod is unloaded (hot reload, disabled, error). That placeholder is normal; your content swaps back in when the mod re-registers the panel. If it stays a placeholder, your mod failed to activate — check the Mod Manager log.
Two mods conflict
Symptom: Both mods work alone but break when both are active.
- Check command id collisions — command ids are global. If both mods register
"export.map", the second overwrites the first. Namespace with your mod id:"my-mod.export.map". - Check event handler order — bus handlers run in registration order. If both cancel
save.before, the first one wins. - Check tool id collisions — same issue as commands. Use unique tool ids.
TypeScript / type checking
Symptom: You want IntelliSense for ctx.
// tsconfig.json in your mod folder{ "compilerOptions": { "types": ["../../path/to/editor/src/mod-api"] }}Or use a /// <reference types="..." /> directive in your entry file.
The type definitions live in src/mod-api/types.ts in the editor source.
Context menu item doesn’t appear
Symptom: ctx.ui.registerContextMenuItem() was called but item doesn’t show in the right-click menu.
- Check context name — must be one of
"map-tile","map-event","tile-palette","tile-palette-extra","layer","map-tree","event-editor". Case-sensitive. - Check
parentMenuspelling — if usingparentMenu, the submenu label must match exactly (case-sensitive). Check the editor’s context menu for the exact label (including ellipsis…). - Check
isEnabled— if your callback returns false, the item is greyed out but still visible.
Overlay doesn’t render
Symptom: ctx.ui.registerOverlay() was called but nothing draws on the map canvas.
- Check render function — ensure you’re actually drawing to the canvas context (e.g.
ctx.fillStyle = ...,ctx.fillRect(...)). - Check viewport math — tile positions must be converted to screen coords:
(tileCoord * tileSize - viewportOffset) * zoom. Out-of-viewport draws are clipped. - Check
zOrder— overlays with higherzOrderrender on top. Default is 0. - Check
info.mapId— if your overlay only draws for specific maps, verify the mapId matches.
Keyboard shortcut doesn’t fire
Symptom: ctx.ui.registerShortcut() (or a menu item’s shortcut) was called but pressing the keys does nothing.
- Check key format — must be
"Ctrl+Shift+F","Alt+G", etc. Case-sensitive,+separated. - Check for conflicts — if your key clashes with a built-in or another mod’s shortcut, open the editor’s Keyboard Shortcuts dialog (the “Mods” section lists every mod menu shortcut) and rebind whichever side you want. Avoid the common built-ins like
Ctrl+S(save) andCtrl+Z(undo). - Check mod is active — shortcuts only work while the mod is loaded and enabled.
Note: A menu item’s
shortcut(ctx.menu.registerMenuItem({ shortcut })) now fireshandleron its own and is rebindable in the Keyboard Shortcuts dialog. You do not need a separatectx.ui.registerShortcutfor it — calling both double-registers the key.
Multi-file import doesn’t work
Symptom: import { x } from './utils.js' causes the mod to fail to load.
- Use relative specifiers only — imports must start with
./or../. Bare specifiers like'lodash'or'my-lib'will not work — the editor does not bundle npm packages. - Include the
.jsextension — always write'./utils.js', not'./utils'. The file extension is required. - File must exist in the mod folder — all imported files must be
.jsfiles inside the mod directory (subdirectories are fine). The editor discovers files by scanning the directory tree. - Check for syntax errors in imported files — any syntax error in any
.jsfile in the mod folder can prevent the mod from loading. Check the Mod Manager log for the specific file and line. - CommonJS mods are single-file only — if your entry uses
module.exports = ..., thenew Functionfallback does not support multi-file imports. Use ESM syntax (export function ...) in your entry to enable multi-file support.