Skip to content

启动引导 ​

StudioModLoader.Bootstrapper.Initialize() 是整个框架的入口,由 Installer 通过 Cecil 注入到 Studio.Startup.dll 的初始化序列中,是 Studio 启动时最早执行的 Mod 相关代码。

入口不止一种

Initialize() 设计上不依赖特定的注入方式——Cecil 注入、Doorstop,或 Unity 原生清单调用都可以触发它。内部有 _initialized 幂等保护,重复调用会直接返回。

四个步骤 ​

csharp
public static void Initialize()
{
    if (_initialized) return;
    _initialized = true;

    SetupAssemblyResolver();                          // 1
    GameObject loaderHost = new GameObject("[StudioModLoader]");
    UnityEngine.Object.DontDestroyOnLoad(loaderHost); // 2
    loaderHost.AddComponent<LoaderManager>();         // 3
    ApplyCorePatches();                               // 4
}

① 注册全局程序集解析器 ​

挂 AppDomain.CurrentDomain.AssemblyResolve,在下面这些目录里按文件名查找缺失的程序集,并额外检查每个目录的第一层子目录:

搜索目录
<Studio 安装目录>\Studio_Data\Managed
<Studio 安装目录>\Mods
<Studio 安装目录>\deps
%LOCALAPPDATA%\Studio 2.0\Mods
<Studio 安装目录>

这就是插件可以把自己的依赖 DLL 和主 DLL 放在同一个子目录里的原因。

② 创建全局宿主 ​

创建一个名为 [StudioModLoader] 的 GameObject,标记 DontDestroyOnLoad——切换场景时不会被销毁,保证整个 Studio 会话期间 Loader 一直活着。

③ 挂载 LoaderManager ​

LoaderManager 是一个 MonoBehaviour,负责扫描插件、托管 F10 覆盖层、驱动自动更新与遥测服务。

④ 应用核心补丁 ​

用独立的 Harmony 实例(Identifier = com.studiomodloader.core)打三个补丁:

补丁目标作用
SkipUpdatePromptStudio.Startup.Initialization.Steps.PromptForApplicationUpdateStep.ExecuteAsync跳过 Studio 官方强制版本更新弹窗,避免它把进程顶掉
SaveModelBLStudio.SaveModelToLocalFileSystem(Postfix)捕获存盘事件并分发到 StudioAPI.OnModelSaved
特性补丁扫描当前程序集自动应用 MenubarForWindow、MenuHandler 等声明式补丁

三个补丁各自独立 try/catch:某个目标类型在当前 Studio 版本里不存在时只记一条 Warning,不影响其余补丁与整体启动。

失败处理 ​

Initialize() 整体包在 try/catch 里。出现严重异常时:

  • 异常与堆栈写入 modloader.log(记录器前缀 Bootstrapper);
  • 若 LoaderManager 已实例化,调用 ReportBootstrapError(ex),错误会显示在 F10 控制台的「已加载插件」页。

Studio 本身不会被这个异常带崩——引导失败的结果是「Mod 功能不可用」,而不是「打不开 Studio」。

为 BrickLink Studio 2.0 打造的第三方 Mod 加载框架 · 与 BrickLink / LEGO 官方无关联