Class ModManager
- Namespace
- GrindFest
- Assembly
- GrindFest.dll
Central mod manager. Handles discovery, deployment, and hot-reload of all mod types.
Currently supports:
- Ink Story mods (.ink files → runtime compilation → world regeneration)
- UI mods (JavaScript/TypeScript → OneJS ScriptEngine eval)
Future:
- Prefab mods (Addressable prefab overrides)
- Script mods (C# bot scripts)
Folder structure: persistentDataPath/Mods/GrindFest/Story/ — base story mod (smart-copied from StreamingAssets) persistentDataPath/Mods/[ModName]/Story/ — additional story mods persistentDataPath/Mods/[ModName]/UI/dist/index.js — UI mod entry point (eval'd after app.js) persistentDataPath/Mods/[ModName]/Prefabs/ — (future) prefab overrides persistentDataPath/Mods/[ModName]/Scripts/ — (future) script mods
In Editor, can optionally use Assets/_GrindFest/Story/ directly (toggle via UseEditorStoryFiles).
[DefaultExecutionOrder(-50)]
public class ModManager : Singleton<ModManager>
- Inheritance
-
objectModManager
- Inherited Members
Fields
- ReopenModBrowserAfterReload
Re-discover all mods and trigger a full UI reload via Runner. Call this after subscribing/unsubscribing to workshop mods. Sets GrindFest.ModManager._uiModDirty so Runner.Reload() happens safely on the next frame (avoids destroying the JS engine while JS code is still on the call stack).
Properties
- ActiveStoryDirectory
The active story directory used for compilation. In Editor with UseEditorStoryFiles=true: Assets/_GrindFest/Story/ Otherwise: persistentDataPath/Mods/GrindFest/Story/
- BaseModStoryDirectory
Base mod directory: persistentDataPath/Mods/GrindFest/Story/
- EditorStoryDirectory
Editor source: Assets/_GrindFest/Story/
- LoadedUIMods
Discovered UI mods: modName → full path to index.js
- ModsRootDirectory
Root mods directory: persistentDataPath/Mods/
- StreamingAssetsStoryDirectory
StreamingAssets story source: StreamingAssets/Mods/GrindFest/Story/
- TypingsDirectory
Shared typings directory: persistentDataPath/typings/ (sibling to Mods/)
Methods
- CompileStory()
Compile Story.ink from the active directory (with mod injection) and return a Story object. Returns null on compilation failure.
- DeployBaseStoryMod()
Deploy base .ink files to Mods/GrindFest/Story/ (persistentDataPath). Uses hash-based detection to avoid overwriting player-modified files. In editor: copies from Assets/_GrindFest/Story/ directly (.ink files). In builds: copies from StreamingAssets/Story/ (.inkdata files, renamed to .ink). StoryBuildPreprocessor uses .inkdata extension to avoid Ink editor auto-compilation.
- DeployStoryToModsFolder()
Copy .ink files from Assets/_GrindFest/Story/ to persistentDataPath/Mods/GrindFest/Story/. Use this to test the mod pipeline: toggle UseEditorStoryFiles off, then edit files in the Mods folder.
- DiscoverMods()
Discover all mods from local Mods/ folder and Steam Workshop. Populates the Mods list with ModDefinitions. Local mods take priority (if same Name exists in both).
- GetAllModPaths()
Get all mod folder paths (local + Workshop). Used by JS-side loadUIMods to find UI/dist/index.js files.
- RecompileStoryAndReload()
Recompile ink and reload the story + world.
Events
- OnCompilationError
Fired when compilation fails. Listeners receive the error message.
- OnStoryRecompiled
Fired when story is recompiled from .ink sources. Listeners receive the compiled Story object.
- OnUIModError
Fired when a UI mod fails to load. Listeners receive (modName, error).
- OnUIModLoaded
Fired when a UI mod is loaded. Listeners receive (modName, modPath).