Skip to content

技能试验场 ​

技能试验场让作者在普通场景中调试真实单位和技能:迁移已有主控或创建测试单位,搜索并调整实际技能列表,修改表现参数,施放后导出可供 AI 回写的草稿。施法由真实调试服务端执行,客户端负责输入、资源准备和表现。

开发状态:核心功能已完成 Jenkins 双端构建和真实调试链路验证。实际使用需要对应的 SDK、依赖与编辑器;工具已注册或接口已导出,不代表当前安装的宿主已支持全部行为。动画准备、产物保护与退出隔离仍应分别核验,不能以一次 Ready 代替完整闭环。

怎么进入技能试验场 ​

  1. 可选地在当前游戏模式的 AbilityTestArena 或 AbilityTestArenas 中配置 GameDataSkillTestArena;旧项目中的 SkillTestArena / SkillTestArenas 仍可读取。未配置时自动使用当前 GameDataGameMode.SceneList 的第一个场景和当前主控单位,并将出生点回退到该场景中心。
  2. 使用编辑器的普通调试流程编译项目、上传服务端脚本、启动调试 Host,并连接客户端;不要使用纯客户端调试来验证技能施法。
  3. 进入正常游戏阶段后,在 PIE 顶部调试栏点击 技能调试 打开面板;入口不占用游戏画面中的项目 UI,也无需 F9 或额外命令行开关。
  4. 面板打开后会自动进入当前模式的默认配置;未配置试验场时使用第一个有效场景、场景中心出生点和当前主控单位作为回退。进入后先刷新并确认服务端状态,再以快照中的实际单位、技能列表、session 和 revision 作为后续操作依据。没有有效场景或主控时,服务端返回枚举式失败原因并写入日志。

需要记录完整的服务端上传、Host 开局和客户端连接证据时,按真实双端验收清单执行;仅能打开面板或读取客户端 UI 不足以证明权威施法链路可用。

进入试验场 ​

使用编辑器普通调试流程,让项目完成编译、服务端脚本上传、调试 Host 开局和客户端连接。在项目正常主控已经出现的阶段进入试验场,可以复用该真实对象。没有主控也可进入,服务端会创建配置中的兜底单位并返回原因。

入口要求 Game.IsDebugTestMode,服务端还要求活动中的真实双端对局。服务端进入接口返回 AbilityTestEntryStatus,可区分调试模式、场景、主控、适配器和会话状态。生产对局拒绝试验场命令;纯客户端调试不能验证技能命令、目标、消耗或效果链。

作者通过 GameDataSkillTestArena 配置普通场景,并由当前 GameDataGameMode.AbilityTestArena 引用默认配置、AbilityTestArenas 提供其它可选配置;旧字段 SkillTestArena / SkillTestArenas 仅用于兼容已有项目。

配置字段含义
Scene作者制作的普通场景,包含地形、建筑、障碍、靶子、光照和镜头
Unit关闭复用或复用失败时创建的指定单位,必填
SpawnPosition / SpawnFacing测试位置与朝向;XY 为地面,Z 为高度
PreferCurrentMainUnit优先复用当前可用的真实主控,默认开启
CreateDefaultAbilityIndicator显式试验场是否允许项目适配器在缺少项目技能指示器时创建默认指示器
CreateMovementJoystick显式试验场是否允许项目适配器在缺少项目移动摇杆时创建默认移动摇杆
AdapterKey项目显式注册的业务隔离与控制适配入口,可选

配置不填写测试技能或候选技能。复用时从已有主控的实际实例读取列表;创建时从该单位自己的默认技能建立列表。无技能单位同样可以进入。靶子可由作者放在场景中,也可由项目脚本生成,不要求逐项登记到试验场配置。

未配置 GameDataSkillTestArena 时,两个默认控件选项都按“自动创建”处理;显式配置的试验场按字段值交给项目适配器决定。GameSystemUI 在客户端调试会话中会按这两个选项创建并在退出时销毁它自己创建的默认控件;项目适配器也可以在 ISkillTestArenaAdapter.Enter 或 OnControlChanged 中读取 SkillTestArenaContext.Options,管理自定义控件。框架不会把项目自己的 GameSystemUI 控件强行挂到生产流程。

运行时使用同一 GameData 定义身份与注册目录,测试入口不按源数据编辑方式分叉。源条目来自哪里,仅在 AI 回写时定位。

主控、技能列表与目标 ​

默认入口沿用玩家主控与场景切换链路。项目有自定义装备、角色控制或镜头系统时,用适配器接管相应控制。

  • 开启复用:同一对象迁移到测试场景,保留当前实际技能和装备;记录原位置、朝向与玩家控制权。
  • 关闭复用,或当前主控不可用:创建配置中的指定单位,沿用它自己的默认技能,并显示兜底原因。
  • 清空:取消当前测试施法/循环并真实移除所有技能项,包括被动项。复用原主控的基线实例由框架暂存,以便退出时恢复同一实例与物品授予关系。
  • 添加:从已注册的全量技能目录选取稳定身份并挂载;结果以真实实例和容器规则为准。项目自动重新授予技能时,显示真实列表与诊断。
  • 换角:从已注册的单位目录创建完整新单位,切换主控并使用新单位自身默认技能;不会继承上一角色的临时添加列表。
  • 退出:恢复原主控与玩家控制权,并回收会话临时单位。原对象已销毁、原技能已失效或原场景不可用时会返回诊断,不能视为恢复成功。

目录包括当前项目和依赖库已注册的单位、技能,支持名称和定义身份搜索;同名条目按 Link/type 身份区分。被动、非人形和项目扩展类型不因目录筛选而消失。是否可直接施放、是否可成为主控,由当前对象的实际能力校验。模式条件未满足、初始化未执行或尚未动态注册的定义不会被静态扫描补造;完成注册后刷新目录。

无目标、自身、真实场景单位和地点目标仍通过普通权威命令施放;Runtime MCP 可以指定这些目标。面板只提供以当前主控为目标的单次施放,避免与项目自己的技能指示器重复。

“试验会话选项”只作用于当前调试会话:AutoCast 会在主控发出的施法命令上自动增加 CommandFlag.DoRecast;IgnoreCooldown 会跳过当前测试技能的冷却与充能等待;NoDamage 会在活动技能试验场中把实际伤害值压为零,但仍执行技能的其它效果链;CreateDefaultAbilityIndicator 与 CreateMovementJoystick 通过项目适配器控制默认控件的创建。退出试验场后这些选项全部清理。

调整表现与时长 ​

先选择当前单位实际拥有的技能实例,再查看该投影提供的 Fields。每项都有生效时机或只读/不支持原因,不能把所有反射可见字段都当成可编辑字段。项目可以扩展表现适配器与投影,支持自身的字段和施法生命周期。

当前内置投影围绕技能动画、阶段 Actor、AnimationDefinitions 动画定义与施法四段时长;效果链保持真实执行,不通过改写 Effect 模拟完整逻辑。Sequence 的可编辑片段、Actor 和事件字段以实际快照为准,片段切片、实际播放时长和速度倍率是不同概念。

时长模式行为源定义含义
Original根据当前实例上下文执行原四段公式及归一化逻辑保留原 Formula/委托
Fixed本次测试使用输入的最终前摇、施法、持续施法、后摇秒数不覆盖原 Formula,也不再次按 NormalizedDuration 归一化

固定四段是测试目标,不自动授权将源公式变成常量。草稿与 AI 回写应保留“原公式”与“本次固定目标”的区分;需要转换公式时由作者明确选择。

一次确认是一个事务,可以同时修改多个嵌套字段。Undo、Redo、Reset 作用于实例测试覆盖,不修改共享定义或其它单位。已经开始的施法持有自己的版本快照;新修改用于下一次施法。成功编辑停止后续循环,当前施法仍按旧快照完成。

客户端必须先准备该目标、generation 和 revision 的资源,并向服务端确认。请求已发送、服务端接受了修改、客户端准备完成、实际施放成功是四个不同状态;客户端未确认时,服务端不会假装已就绪。缺烘焙资源、无效身份或版本过期会给出原因。

Sequence 编排 ​

GameDataAnimationSequence 由三类列表组成:

  • Playbacks:按顺序播放的片段。AnimationRaw 指源动画;StartOffset 和切片模式限定源内容,Scale 是倍率,PlaybackDuration 是该片段实际播放时长。
  • SequenceActors:每个 Actor 独立设置 SpawnOffset 与 Duration,用于附属模型、粒子、音效等表现的生命周期。
  • SequenceEvents:事件键、时间偏移与是否暂停。使用注册目录中真实存在的键;例如 WaitForPlayerInput、ApplyPlayerState。事件不是自动授权的服务端伤害。

使用 PauseSequence=true 时,项目必须提供恢复或取消流程;新增一个事件名字不会自动实现输入等待、状态变化或伤害逻辑。换角、清空、取消和退出时,检查片段控制器、Actor、声音与事件回调是否按当前生命周期清理。

code_sample/src/SkillTestArenaSample/ 提供三片段、两个 Actor 和两个真实事件键的配置,并使用服务端日志效果对照逻辑执行。该示例的事件没有暂停 Sequence,便于先验证完整播放与清理。

Sequence 编辑数据带稳定 EntryId,支持列表增删、复制、更新和顺序调整;重排片段不自动移动 Actor/Event 的绝对偏移。区间与事件需落在片段总播放时长内,当前不提供任意空隙、重叠片段或 seek。使用前按实际编辑器工具与运行时能力确认可用的编辑、资源准备和播放入口。

草稿与回写 ​

导出草稿包含项目与定义身份、原始基线、差异、实例布置和采纳资源信息,不保存原生指针或可执行委托。清空/添加技能与换角属于本次测试布置,默认不回写 GameDataUnit.Abilities。

动画资源的 ModelPath 记录当前测试单位实际使用的模型 prefab,动画 Path 保留原值。复现时应同时核对模型与动画,不能把别名、模型自带动画或共享源路径当成同一种引用。

Setup.CastTarget 记录所选技能最近一次成功施法的目标类型:无目标、自身、单位或地点。单位使用稳定定义身份,地点保留 XYZ 坐标;这些都是复现上下文,不包含运行中的单位 ID,也不会在导入时自动找到某个场景实例。失败施法保留上次成功记录,切换技能不会串用目标;旧草稿缺少此字段时,需要重新确认目标。

客户端可使用 SkillTestDraftStorage.Save(name, draft) 保存,名称仅允许 1–64 个 ASCII 字母、数字、下划线或连字符。

位置路径
客户端运行时user_files/skill_test/<name>.json
项目内实际文件ui/AppBundle/user_files/skill_test/<name>.json

重新导入时,需要当前项目、定义身份、字段集和原基线匹配,并重新验证资源就绪状态。旧 session、generation 和实例 ID 不会用来自动定位新对象;冲突应先审阅,不强行套用。

AI 回写流程:

  1. 确认作者采纳哪些差异,以及哪些只是复现上下文。固定四段与修改默认技能列表分别表达清楚。
  2. 从稳定定义身份定位真实源条目;修改真实源数据或声明,不修改 DataGenerated、共享缓存或下载的依赖产物。
  3. 保留未被采纳的字段、Formula、Link 身份、事件语义与列表顺序。依赖库定义需要项目自有覆盖或在有权限的依赖源中修改。
  4. 补齐实际采纳资源的统计与模型动画烘焙。仅浏览过的资源不是发布依赖。详见资源路径与发布资源缺失排查。
  5. 取消循环,退出试验场,撤销全部临时覆盖并停止旧调试局;按项目正常双端编译、上传与开局流程重开。
  6. 从源定义重建的真实单位再次验证施法、四段、Sequence、目标、资源和控制权。不能仅凭仍带临时覆盖的旧局宣称回写成功。

项目业务隔离 ​

ISkillTestArenaAdapter.Enter 返回项目自己的隔离 lease;退出时恢复,并处理自定义角色控制和镜头。框架不能推断任意项目的波次、任务、掉落、自动存档或胜负逻辑。

项目可在正式进度写入入口查询活动上下文:

csharp
#if SERVER
using GameCore.SkillTestSystem;

if (SkillTestService.GetContext(player)?.SuppressProgressWrites == true)
{
    return; // 本次技能测试不提交该项目进度写入
}
#endif

这只保护作者接入的路径。项目仍需通过 lease 暂停或隔离相关业务,明确正常施法中的消耗、生成物和其它副作用如何恢复;测试效果保持真实逻辑。AdapterKey 配置存在但没有注册对应适配器时,启动会失败并给出原因。

AI 与自动化入口 ​

SkillTestClient 提供请求、响应、当前状态与资源准备;服务端公开入口 AbilityTestService.Enter 校验真实发送玩家与会话身份并返回 AbilityTestEntryStatus。Runtime 调试工具提供 ability_test.open、ability_test.snapshot、ability_test.command 和 ability_test.response,可经当前编辑器的 Runtime MCP 调用;旧的 skill_test.* 名称仅作为兼容别名。

ability_test.prepare_animation 可提前准备或查询模型动画。传入 animation 源路径;modelPrefab 可省略,默认使用当前测试单位或主控的模型。queryOnly=true 只查询状态,force=true 显式重试或重新准备。结果返回实际状态、原因与产物路径,不会修改技能定义或自动补播;宿主不可用时返回明确的 Unsupported。

动画准备的范围与验收 ​

目前按需生成由编辑器进程提供,普通角色 Actor 缺失播放与主动准备共用该服务。独立、移动或跨进程客户端没有这一进程内宿主时,应按返回的 Unsupported 处理;GameGraph 直接播放不等同于普通角色 Actor 的自动缺失入口。项目自定义模型或动画控制器仍需相应适配。

共享人形源素材使用完整资源路径,例如 anim/human/other_anim/other_01/skill_01.ani。sword_idle 之类模型自带动画名或别名用于原有播放入口,不是此工具接受的共享源文件路径;不能据其准备结果判断模型自带动画是否存在。

当前人形动画生成器要求组合动画的输入是普通动画素材;嵌套组合应先在源素材中展平。这是现有生成器的能力边界,准备接口不会把不支持的输入当作已生成的可播放结果。

检查项可确认的结果不能据此推断的结果
主动准备返回 Ready当前局可访问准备产物已播放、已采纳或已满足正式发布清单
普通缺失播放首次不等待后台生成;完成后同局再次请求能播放自动恢复首次失败的播放
先准备后实际采用采用的入口动画和依赖文件加入本地保护清单浏览目录中的全部候选都会被保护
冷资源与组合动画参考模型、骨架及组合依赖完整,当前局能读到完整可播放结果只生成入口文件就足够,或热缓存结果能代表冷启动
生成中结束调试局旧任务不向下一局运行目录提交;原项目缓存可以保留供后续复用CPU 工作必须立即终止,或保存了缓存就代表当前局播放成功

已采用的本地产物由项目 ref/pie_animation_observed.json 的 protected 列表保护;单纯提前准备的候选可能仅记录在 candidates。正常保存后检查采用产物仍在 res/anim,组合动画还要检查其依赖文件。此记录用于本地调试保护,不替代正式资源统计、模型动画烘焙与发布检查。

要验证普通缺失入口,使用原技能基线中已有的共享 .ani,不要先用面板换素材或主动 Ensure,否则验证的是提前准备流程。详细的冷路径、保存和退出步骤见 复现清单。

先读取快照,再使用快照中的 session、generation、布置版本,以及当前选中完整 target/表现 revision 发命令。发送结果包含 request ID,继续读取真实服务端响应;pending 不表示成功。过期身份或版本需重新读取快照,不能把服务端最新身份悄悄替换进旧命令。

快照同时返回实际主控与测试单位的定义、场景、位置、朝向和归属。退出后应对照这些实际值,不能只依据会话已关闭判断恢复成功。大草稿通过同一权限校验的消息通道分片传输;若响应超时,结果视为未知,先刷新权威状态再决定是否重试。

更具体的 AI 工作流见技能试验场 Skill。最终验收应同时记录客户端表现、服务端实际技能/命令状态、恢复结果和源定义重开结果。