Skip to content

验证环境

本页内容已按 Build 740622 对应的本机 Managed DLL 和项目配置检查;尚未在游戏内完成运行验证。

游戏源码分析工具

想真正理解《缺氧》的行为逻辑,光看教程不够,还是得回到游戏源码本身。 这一步通常会从反编译 Assembly-CSharp.dll 开始,因为大多数建筑、实体、AI、UI 和系统逻辑都藏在这里。

这一章主要讲两件事:

  1. 你该用什么工具来看源码
  2. 你该怎么从源码里提取出可用于 Harmony Patch 的信息

一、先认识目标文件

《缺氧》的主要逻辑程序集通常位于:

text
OxygenNotIncluded_Data/Managed/Assembly-CSharp.dll

你在 dnSpy 里最常看的,也基本就是这个文件。 如果你想研究某个系统是否有别的依赖,通常还会顺手看这些程序集:

  • Assembly-CSharp-firstpass.dll
  • 0Harmony.dll
  • UnityEngine.dll
  • UnityEngine.CoreModule.dll

但真正决定游戏行为的大部分入口,还是 Assembly-CSharp.dll


二、为什么选 dnSpy

dnSpy 是《缺氧》Mod 圈里最常用的反编译工具之一,因为它同时能做三件事:

  • 查看 C# 反编译结果
  • 搜索类名、方法名、字符串
  • 直接导出项目或做基础修改

对于 ONI 来说,它最实用的地方不是“能改源码”,而是“能帮你快速找到 Patch 点”。

适合做什么

  • 找某个建筑配置类,比如 ElectrolyzerConfig
  • 找某个方法名,比如 CreateBuildingDef
  • 看某个方法到底调用了什么
  • 判断一个逻辑是在 PrefixPostfix 还是 Transpiler 更适合处理

不适合把它当成什么

  • 不是完整的项目管理工具
  • 不是 IDE
  • 不是 Mod 编译环境

它更像一个“源码放大镜”。


三、安装和打开

1. 下载

建议直接下载 Release 版本,不需要自己编译。

2. 打开游戏程序集

  1. 进入游戏目录
  2. 找到 OxygenNotIncluded_Data/Managed/Assembly-CSharp.dll
  3. 把它拖进 dnSpy,或者用 File -> Open

打开后,你会看到左侧是一棵程序集树,里面展开的就是命名空间、类、方法和字段。


四、怎么在 dnSpy 里找东西

1. 按类名找

如果你已经知道目标类的名字,这是最快的方式。

例如:

  • ElectrolyzerConfig
  • GeneratedBuildings
  • Db
  • BuildingDef

可以直接搜索类名,然后展开看内部方法。

2. 按方法名找

如果你只知道行为,不知道类名,可以直接搜方法名。

例如:

  • CreateBuildingDef
  • OnSpawn
  • ConfigureBuildingTemplate
  • LoadGeneratedBuildings

这类方法经常就是 Mod 的入口。

3. 按字符串找

如果你记得游戏里出现过某句文本,也可以用字符串倒推代码。

例如:

  • 某个建筑名称
  • 某个日志文本
  • 某个错误提示

这种方式有时候比类名搜索更快,因为你会先找到“被调用的地方”,再回头找类和方法。

4. 按调用关系找

如果你已经找到一个方法,想知道它是从哪儿被调用的,可以看:

  • References
  • Analyze
  • 调用链

这对理解“这个函数什么时候跑”的帮助很大。


五、怎么看 ONI 的源码

ONI 的代码读法,和普通 C# 项目有点像,但也有自己的习惯。

1. 先看类名

类名通常会告诉你这个东西是什么。

例如:

  • ElectrolyzerConfig 通常是电解器配置
  • BuildingDef 通常是建筑定义
  • GeneratedBuildings 常和建筑注册有关

如果类名看起来像 ConfigDefManagerStateMachine,通常都值得多看一眼。

2. 再看方法名

方法名通常比类名更关键,因为真正的逻辑往往藏在方法里。

在 ONI 里很常见的几类方法有:

  • CreateBuildingDef
  • ConfigureBuildingTemplate
  • OnSpawn
  • OnPrefabInit
  • LoadGeneratedBuildings

这些方法里,前两个通常和“定义”有关,后两个通常和“实例行为”有关。

3. 最后看参数和返回值

参数和返回值能帮你判断这个方法是:

  • 只是设置数据
  • 还是会改状态
  • 还是会返回一个新对象

例如:

  • void:很多时候是初始化、注册、附加逻辑
  • bool:常用于是否允许执行
  • BuildingDef:通常是构造或修改建筑定义
  • GameObject:通常和预制体、实体生成有关

六、从源码里提取 Patch 信息

这是 dnSpy 对 ONI Mod 开发最有价值的部分。

你最终想提取出来的,一般是这三样:

  1. 类名
  2. 方法名
  3. 参数类型

例子 1:普通方法

源码大概长这样:

csharp
public static void LoadGeneratedBuildings()

可提取的 Patch 信息:

csharp
[HarmonyPatch(typeof(GeneratedBuildings), "LoadGeneratedBuildings")]

例子 2:带参数的方法

源码大概长这样:

csharp
public void SetActive(bool value)

如果你只写方法名,遇到重载时就可能出问题。 这时候就要把参数类型也带上。

例子 3:属性

如果你看到的是属性,不是普通方法,要注意 Getter / Setter

例如:

csharp
public bool IsSolid { get; }

这种情况就不是简单搜方法名了,而是按属性处理。


七、一个典型的读源码流程

你可以按这个顺序来:

  1. 在游戏里确认你想改的对象
  2. 在 dnSpy 里找这个对象对应的类
  3. Create...OnSpawnConfigure... 之类的方法
  4. 看方法内部调用了哪些东西
  5. 找出最适合下手的位置
  6. 再回到 Harmony 里写 Patch

如果你只是为了“改个数值”,很多时候不用深挖整个类。 但如果你要改流程、改条件判断、改调用顺序,就一定要把上下文看完整。


八、常见坑

1. 只看到了表面代码

dnSpy 反编译出来的是可读 C#,但不等于原始源码。 有些结构是反编译器“尽量还原”的,真正逻辑要结合调用关系一起看。

2. 忽略重载

同名方法很多时候不止一个。 如果不看参数类型,你很容易 Patch 错目标。

3. 把静态方法和实例方法混了

静态方法和实例方法在 Patch 写法上有时会有差别,尤其是参数和上下文读取方式。

4. 只看一次就急着写补丁

最好先看三层:

  • 这个方法做什么
  • 它被谁调用
  • 它的返回值会不会影响后续逻辑

这样写出来的 Patch 会稳很多。


九、和 Harmony 的配合方式

dnSpy 的任务,是帮你把 Patch 目标找准。 Harmony 的任务,是帮你把修改干净地挂上去。

一般来说:

  • dnSpy 用来确认类、方法、参数
  • Harmony 用来执行 Prefix / Postfix / Transpiler

如果你已经在 C# 基础 里熟悉了 namespaceclassref 这些概念,再结合这里的源码分析,你就能比较顺地从“看懂”走到“改动”。


十、下一步

如果你已经会打开程序集、搜索类名、找到方法入口了,下一步就可以去看:

这两篇会把你从“找到源码”带到“真正开始写补丁”。