Mod Discovery

Detect other loaded mods for integrations and dependencies

The api.mods namespace lets your mod see which other mods are loaded in the current session. Use it to enable optional integrations ("if the stats mod is present, feed it my data"), or to warn the player when a mod you depend on is missing.

The registry reflects mods whose scripts executed successfully β€” a mod that is installed but disabled, or that crashed during load, is not listed. It is rebuilt on every hot reload.

isLoaded#

Check whether a mod with the given id is loaded. The id is the id field from the other mod's manifest.json.

javascript
const api = window.SubwayBuilderAPI;

if (api.mods.isLoaded('ridership-heatmap')) {
    console.log('Heatmap mod detected β€” enabling integration');
}

getLoadedMods#

Get manifest info for every loaded mod. Returns an array of:

typescript
{
    id: string;       // manifest id
    name: string;     // display name
    version: string;  // manifest version
    author?: string;  // author name, if declared
}
javascript
for (const mod of window.SubwayBuilderAPI.mods.getLoadedMods()) {
    console.log(`${mod.name} v${mod.version} (${mod.id})`);
}

Load order#

Mods load in the order the loader discovers them, so a mod that loads before yours is visible immediately, while one that loads after yours is not visible until its script has run. If you depend on another mod, don't check at the top of your script β€” check inside a lifecycle hook, by which time every mod has loaded:

javascript
const api = window.SubwayBuilderAPI;

api.hooks.onGameInit(() => {
    if (!api.mods.isLoaded('transit-data-core')) {
        api.ui.showNotification(
            'My Mod works best with Transit Data Core installed!',
            'warning'
        );
    }
});

Communicating between mods#

Discovery tells you a mod is present; to actually exchange data, agree on a shared convention. Since all mods run in the same page context, a namespaced global is the simplest channel:

javascript
// Provider mod
window.MyStatsMod = {
    version: '1.0.0',
    getDailyRidership: () => ({ ...stats }),
};

// Consumer mod
if (window.SubwayBuilderAPI.mods.isLoaded('my-stats-mod') && window.MyStatsMod) {
    const stats = window.MyStatsMod.getDailyRidership();
}