外观
C# / DLL 插件开发
当数据文件无法表达新的行为、界面或系统时,需要编写 C# 代码并随 .scmod 一起构建。最重要的不是复制某个示例类,而是让 SDK、NuGet 依赖和 API 分支完全一致。
开发环境
当前 API 1.9 模板使用 .NET 10 SDK 和 NuGet 包。实际安装时:
- 安装 .NET 10 SDK;
- 克隆 API 1.9 示例模板;
- 保留模板的
nuget.config并执行dotnet restore; - 不要引用另一个游戏版本目录中的同名 DLL;
- 把 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、网络请求、大量分配和无边界遍历。
修改既有逻辑
直接复制并替换原有类虽然能快速验证想法,但维护成本很高。优先顺序应是:
- 使用 API 提供的事件或扩展点;
- 继承可扩展类型并只覆盖必要方法;
- 用独立组件或子系统组合行为;
- 只有目标 API 没有扩展点时,才考虑替换核心逻辑,并记录被替换的原始版本。
调试编译错误
| 错误类型 | 优先检查 |
|---|---|
| 类型或命名空间不存在 | 引用程序集、API 分支、using 与类型是否已改名 |
| 程序集无法加载 | 目标框架、CPU 架构、依赖 DLL 与加载目录 |
| 编译成功但插件不出现 | 入口类型、访问级别、加载清单与日志 |
| 进入世界后崩溃 | 数据标识、生命周期顺序、空引用与旧存档兼容 |
| 性能持续下降 | 每帧逻辑、事件重复注册、未释放集合与资源 |
