<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>项目 on 羽衣甘蓝的博客</title><link>https://blog.yurikale.top/tags/%E9%A1%B9%E7%9B%AE/</link><description>Recent content in 项目 on 羽衣甘蓝的博客</description><generator>Hugo</generator><language>zh</language><lastBuildDate>Mon, 27 Jul 2026 18:30:00 +0800</lastBuildDate><atom:link href="https://blog.yurikale.top/tags/%E9%A1%B9%E7%9B%AE/index.xml" rel="self" type="application/rss+xml"/><item><title>BlockyLauncher —— 新一代模块化 Minecraft 启动器</title><link>https://blog.yurikale.top/post/blockylauncher--%E6%96%B0%E4%B8%80%E4%BB%A3%E6%A8%A1%E5%9D%97%E5%8C%96-minecraft-%E5%90%AF%E5%8A%A8%E5%99%A8/</link><pubDate>Mon, 27 Jul 2026 18:30:00 +0800</pubDate><guid>https://blog.yurikale.top/post/blockylauncher--%E6%96%B0%E4%B8%80%E4%BB%A3%E6%A8%A1%E5%9D%97%E5%8C%96-minecraft-%E5%90%AF%E5%8A%A8%E5%99%A8/</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://blog.yurikale.top/images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE-2026-07-27-183955.png"&gt;&lt;/p&gt;
&lt;p&gt;Minecraft 启动器这块向来不缺选择：官启、HMCL、PCL、BakaXL，甚至美西螈启动器……那为什么还要自己写一个？&lt;/p&gt;
&lt;p&gt;原因很简单——&lt;strong&gt;我想要一个真正模块化的启动器&lt;/strong&gt;。不是那种&amp;quot;支持插件&amp;quot;但核心代码拧成一团的，而是从底层架构就允许每个功能被独立替换、独立扩展的。&lt;del&gt;另外我也想用 .NET 10 + Avalonia UI 写点真正能用的东西，而不是整天写 CRUD（笑）。&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;于是就写了 BlockyLauncher。&lt;/p&gt;
&lt;h1 id="整体架构"&gt;整体架构&lt;/h1&gt;
&lt;p&gt;BlockyLauncher 分成五层：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;BlockyLauncher.Abstractions # 纯接口层
BlockyLauncher.PluginSDK # 插件开发 SDK
BlockyLauncher.Framework # 框架核心实现
BlockyLauncher.Desktop # Avalonia 桌面入口
BlockyLauncher.Plugins.BuiltIn # 6 个内置插件
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;有趣的地方在于，「内置」插件其实走的是和第三方插件完全一样的加载通道。它们在 &lt;code&gt;.csproj&lt;/code&gt; 里用 &lt;code&gt;Private=&amp;quot;false&amp;quot; ReferenceOutputAssembly=&amp;quot;false&amp;quot;&lt;/code&gt; 引用，编译时不链接，运行时从 &lt;code&gt;builtin/&lt;/code&gt; 目录动态加载。也就是说，启动器的核心功能和第三方开发者将来写的一个插件，在框架眼里是没有区别的。&lt;del&gt;其实这里是在致敬 &lt;a href="https://koishi.chat"&gt;Koishi&lt;/a&gt;。&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;这意味着什么？&lt;/p&gt;
&lt;p&gt;这个这意味着启动器的核心跟 Minecraft 是完全解耦的！甚至创建 Minecraft 游戏实例、启动 Minecraft 游戏、管理 JVM 等等启动器的核心功能，都只是插件，只不过是预装的而已。你未来大可以写一个 Minecraft Server 启动器插件、Touhou 启动器插件，甚至 PS 主机游戏启动插件，并且可以将你自己的插件分发，其他人只需在“设置”里动动鼠标即可一键安装。&lt;/p&gt;
&lt;h1 id="插件怎么工作"&gt;插件怎么工作&lt;/h1&gt;
&lt;p&gt;每个插件实现 &lt;code&gt;IPlugin&lt;/code&gt; 接口的三个方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; Id { &lt;span style="color:#66d9ef"&gt;get&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Task InitializeAsync(IPluginContext context);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Task OnServicesReadyAsync(IServiceProvider services);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Task ShutdownAsync();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;InitializeAsync&lt;/strong&gt; 里注册视图、服务、设置页面，这时候你只能用自己的东西&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnServicesReadyAsync&lt;/strong&gt; 时所有服务都就位了，可以获取其他插件注册的服务来协作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ShutdownAsync&lt;/strong&gt; &lt;del&gt;收尸&lt;/del&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;插件通过 &lt;code&gt;IPluginContext&lt;/code&gt; 接触到框架提供的一切能力，包括但不限于注册导航页面、注册设置页面、发布/订阅事件、注册自己的服务给别人用。配合 &lt;code&gt;manifest.json&lt;/code&gt; 描述元信息：&lt;/p&gt;</description></item></channel></rss>