Skip to content
MOD 开发 · 游戏方块图集与加载器图标

C# / DLL 插件开发

当数据文件无法表达新的行为、界面或系统时,需要编写 C# 代码并随 .scmod 一起构建。最重要的不是复制某个示例类,而是让 SDK、NuGet 依赖和 API 分支完全一致。

开发环境

当前 API 1.9 模板使用 .NET 10 SDK 和 NuGet 包。实际安装时:

  1. 安装 .NET 10 SDK
  2. 克隆 API 1.9 示例模板
  3. 保留模板的 nuget.config 并执行 dotnet restore
  4. 不要引用另一个游戏版本目录中的同名 DLL;
  5. 把 API 包版本和模板提交写入项目说明。

旧教程需要隔离

历史教程使用过 .NET Framework 4.5、4.7.2 等环境,仅适用于对应旧分支。当前 API 1.9 以仓库模板声明的 .NET 10 SDK 为准,不要混合依赖。

建立最小项目

建议先让空插件完成“编译—加载—输出一条可确认信息”的闭环,再加入方块或组件。项目结构可以这样组织:

text
MyMod/
├─ MyMod.csproj
├─ src/
│  ├─ Entry.cs
│  ├─ Blocks/
│  ├─ Components/
│  └─ Subsystems/
├─ content/
└─ README.md

具体入口、初始化方法和注册方式从目标 API 示例项目取得。先完成项目搭建,再阅读源码。

增加方块或物品

一个新内容通常不只是一段 C# 类,还涉及多处一致性:

text
代码中的类型与行为

方块数据中的标识与属性

配方中的名称和产物

纹理或模型资源

API 加载清单 / 封装信息

任何一层名称不一致,都可能表现为缺失纹理、配方无效、类型找不到或世界加载失败。

组件与子系统

  • 组件(Component) 通常描述附着在实体上的一部分状态或行为。
  • 子系统(Subsystem) 通常管理世界范围的服务、数据或更新逻辑。
  • 覆盖加载、保存、实体加入与移除等生命周期时,要调用或保留目标 API 要求的基础行为。
  • 每帧更新代码中避免文件 IO、网络请求、大量分配和无边界遍历。

修改既有逻辑

直接复制并替换原有类虽然能快速验证想法,但维护成本很高。优先顺序应是:

  1. 使用 API 提供的事件或扩展点;
  2. 继承可扩展类型并只覆盖必要方法;
  3. 用独立组件或子系统组合行为;
  4. 只有目标 API 没有扩展点时,才考虑替换核心逻辑,并记录被替换的原始版本。

调试编译错误

错误类型优先检查
类型或命名空间不存在引用程序集、API 分支、using 与类型是否已改名
程序集无法加载目标框架、CPU 架构、依赖 DLL 与加载目录
编译成功但插件不出现入口类型、访问级别、加载清单与日志
进入世界后崩溃数据标识、生命周期顺序、空引用与旧存档兼容
性能持续下降每帧逻辑、事件重复注册、未释放集合与资源

参考资料

玩家共建文档 · 原版、插件版、联机版与插件联机版请注意区分