Skip to content

元素深度教程

基础元素教程里已经能注册一个固体元素。进阶时真正麻烦的是三件事:物性、材质、相变。元素一旦进入模拟层,写错数值不只是显示问题,还可能影响热量、管道、建筑材料和存档。

这一章继续沿用 AuroraCrystal,讲怎么把它写得更像游戏里的正式元素。

先定状态

元素有三类常见状态:

  • Solid:最适合入门,可以做矿物、建筑材料、掉落物。
  • Liquid:要考虑流动、管道颜色、凝固和汽化。
  • Gas:要考虑扩散、吸入、管道和气压。

建议先把固体跑通,再扩展液体和气体。固体失败通常只是看不见或不能生成;液体气体失败时,可能会在模拟层刷日志。

物性字段

elements/custom_elements.yaml 里最常改的是这些:

yaml
elementId: AuroraCrystal
state: Solid
specificHeatCapacity: 0.5
thermalConductivity: 1.2
defaultTemperature: 290
defaultMass: 200
maxMass: 500
hardness: 20
highTemp: 1200
highTempTransitionTarget: Magma
materialCategory: BuildableRaw
tags:
- BuildableRaw

常用理解:

  • specificHeatCapacity:比热容,越高越难升温降温。
  • thermalConductivity:导热率,越高越容易传热。
  • highTemp / lowTemp:相变温度。
  • highTempTransitionTarget / lowTempTransitionTarget:相变目标。
  • materialCategory:材料分类,影响建筑材料筛选。
  • tags:游戏系统识别它的方式,储存、配方、建筑都会用。

不要一开始就把数值写得很极端。先抄一个接近用途的原版元素,再改 20% 左右测试。

材料分类

如果元素要当建筑材料,materialCategorytags 都要对。

yaml
materialCategory: BuildableRaw
tags:
- BuildableRaw

常见分类:

  • BuildableRaw:普通原材料。
  • Metal:金属矿石。
  • RefinedMetal:精炼金属。
  • ConsumableOre:可消耗矿物。
  • Filter:过滤介质。

如果建筑菜单里看不到这个材料,先检查分类,再检查元素实体是否已经注册成矿物。

相变链

固体变液体可以这样写:

yaml
highTemp: 900
highTempTransitionTarget: MoltenAuroraCrystal

然后再注册一个液体元素:

yaml
- elementId: MoltenAuroraCrystal
  state: Liquid
  defaultTemperature: 920
  lowTemp: 880
  lowTempTransitionTarget: AuroraCrystal
  highTemp: 1600
  highTempTransitionTarget: AuroraCrystalGas

相变目标必须存在。目标元素没注册,游戏加载时就会报错,或者进入世界后出现无法解析的元素。

Substance 补丁

yaml 只解决物性,显示还要补 Substance。固体可以先复用原版材质:

csharp
[HarmonyPatch(typeof(Assets), "SubstanceListHookup")]
public static class AuroraCrystalSubstancePatch
{
    public static void Postfix()
    {
        Element element = ElementLoader.FindElementByHash(ModElements.AuroraCrystal);
        Substance source = Assets.instance.substanceTable.GetSubstance(SimHashes.Granite);

        Material material = new Material(source.material)
        {
            name = "matAuroraCrystal"
        };

        Color32 color = new Color32(102, 220, 255, 255);
        element.substance.material = material;
        element.substance.anim = source.anim;
        element.substance.colour = color;
        element.substance.uiColour = color;
        element.substance.conduitColour = color;
    }
}

液体和气体也可以复用原版 Substance,再改颜色。先不要急着自己写 shader。

自定义贴图

贴图建议放在:

text
assets/
└── textures/
    └── AuroraCrystal.png

读取后赋给材质:

csharp
Texture2D texture = LoadTexture("AuroraCrystal.png");
if (texture != null)
{
    material.mainTexture = texture;
}

贴图失败时,不要让整个元素注册中断。记录警告,然后继续用原版材质,至少能进游戏测试物性。

生成到世界

元素注册完成后,想要在新地图里自然出现,还需要接世界生成系统。这部分涉及 feature、subworld、world 三层 yaml 结构和 biome 地层配置。

详见独立教程:世界生成

检查清单

  • yaml 文件是否被复制到 Mod 输出目录。
  • elementId 是否和 Hash.SDBMLower() 用的 ID 一致。
  • 相变目标是否全部存在。
  • materialCategorytags 是否匹配用途。
  • SubstanceListHookup 里是否能找到元素和参考物质。
  • 固体是否有 IOreConfig,否则它可能有元素但没有可掉落实体。
  • worldgen 文件路径是否和引用路径一致,比如 features/rift/MyCrystalPocket
  • 新元素是否出现在 feature、biome 或模板里,且对应 world 能选到它。