Skip to content

星火 1.0 → 2.0 迁移参考(reference) ​

本文件是 migrate-1to2/SKILL.md 的详细版:1.0 工程解剖、如何读 1.0 的 API、三张映射表、分系统迁移配方、手补清单、校验。

> 准确性提醒:1.0 与 2.0 可比拟但有差异。本文标注「需确认」的地方,请用工程内 lua_declare.d.ts、SDK 的 schemas/types/、api/ 实际核对,不要凭印象编造类型名/字段名。


一、1.0 工程解剖 ​

典型 1.0 工程根目录(以一个 ts2lua 模板工程为例):

text
<1.0 项目根>/
├── editor/                 # ★ 数据编辑器 + 触发器编辑器的"配置"(source of truth)
│   └── table/
│       ├── entry_data/     # ★ 数据编辑器各类型条目(.ini)
│       │   ├── unit/  buff/  spell/  effect/  actor/  item/  model/  ...
│       │   ├── camera_property/  loot/  link_node/  map_config/
│       │   ├── template@buff/  template@effect/  template@gui_ctrl/   # 模板(继承根)
│       │   ├── const_config.ini   # ★ 常量 / 可附加枚举 / 单位属性 / 伤害类型
│       │   └── ui_data.ini         # UI 数据
│       ├── package_info.ini
│       └── save_info.json
├── script/                 # ★ 服务端:ts2lua 生成的逻辑代码
│   ├── trigger_module_main_*.ts(.lua)   # ★ 触发器编辑器生成的逻辑
│   ├── trigger_validator*.ts(.lua)       # ★ 数编公式值生成的公式/校验函数
│   ├── lua_declare.d.ts                  # ★ 1.0 API + 本项目 _OBJ_ 自定义数编类型
│   ├── obj/                              # 数编配置生成的数据(lua)
│   ├── scene/                            # 场景相关生成代码
│   └── tsconfig.json                     # typeRoots 指向编辑器 Update 的基础声明
├── ui/
│   ├── script/             # ★ 客户端:结构同 script/(自己的 trigger_module_main / validator / lua_declare)
│   ├── image/  src/  gui/
├── scene/                  # ★ 地形/场景资产 + 预放置(见 4.4)
│   ├── .sceneconfig
│   └── <场景名>/  heightdata.dat  collision.dat  sight.dat  map.acmap  map.scene_items
│                  config.lua  area_save.lua  unit_save.lua  group_nest.json  sortinfo.json
├── table/  res/  block/  atmosphere/  lightmap/  game_hud/  i18n/  ref/
├── libs.json               # 依赖的脚本库(script_libs)
├── config.ini  project.sce

要点 ​

  • editor/ = 配置(1.0 是 .ini,2.0 是 editor/data/*.json)。script/ 与 ui/script/ = 配置 + 触发器生成出来的代码。 2.0 没有 script/ui\script 这两个文件夹——代码全在 src/,双端共通,用 #if SERVER/#if CLIENT 区分单端逻辑。
  • 服务端 = script/,客户端 = ui/script/。 两边各有一份 trigger_module_main*、trigger_validator*、lua_declare.d.ts。迁移时合并到 2.0 同一份 src/ 代码 + #if。
  • 有同名 TS 时优先读 TS。 同时检查独立手写 TS 模块及其初始化/导入链;可只读 main.lua 的 require 查漏。没有 TS 对应的手写 Lua、场景 Lua 表和 UI 配置仍是需要解读的源工件。
  • script/obj/**、ui/script/obj/** 是数编配置生成的 Lua 数据,不直接搬到 2.0;数据迁移以 editor/table/entry_data/*.ini 或明确选择的代码化路线为基准。INI 可能只保存本地覆盖;默认值、模板继承或服务端/客户端表现配置不明确时,只读对照相应生成 Lua,记录有效值及来源。生成 Lua 也需核对与当前 INI 是否一致,不能把过时产物直接当作权威配置。
  • 重复构建产物忽略:已确认有 TS 对应的生成 .lua、*.lua.map、*.diagnostic、*_debug_infos.json、tstl.log,不按 .lua 后缀排除全部文件。
  • libs.json 列出该项目依赖的 1.0 脚本库。这些库在 2.0 多半有对应官方库/能力,但不保证一一对应,属于手补评估项。
  • 其它配置:1.0 工程根目录 table/ 下可能还有 constant.ini(常量)、mapinfo.ini、floatingtexttemplate.json / riseletter.json(浮动文本/飘字模板)等;game_hud/ 下可能有小地图(minimap*)等表现资源。按需迁移到 2.0 对应的数据/表现配置(飘字见伤害/表现相关配置;小地图见下「已知不支持」——建议用 Canvas 直接绘制)。

二、如何读 1.0 的 API ​

1.0 没有 2.0 那样完善的 docs,但有两处声明可"望文生义",都在用户本机:

2.1 工程内的 lua_declare.d.ts(自定义类型) ​

script/lua_declare.d.ts(服务端)与 ui/script/lua_declare.d.ts(客户端)含:

  • 基础枚举(项目用到的常量枚举,如单位属性、Buff 分类等);
  • 本项目的自定义数编类型声明,通常以 _OBJ_ / _OBJ__ 开头,例如:
typescript
declare const enum 单位属性 { ["弹道半径"]="弹道半径", ["金币"]="金币", ... }

declare class _OBJ_xxx_yyy extends _OBJ__base_type {
    SomeField: number;
    ...
}

> 1.0 的自定义数编类型是单独定义后插入触发器类型;2.0 反过来——数编类型以触发器/代码类型为准。但 lua_declare.d.ts 里这些 _OBJ_* 仍是你了解"这个项目自定义了哪些数编字段"的最佳入口。

2.2 基础官方 API(tsconfig.json → 编辑器 Update 目录) ​

读工程的 tsconfig.json,其 typeRoots / types 指向用户本机 1.0 编辑器 Update 目录下的基础声明。服务端与客户端路径不同(服务端在 script/,客户端在 ui/script/):

text
服务端: <编辑器 Update 目录>/Res/_m/maps/global_default/<版本>/global_default/script/lua_declare.d.ts
客户端: <编辑器 Update 目录>/Res/_m/maps/global_default/<版本>/global_default/ui/script/lua_declare.d.ts

这是 1.0 官方 API 的总声明,类比 2.0 的 API 参考(以及 SDK 根目录 schemas/types/ 的字段 schema),只是没那么完善。查 1.0 的类型/字段时以它为准。

2.3 对照 2.0 的 API ​

2.0 这边查类型/字段用:schemas/types/GameData*.json(字段 schema)、api/client/ + api/server/(C# 声明 + XML 注释)、docs/systems/*.md(系统说明)。把 1.0 的 _OBJ_ 字段逐个在 2.0 对应 GameData<Type> 里找落点。

区分 C# API 类型形状、数编源 JSON 形状与编辑器元数据;运行时 schema 不一定包含全部作者字段。写入格式以数据编辑器模板/MCP 元数据与实际保存样例核对,再通过生成投影和运行值验证,不能只按 C# 成员名拼 JSON。


三、三张映射表 ​

3.1 目录映射 ​

1.02.0说明
editor/table/entry_data/<type>/*.inieditor/data/<Scope>/GameData<Type>/<name>.json数据编辑器配置;类型名变(见 3.2)
script/(服务端)+ ui/script/(客户端)src/(单源,双端共通)单端逻辑用 #if SERVER / #if CLIENT
script|ui/script/trigger_module_main*.tssrc/ 中的 C# 触发器代码见 4.2
script|ui/script/trigger_validator*.ts数据字段引用的触发器函数 / C# 委托见 4.3
script|ui/script/lua_declare.d.ts生成的 src/DataGenerated/ScopeData.cs(强类型 GameLink<T>)2.0 由数编 JSON / 代码生成
script|ui/script/obj/**无(不直接迁)1.0 数编生成的 lua 数据
tsconfig.jsonsrc/*.csproj构建配置
scene/<名>/(资产 + lua 预放置)scene/<名>/(资产可直接复制)+ GameDataScene(场景信息/预放置)见 4.4
table/mapinfo.ini(旧称 map.info,文件名可能不同,如有)GameDataGameplay + GameDataScene见 3.3

3.2 GameData 官方类型名映射 ​

1.0 官方数编类型与 2.0 可比拟,但名称不同(2.0 统一加 GameData 前缀,以区别于真正的运行时对象类型如 Unit/Ability)。字段大致可比拟,但有细节差异。

1.0(entry_data/ 目录名)2.0 类型示例命名空间(以 api/、schemas/ 实际为准)
unitGameDataUnitGameCore.EntitySystem.Data
spellGameDataAbilityGameCore.AbilitySystem.Data
effectGameDataEffect*(多子类型:GameDataEffectDamage / GameDataEffectSearch / GameDataEffectUnitModifyUnitProperty …)GameCore.Execution.Data
buffGameDataBuffGameCore.BuffSystem.Data
actorGameDataActor(及 GameDataActorModel 等子类型)GameCore.ActorSystem.Data
itemGameDataItemGameCore.ItemSystem.Data
modelGameDataModel—
unit_level_profile(嵌在 unit 内的子节点)GameDataUnitLeveling见 4.1「嵌套子节点」
camera_property2.0 镜头相关 GameData需确认:在 schemas/types/ 搜镜头类型名
loot2.0 掉落/奖励相关(如 GameDataReward*)需确认
link_nodeGameDataControl*(UI 控件)GameUI 体系,见 4.7
map_config / table/map.infoGameDataGameplay + GameDataScene见 3.3
const_config(常量)可扩展枚举 + GameDataUnitProperty + GameDataDamageType见 3.3、4.5
template@*2.0 数编继承($inherit / 根节点继承)见 4.1

注意字段级差异:例如 1.0 把技能动画直接填在技能表里,2.0 的技能动画可指向单独的 GameDataAnimation 节点(见 4.6)。逐字段务必对照 2.0 schema/api 落点,别假设字段名一致。

3.3 概念映射(重设计的机制) ​

1.0 概念2.0 落点关键差异
可附加枚举(const_config 里配置)可扩展枚举(EnumExtension),扩展到整个枚举类型级别在代码或触发器里扩展;扩展枚举名以 E 开头、生成时去掉 E 前缀。见 EnumExtension、02-高级功能
可附加枚举里的单位属性独立数据类型 GameDataUnitProperty过去 Gameplay 表里"针对单位属性的可附加枚举公式系统",现内化为 GameDataUnitProperty 自身的属性字段。见 UnitPropertySystem
伤害类型GameDataDamageType从可扩展枚举变成独立数据类型,公式在自己表里定义,不再全塞进 gameplay 表
table/map.infoGameDataGameplay + GameDataScene关键值内化;部分原全局配置改为按场景区分(如寻路模式、视野模式等)
数编公式值 = 内嵌触发器 json 到 ini数据字段直接引用触发器函数 / C# 委托1.0 繁琐冗长;2.0 简洁,见 4.3
客户端/服务端两个文件夹同一份 src/ + #if CLIENT/#if SERVER提倡双端共通代码

四、分系统迁移配方 ​

> 决策树:先沿用用户确认的作者路线。允许普通 C# 时,逻辑/触发器/公式优先代码化;明确要求可视化维护时,用 trigger-editor-mcp 保留可编辑结构。数据需数编维护时用 data-editor;允许纯代码定义时可按复杂度权衡。token 成本不能替代可维护性和保真度要求。

4.1 数据编辑器 ​

1.0 长这样:editor/table/entry_data/unit/<名>/entry_data.ini,Lua 表语法,NodeType='$$.unit.Unit',字段含中文键、可能内嵌 IsFunc/LuaCode/Func 公式串。

2.0 怎么写:

  • 路径 → editor/data/<Scope>/GameData<Type>/<名>.json,$type 指向 2.0 类型(如 GameCore.EntitySystem.Data.GameDataUnit),引用其它数编用 $<Link>.Root 形式。用 data-editor 处理 $id / $inherit / link 路径与保存边界。
  • 自定义类型且继续使用图形化编辑器:在触发编辑器 Class 的属性面板选择“设置为数编分类/类型”,保存并生成代码后,再回数据编辑器创建条目。
  • 或明确选择纯代码化:用 [GameDataNodeType<T,V>] + partial class 定义类型、用 new GameData...(link){ ... } 写条目(见 GameData 系统)。
  • 1.0 的 template@* → 2.0 用数编继承($inherit 或以某根类型为父)表达。

坑:类型名变(3.2);字段不一一对应,逐字段对 schema/api 找落点;技能动画拆到 GameDataAnimation(4.6)。

首次写入一种节点前,用目标编辑器的 gamedata_list_types / gamedata_get_type_schema 确认完整 $type、是否可实例化及引用目标类型;无对应 MCP 时查目标 SDK schema/API 和实际保存样例。保存后全量生成,检查结构化诊断与实际赋值,按 quality-gates.md 4.4 处理 GDATA001。能通过 C# 编译不代表字段没有在生成时被省略。

嵌套子节点:1.0 的 ini 条目常含嵌套子节点(如 unit 内的 Unit_Level_Profile、技能内的多个效果节点),每个子节点都有自己的 NodeType。逐个把 NodeType 值在 2.0 schemas/types/ 里找对应 GameData*(例如 $$.unit_level_profile.* → GameDataUnitLeveling、$$.effect.* → GameDataEffect*),别只迁顶层节点。

技能/普攻:2.0 主动技能用 Time.NormalizedDuration 字段(主动技能基类 GameDataAbilityActive 上,见 GameDataAbilityExecute 等)直接控制最小攻击间隔/普攻节奏,不必像 1.0 那样写复杂公式同时操作四阶段时间与冷却。见 AbilitySystem 与 3d-unit-game 的普攻配置。

4.2 触发器 ​

1.0 长这样:script/trigger_module_main_*.ts 里用 base.trigger_new(callback, ...) 注册;事件转发、初始化逻辑等。客户端版在 ui/script/。

2.0 怎么写:

csharp
// 一行式订阅(推荐)
var t = Game.Subscribe<EventEntityDeath>(async (sender, e) =>
{
    Game.Logger.LogInformation("单位 {Name} 死亡", e.Entity.Name);
});

// 或标准式
var trigger = new Trigger<MyEvent>(OnMyEvent);
trigger.Register(Game.Instance);   // 也可 Register(unit) / Register(unitData)
  • 事件可注册到 Game.Instance(全局)/ 实体 / 数编表对象(数据类型级)。
  • 客户端专属逻辑包 #if CLIENT,服务端专属包 #if SERVER。
  • 框架约定:用 Game.Delay() 不用 Task.Delay();不要用 Task.Run(),也不要使用 TaskCreationOptions.RunContinuationsAsynchronously;日志用 Game.Logger(结构化),不用 Console.WriteLine、不用字符串内插。
  • 详见 TriggerSystem、01-核心差异;用 MCP 操作触发器见 trigger-editor-mcp。

4.3 公式值与 Validator ​

1.0 长这样:数编 ini 里公式值是内嵌的触发器 json;生成到 script\|ui/script/trigger_validator*.ts,形如 export let validator_xxx = (...) => { ... }。

2.0 怎么写:数据字段直接是触发器函数 / C# 委托:

csharp
new GameDataBuff(buffLink)
{
    Modifications = [
        new () {
            Property = ScopeData.UnitProperty.LifeMax,
            Value = (context) => context.Target.GetUnitPropertyFinal(ScopeData.UnitProperty.Strength) * 2,
        }
    ],
};
  • #if 放置规则必须遵守 GameDataFormulaPlacement:字段只在一端 API 存在就只在对应 #if 赋值;FunctionBias.Server 默认放 #if SERVER;GameDataEffectXXX 的效果公式默认按服务端处理;常量/双端共有 API 的公式可双端共享。
  • 公式参数是 IExecutionContext(可取施法者/目标)或具体上下文(如响应节点的 ResponseContextDamage),不再是 1.0 的效果节点参数。见 02-高级功能·通用公式。
  • 1.0 技能公式历史遗留:1.0 技能节点里一些本该支持公式的字段只能填数值,要勾选"使用数值公式"再到单独的"数值公式"字段填公式。2.0 的技能/物品/Buff 在脚本层完全重新实现,公式与数值不再分开——只有一个公式字段。迁移时把 1.0 的"数值 + 数值公式"两处合并成 2.0 的单一公式字段即可。

4.4 场景与地形 ​

基础地形/场景资产文件 1.0 与 2.0 同格式,可直接复制使用。1.0 工程不包含 Volumetric3D 场景,因此默认迁移不需要生成 2.0 的 3D 场景产物;只有目标工程主动改用 Volumetric3D 时,才按 3DSceneSetup 重新生成派生产物。主要差异与处理方式:

资产1.0 文件名2.0 文件名实测
高度图heightdata.datHeightData.dat同格式(头部一致,zlib 压缩),仅大小写改了
寻路碰撞collision.dat / clientcollision.dat / editorcollision.datCollision.dat / ClientCollision.dat / EditorCollision.dat同格式,仅大小写
视野sight.dat / editorsight.datSight.dat / EditorSight.dat同格式
地块map.acmapmap.acmap同格式
地形信息map.scene_itemsmap.scene_items头部逐字节相同(JSON 文本)
场景配置config.luaconfig.lua同结构;内部链接从 $$.xxx.root 变为新 GameLink id($01K...)
区域/预放置area_save.lua / unit_save.lua同名同在同格式

只有几处真实差异(都不是"地形格式变了"):

  1. 目标工程可能有 scene_info.xml、PhysicsCollision.dat 等 2.0 派生产物;1.0→2.0 默认迁移不需要生成 PhysicsCollision.dat,只有目标场景主动升级为 Volumetric3D 时才按 2.0 编辑器流程生成。
  2. 场景信息 + 预放置物体额外要写进 GameDataScene(1.0 用 scene/<名>/area_save.lua、unit_save.lua 的 Lua 表记录)。

迁移配方:

  1. 把 1.0 scene/<名>/ 的资产文件复制到 2.0 工程对应场景文件夹。
  2. 用 2.0 编辑器打开项目,确认目标 GameDataScene、场景入口、尺寸和相机等链接;默认 1.0→2.0 迁移不要求生成 PhysicsCollision.dat。如果用户明确把目标场景升级为 Volumetric3D,再按 3DSceneSetup 生成 3D 场景产物。
  3. 把 area_save.lua / unit_save.lua 里的点/线/区域/预放置单位,誊写进 GameDataScene 的预放置字段(PlacedSceneShapes / PlacedPlayerObjects 等,字段名以 GameDataScene schema 为准)。部分原全局配置(寻路/视野模式)现按场景配在 GameDataScene,见 SceneSystem、SceneVisionSystem。
  4. 在编辑器场景列表中核对所有预期入口,并保存、重开复查。编辑器元数据如 Path 可能不在运行时 schema 中,不能仅因 schema 未列出就删除;先对照编辑器创建的有效场景源文件及 MCP 元数据。矩形区域的两角坐标不能直接当作中心/尺寸,见 4.9。
  5. 覆盖目标模板的同名场景后,检查 editor/terrain/scenes/<名>/ 的 authoring projection 及关联派生产物是否仍属于模板旧地形。通过目标编辑器实际提供的场景状态、保存和资源生成工具刷新并回读;source_stale、保存检查点未到达或投影无效都不能计作保存成功,也不能把旧投影导入刚复制的地形。仅当确认是本次骨架产生、且无用户编辑的模板残留时,才可留档移出;用户已有投影需保留并单独处理。尚未生成投影时如实记录,不能伪造 manifest/hash 或额外启用不需要的 3D 烘焙来消除提示。

4.5 单位属性 / 可扩展枚举 / 伤害类型 ​

  • 可附加枚举 → 可扩展枚举:用 [EnumExtension(Extends = typeof(...))] 扩展已有枚举,或 [EnumExtension(Extendable = true)] 定义新可扩展枚举。枚举名必须以 E 开头(生成时去掉 E),且只能用于直属命名空间的枚举。例:
    csharp
    [EnumExtension(Extends = typeof(PropertyUnit))]
    internal enum EGameplayPropertyUnit { MagicPower, CriticalRate, Inventory }
    // 使用:unit.SetProperty(GameplayPropertyUnit.MagicPower, 100.0);
  • 单位属性 → GameDataUnitProperty:1.0 在 const_config / Gameplay 表里配的单位属性公式,现内化为 GameDataUnitProperty 自身字段。见 UnitPropertySystem。
  • 伤害类型 → GameDataDamageType:公式在自己表里定义。
  • 详见 EnumExtension 与 02-高级功能。

4.6 动画 ​

  • 1.0 技能表里直接填的动画 → 2.0 可指向独立 GameDataAnimation 节点(GameDataAnimationSimple / GameDataAnimationSequence / GameDataAnimationBracket)。见 ModelAnimationSystem、schemas/types/GameDataAnimation*.json。
  • 核对完整类型与引用链:当前简单动画节点为 GameCore.ModelAnimation.Data.GameDataAnimationSimple;不要因 GameDataAnimation 基类位于资源类型命名空间就推测其子类型也在同处。仍以目标版本查询为准。核对 Ability.Animation → 可实例化动画节点 → 模型真实片段名及大小写,生成后确认赋值存在,并实际播放;资源路径存在或技能命令成功不能代替动画验收。
  • 捏人/共享人形动画:资源统计会尝试沿 GameDataUnit.Model / Abilities → GameDataAbility.Animation → GameDataAnimation 素材自动收集烘焙关系,但这是依赖代码结构的静态分析,不保证覆盖 helper、工厂或运行时动态组装。关键动画可继续在对应 GameDataModel.HumanoidSourceAnimations 中显式填写(≈ 1.0 数据编辑器的“额外加载动画”)作为保险。之后仍需在编辑器手动执行动画重定向(工具 → 资源统计和动画重定向 → 统计资源并生成)。也可手动维护 ref/model_animation.json 后只执行菜单中的“生成”;再次统计资源会覆盖手工 JSON。见 04-限制。

4.7 UI ​

2.0 UI 编辑器 / UI Authoring 已进入工具链,但仍处于早期阶段,覆盖范围与 1.0 不等价;同时支持以下构造法(见 03-UI系统):

  1. 数编模板:GameDataControl* 定义模板 → Control.Xxx.CreateButton() 实例化。与 1.0「存配置生成代码」的路径最像,适合静态/复杂/可复用 UI。
  2. 运行时动态:new Button{ ... }、设 Parent、订阅 OnPointerClicked、AddToVisualTree()。
  3. 流式语法:Button().Size(...).Center().Background(...),见 FluentUILayoutGuide、ui-layout-api。

迁移 1.0 UI(控件在 ui/script + link_node;事件响应触发器配置在 ui/src/gui/ui_response/——触发器 json 配置,后缀虽是 .lua——生成代码在 ui/script/gui/ui_response/。UI 事件必在客户端,故都在 ui/ 下;仅当项目有自定义 UI 事件响应时存在):

  • AI 助手按场景选择 UI Authoring、流式(Flex)、运行时代码或数据驱动模板;流式语法仍适合快速构造,但复杂交互和最终行为必须走普通客户端运行时验证。见 ui-authoring-mcp、ui-layout-api、FluentUILayoutGuide。也可直接代码对代码翻译。
  • 挂载差异(易漏):1.0 控件创建时默认挂上 visual tree;2.0 需主动挂(AddToVisualTree() 或流式的 AddToRoot()),漏挂则控件不显示。迁移完整页面或菜单时,优先把页面根节点写成 UI.Page(),再把实际内容容器 FillParent() 到 Page 内部。
  • 控件类型也是数编类型:1.0 控件类型在 lua_declare.d.ts 里同样以 _OBJ__ 开头(设计上是数编类型的一种),对应 2.0 GameDataControl*。
  • UI 代码通常包 #if CLIENT。2D 绘制见 canvas-2d-game、CanvasDrawingSystem。"物品额外属性"在 2.0 改名为"物品动态属性",客户端可读(1.0 客户端读不到公式属性的痛点已解决)。

4.8 表现资源与客户端注册 ​

模型、动画和 Actor 的迁移应把“资源入口”和“依赖闭包”分开检查。prefab 或模型路径存在时,仍需确认其 mesh/mdl、材质、纹理、动画、碰撞、Socket 及粒子 Actor 依赖可被目标客户端解析;不要把文件存在视为运行时可用。

资源目录迁移 ​

  • 将 1.0 工程根目录的 res/ 按相对路径整体合并到 2.0 项目 res/。这一步不能省略:旧项目的地形、模型、材质、粒子、音频或场景配置可能通过 res/... 间接依赖,即使当前 .ts / .ini 没有直接出现完整路径。
  • 将 ui/image/、ui/spine/ 及其配套的 .atlas、.skel、.json、贴图等文件一起复制;若源工程使用 ui/Spine/,保留源目录大小写并按 ResourcePathGuide 转换代码路径。不要复制生成产物或目标项目已有的 ui/AppBundle/、AppBundle/managed/。
  • 合并时记录同名文件冲突并以目标工程实际引用为准;不要用空壳资源、伪造模型或伪造动画文件掩盖缺失依赖。
  • 复制后执行一次 Client-Resource,检查 ref/objref.txt 是否包含关键资源;发布到不同运行环境时,还要确认自定义云端资源在目标环境存在。

运行时创建的单位,其客户端可见部分应与服务端创建逻辑分离:

  • GameLink、基础 GameDataUnit、Model、状态栏和客户端需要解析的 Actor/Ability 数据放在双端共享区域;
  • 动态属性公式、AI、创建/销毁、死亡和权威战斗逻辑按 API 能力放入 #if SERVER;
  • 服务端和客户端分别编译后,仍需用客户端日志或截图确认单位可见。

1.0 技能动画名可能只是逻辑别名,迁移时应在目标模型中核对真实片段名和大小写,再通过 GameDataAnimation 指定。特殊技能的预警、投射物、爆炸和伤害应尽量共享同一落点/载体作用域;若 Actor 挂在载体上,搜索或命中后应留出清理延迟,避免表现随载体立即消失。

1.0 数据复用边界:

  • 直接复用源配置中的坐标、数量、半径、时间、伤害公式和已确认完整的资源路径;
  • 不假设 1.0 的 Effect/Actor 运行时结构可被 2.0 原样加载;
  • 用 2.0 的 TargetLocation、执行上下文、Mover、Model Event、Socket 和 Actor 生命周期重新表达节点关系;
  • 每个阶段明确位置所有者,避免技能原始目标、随机点、新载体和默认目标混用。

迁移垂直下落表现时,先检查运动是否已编码在模型动画、Model Event 或 Socket 中。若起点和落点的水平坐标相同,不要默认使用依赖水平朝向的投射物移动器,也不要通过增加水平偏移制造方向;优先采用地面载体统一预警、落点、爆炸和伤害中心,再由模型动画或 Socket 提供高度变化。


4.9 高风险语义与字段回读 ​

遇到以下映射时,在批量转换前选一个非默认样例核对。表中给出检查点,具体字段、默认值与序列化格式仍以目标 SDK/编辑器版本为准;版本缺陷应记录最小复现,不写成永久能力限制。完整四层回读流程见 quality-gates.md 4.4。

映射场景必须辨认的语义最小验证
两角矩形 → 区域配置目标字段若要求左上角 + 尺寸,先按其坐标约定求角点与宽高;不要当中心点,也不要额外旋转整张地图坐标用非原点、非正方形区域核对两个角与边界进出
Cast / Channel → 技能阶段对照源事件触发时机、首次效果、周期和结束;名称近似不代表阶段相同例如立即首击、每 0.5 秒、共 8 次,记录实际时间轴
响应上下文与关系筛选分辨 Caster、Default 及响应事件提供的目标;Player 与 Alliance 关系不可凭字面互换同时测试自己、同玩家另一单位、盟友、敌人及无效目标
模板集合与实例继承先看模板有效值和集合合并方式;不能假设子集合覆盖父集合,也不能把实例当模板注册核对最终背包、筛选器、效果列表和默认行为,无额外样例项
值对象 / 集合 gettergetter 可能返回副本;配置写对、生成器调用 AddRange 并不证明实例已更新Footprint 等集合核对保存源、生成赋值和运行数量;缺少 setter 回写时按缺陷定位
物品计数与容器操作不可堆叠物品的计数字段含义、载体初始化、同载体交换与跨载体放入、部分堆叠需分别核对;查目标 Swap / Put 等 API 契约单件、多件、满格、部分合并、跨仓库移动后总量守恒,失败无丢失/复制
C# 包装类型 → JSON如 WeightedLinkComplex 在 C# 可有包装 API,不能据此编造 JSON 对象结构;先核对 schema/已保存样例的数组形状保存并重新读取一项非空效果列表,再运行确认效果实际触发
任务等非默认字段按实际 schema/API 选择字段,如 TargetCount,不要猜测 RequiredCount 一类近义名称设置为 3,重新读取并运行确认 1/3 → 2/3 → 3/3

涉及触发器导入/替换时,再核对生成的表达式优先级、变量初始化位置、嵌套引用和函数入口,而非仅检查工具返回成功。若最小样例已暴露工具或生成器问题,保留输入、保存后输出、版本和诊断,将受影响功能标为待修复;替代路线需符合用户已选作者方式,并记录差异。

五、手补清单与已知不支持 ​

迁移收尾,逐条核对并如实告知用户:

  • [ ] 坐标系:2.0 默认镜头转了 90°(仅为统一 2D/3D 坐标规律,非强制,可配回 1.0 朝向)。别换算坐标数据——地形与场景/预放置坐标整体复制、彼此一致,换算反而要连地形一起转。只复查代码里硬编码的方向假设("屏幕上方=某轴"、UI↔场景手动换算)。见 COORDINATE_SYSTEM_GUIDE。
  • [ ] 类型/字段差异:3.2 标「需确认」的类型名(camera/loot 等)务必对 schemas/types/ 核实;逐字段对落点。
  • [ ] 公式 #if 放置:按 GameDataFormulaPlacement 检查,避免客户端编译失败。
  • [ ] 场景预放置:area_save.lua/unit_save.lua 的区域与预放置物体已写入 GameDataScene?
  • [ ] 捏人动画重定向:ref/model_animation.json 是否包含目标模型与动画,编辑器里是否已生成重定向?关键动画是否需要用 HumanoidSourceAnimations 显式兜底?
  • [ ] 依赖库:libs.json 里的 1.0 script_libs 是否都有 2.0 对应能力?无对应的需手工实现。
  • [ ] 小地图:检查 game_hud/minimap* 是否存在;2.0 没有与 1.0 等价的完整内置小地图工作流,但可使用 MiniMapIcon 或 Canvas 自行补表现,见 canvas-2d-game、CanvasDrawingSystem。
  • [ ] 编译 + 运行:Server-Debug 与 Client-Debug 都过;实际跑起来核对行为(wasicore-dev、GameCompletenessChecklist)。

2.0 暂不支持 / 缺失(04-限制):

  • 场景拼接功能:暂未加入(这类 1.0 项目极少,今后会加)。
  • 小地图:没有与 1.0 等价的完整内置工作流;可用 MiniMapIcon 或 Canvas 自行实现所需表现(见 canvas-2d-game)。
  • 部分小卡片机制:可能未覆盖(商城已支持);未覆盖的先用代码/API 实现。

六、校验 ​

  1. 编译:用 2.0 编辑器调试按钮,或 dotnet build src/GameEntry.csproj -c Server-Debug 与 -c Client-Debug。有错先修再继续。
  2. 运行:在编辑器调试,或用 client-only-debug 启动纯客户端核对 UI。
  3. 行为核对:对照原 1.0 项目,抽查关键单位/技能/Buff/场景预放置/UI 是否一致;动态行为异常用 behavior-troubleshoot 排查。
  4. 逐块推进:每迁完一个子系统就编译+跑一次,不要堆到最后一起验。