Table of Contents

Class ModScriptCompiler

Namespace
GrindFest
Assembly
GrindFest.dll

Compiles C# scripts from mods into in-memory assemblies, with security scanning.

Security model:

  1. Parse all .cs files into Roslyn syntax trees.
  2. Walk the syntax trees looking for dangerous API usage (not string matching — avoids false positives from comments and string literals).
  3. If dangerous APIs found and mod is not trusted → block compilation.
  4. Trust is hash-based: if scripts change, trust is revoked.
  5. First-party mods (author "GrindFest Team") are always trusted.
public static class ModScriptCompiler
Inheritance
object
ModScriptCompiler

Properties

TrustStorePath

Path to the trust store file: persistentDataPath/trusted-mods.json Format: { "ModName": "sha256-of-all-scripts", ... }

Methods

CompileAll(List<ModDefinition>)

Compile all mods that have a Scripts/ folder. Handles security scanning, trust gating, and Roslyn compilation. Populates mod.SecurityWarnings, mod.ScriptsBlocked, mod.ScriptsTrusted, mod.ScriptsHash.

ComputeScriptsHash(string[])

Compute a combined SHA-256 hash for all .cs files. Used to detect script changes (invalidates trust).

InvokeEntryPoints(List<ModDefinition>)

Runs every IMod implementation found in the mods' compiled assemblies, in mod load order. Each mod is activated at most once per session; each type is instantiated once, and a type that throws is logged and skipped — one broken mod must never take the boot down with it.

IsModTrusted(ModDefinition, string, Dictionary<string, string>)

Check whether a mod is trusted for the given scripts hash.

LoadTrustStore()

Load the trust store from disk.

NotifyContentLoaded()

Delivers OnContentLoaded() to every active entry point. Called after each successful content merge (boot load and hot reloads alike), so a mod can resolve cross-mod definitions knowing every package is in. A throwing mod is logged and skipped — it never breaks the others or the reload.

ResetSessionState()

Clears the per-session compile/invocation state. Called by ModManager at boot so that a boot always compiles from scratch and re-runs entry points, even with domain reload disabled.

SaveTrustStore(Dictionary<string, string>)

Save the trust store to disk.

ScanSyntaxTrees(List<SyntaxTree>)

Scan parsed syntax trees for dangerous API usage. Walks the AST to avoid false positives from comments and string literals.

TrustMod(ModDefinition)

Mark a mod as trusted (writes its current scripts hash to the trust store). Called from the mod browser UI when user clicks "Trust & Enable".

UnloadMissingMods(List<ModDefinition>)

Delivers OnUnload() to every entry point whose mod is no longer in the active set (unsubscribed / folder removed during a live refresh) and drops its session state, so a later re-subscribe compiles and activates it fresh. Assemblies cannot be unloaded — code a removed mod scheduled elsewhere keeps running until the next boot.