Skip to content

GameData 公式字段赋值位置 ​

需要在图形化编辑器中编写公式时,可在函数字段选择或新建触发器函数;JSON 保存函数引用,不保存 C# lambda。常量、函数引用和纯代码路线,以及未知 JSON 辅助字段与生成失败的区别,见从配置到运行证据。

本文说明纯代码定义 GameData 时,公式字段应该写在双端共享代码里,还是放进 #if SERVER / #if CLIENT。

数据编辑器和触发编辑器会自动处理大多数场景;这条规则主要面向手写 C# GameData 的开发者和 AI 助手。

默认决策 ​

按下面顺序判断:

  1. 先看字段是否存在于当前端 API。只存在于 docs/api/server/ 的字段必须在 #if SERVER 中赋值;只存在于 docs/api/client/ 的字段必须在 #if CLIENT 中赋值。
  2. 再看公式偏向。[DataEditor(FunctionBias = FunctionBias.Server)] 表示服务端公式偏向,不表示字段本身一定是服务端专属。这类字段默认推荐只在 #if SERVER 中赋值。FunctionBias.Client 同理默认放在 #if CLIENT。
  3. 最后看客户端是否需要读这个值。如果客户端 UI、预览或表现确实要读取同一个公式字段,并且公式只使用双端共有 API 或常量,可以写成双端共享公式。
  4. 不要把所有 GameData 都无脑包进 #if SERVER。表现、Actor、UI、单位显示数据、客户端可见的技能展示数据仍然需要客户端定义。

优先查 docs/api/client/ 和 docs/api/server/ 中的字段是否存在,并阅读字段 XML 注释。带有服务端公式偏向的字段会直接在 API 注释中说明“默认可只在 #if SERVER 中赋值,但字段不因此变成服务端专属”。Schema 中的 x-platform-availability / x-function-bias 只是机器可读补充,不是理解这条规则的必读入口。

服务端专属字段 ​

如果字段只在服务端 API 中出现,就必须放进 #if SERVER。例如 AI 思维树运行时对象 AIThinkTree 只存在于服务端,因此参数包含 AIThinkTree 的公式通常都是服务端专属。

csharp
_ = new GameDataAINodeValidateScan(MyLinks.ScanTarget)
{
    IgnoreLeash = true,
#if SERVER
    Range = static thinkTree => thinkTree.ScanRange + 200,
#endif
};

GameDataAINodeValidateScan.Range 在客户端 API 中不存在;不加 #if SERVER 会导致客户端编译失败。

服务端公式偏向字段 ​

很多 GameDataEffectXXX 节点的字段在双端 API 中都存在,但效果树实际只在服务端执行。带有 [DataEditor(FunctionBias = FunctionBias.Server)] 的公式字段默认可以只在服务端赋值。

csharp
_ = new GameDataEffectUnitModifyLevel(MyLinks.ModifyLevel)
{
    Operation = PropertyModificationOperation.Add,
#if SERVER
    Amount = static ctx =>
        Math.Max(1, (int)((ctx.Caster.GetUnitPropertyFinal(GSC.GameDataUnitProperty.AttackDamage) ?? 100) / 100)),
#endif
};

客户端仍然能看到这个字段的默认值或数据结构,但不会运行服务端效果逻辑。把复杂效果公式放在 #if SERVER 中,可以直接使用服务端 API,避免为了双端兼容而牺牲表达力。

双端共享公式 ​

如果字段会被客户端读取来显示 UI、预览技能数据或做表现,并且公式只依赖常量或双端共有 API,可以写成共享公式。

csharp
_ = new GameDataAbilityExecute(MyLinks.Fireball)
{
    DisplayName = "火球",
    Range = static (_) => 500,
};

技能施法距离是典型例子:核心判定通常在服务端,但客户端可能读取同一字段显示技能说明或范围提示。此时共享常量或共享 API 公式是合理的。

AI 助手规则 ​

生成或修改 GameData 代码时,AI 应优先使用下面的简化规则:

  • 字段只在一端 API 中存在:只在对应 #if 中赋值。
  • FunctionBias.Server:默认只在 #if SERVER 中赋值,除非客户端明确需要读这个字段且公式双端兼容。
  • FunctionBias.Client:默认只在 #if CLIENT 中赋值。
  • 常量公式和双端共有 API 公式可以共享,但不要为了共享而调用不存在于另一端的 API。
  • GameDataEffectXXX 的效果公式默认按服务端公式处理。