Debugging
Tips for debugging your mods during development.
Hot Reload
The fastest way to test changes is hot reloading. After rebuilding your mod:
- Press Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac) in-game
- This calls
api.reloadMods()internally, which clears all mod callbacks, UI components, custom layers, and custom train types, then re-executes all mod scripts
If you're using pnpm dev, Vite automatically rebuilds on file save, so you just need to press the
reload shortcut in-game.
Hot reload clears most mod state, but some things persist (like already-built tracks and stations). If your mod gets into a weird state, restarting the game fully is the safest reset.
Console Logging
Use console.log with a tag prefix to identify your mod's output:
const TAG = '[MyMod]';
console.log(`${TAG} Initialized`);
console.warn(`${TAG} Something unexpected`, someData);
console.error(`${TAG} Failed to load`, error);
Viewing Logs
In-game: Open the developer console with Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac).
With pnpm dev: Logs are printed to your terminal and saved to debug/latest.log. The game
launcher enables Electron logging automatically.
Error Handling
Wrap your initialization in try/catch to avoid crashing the game:
api.hooks.onMapReady((_map) => {
if (initialized) return;
initialized = true;
try {
// Setup code
console.log(`${TAG} Initialized successfully.`);
} catch (err) {
console.error(`${TAG} Failed to initialize:`, err);
api.ui.showNotification('My Mod failed to load. Check console.', 'error');
}
});
For hooks that run repeatedly, consider wrapping each callback:
api.hooks.onDayChange((day) => {
try {
// Your logic
} catch (err) {
console.error(`${TAG} Error on day ${day}:`, err);
}
});
Game Error Hooks
The API provides hooks for catching game-level warnings and errors:
api.hooks.onWarning((message) => {
console.warn(`${TAG} Game warning:`, message);
});
api.hooks.onError((error) => {
console.error(`${TAG} Game error:`, error);
});
Type Checking
Run TypeScript's type checker to catch errors before building:
pnpm typecheck
This runs tsc --noEmit and reports any type errors without producing output files. It's a good
practice to run this before testing in-game.
Common Issues
"SubwayBuilderAPI Not Found"
Your mod script ran before the game initialized the API. This shouldn't happen with the template's structure, but if it does:
- Make sure
maininmanifest.jsonis"index.js" - Make sure you're checking
if (!api)before using the API
UI Not Showing Up
- Check that you're registering UI inside
onMapReady— the UI system isn't ready before the map loads - Verify your component doesn't throw during render (check console for React errors)
- Make sure the
idyou're using is unique — duplicate IDs silently fail
Changes Not Appearing After Reload
- Verify Vite rebuilt successfully (check terminal for build errors)
- Make sure the symlink is still intact (
pnpm dev:link) - Try a full game restart if hot reload isn't picking up changes
React Hooks Errors ("Invalid Hook Call")
This usually means there are multiple React instances. Make sure:
- You're importing from
'react'(not installing react as a dependency) - The Vite alias in
vite.config.tsis correctly pointing tosrc/types/react.ts - You haven't accidentally installed
reactinnode_modules
Windows Symlink Permission Error
On Windows, creating symlinks may require Administrator privileges. Either:
- Run your terminal as Administrator
- Enable Developer Mode in Windows Settings (Settings > For Developers > Developer Mode)