Files

224 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 关卡战斗技能系统设计
2026-10-20。首版服务于现有十伙伴、五类敌人、二十关的自动战斗,统一普攻、主动技能、动作、特效、音效和战斗数据处理。技能由配置组合,服务端执行逻辑并产生有序战斗事件,客户端按战斗时钟播放表现。
本次交付设计、禁用运行时的配置样例、TangoFlux音效制作清单及校验工具。现行 `greenfield.json`、`battleRules=2`、在途挑战及奖励协议保持原状;运行时接入按下文实施顺序进行。
## 现有基础与版本边界
`PrototypeBattle.cs` 与 `AIServer/src/game.cpp::battle_lanes` 使用0.05秒固定步长,伙伴技能为shield/heal/slow和伤害分支,命中即时处理;同一单位可以在同tick释放技能和普攻。`PrototypeFlow.RefreshBattle` 读取Pulse/SkillPulse,驱动原型弹体及缩放表现。
服务端在battle.begin时计算并保存结果,以readyAt限制最早结算;battle.finish不接受客户端自报胜负。现阶段没有战中手动决策。新系统沿用该授权方式,自动战斗的技能选择也由服务端执行。
带前摇、投射物到达伤害和动作互斥的新规则指定为 `battleRules=3`。这些会影响战斗节奏和结果,不能直接替换旧分支并声称数值行为完全等价。旧挑战继续读取已冻结结果/快照;新规则发布前须完成平衡、协议和旧版本恢复测试。
## 系统结构
```mermaid
flowchart TD
Config[冻结玩法配置与技能定义] --> Sim[服务端 BattleSimulation]
AI[自动选技能与目标] --> Sim
Sim --> Runtime[SkillRuntime 状态与时间调度]
Runtime --> Actions[逻辑行为执行器]
Actions --> Data[伤害 治疗 护盾 减速 投射物]
Data --> Events[有序 BattleEvent 与权威结果]
Events --> Clock[客户端 BattlePlaybackClock]
Clock --> Present[SkillPresentationDirector]
Present --> Motion[动作播放器]
Present --> VFX[特效池]
Present --> SFX[音效池]
Events --> UI[血量 状态 飘字 战斗统计]
```
| 模块 | 职责 | 不承担的职责 |
| --- | --- | --- |
| SkillDefinition | 目标、前摇、行为、冷却、资源消耗、打断及效果参数引用 | 保存每个单位当前血量或冷却 |
| SkillRuntime | 一次施法的castId、阶段、目标、释放tick和实例状态 | 直接调用Animator/ParticleSystem/AudioSource |
| SkillActionExecutor | 执行Damage、Heal、ApplyStatus、LaunchProjectile等行为 | 读取贴图、骨骼或Unity碰撞结果决定伤害 |
| StatusSystem | 状态实例、过期、合并、护盾吸收、移速修正 | 播放循环特效 |
| BattleEvent | 记录已发生的逻辑事实与结果数据 | 接受客户端改写结果 |
| SkillPresentation | 将事件映射为动作、特效、音效、飘字等组合行为 | 计冷却、再次扣血或发放奖励 |
一次技能可以包含多个逻辑行为,例如命中后先造成伤害再施加减速;一个表现事件也可同时播放动作、特效和音效。首版提供有限的类型化行为和处理器注册表,配置只引用白名单参数与公式,不执行任意脚本字符串。复杂节点编辑器、技能连招树和战中手动输入后续扩展。
模板使用 `actions[]` 顺序组合逻辑行为,每条有独立actionId和trigger。命中时依次执行并输出结果;后续增加“伤害+减速”的技能,只需增加ApplyStatus行为及对应正式数值来源。表现使用事件下的 `bindings[event][]` 组合animation/vfx/sfx,同一事件可触发多种表现。两侧按castId和actionId关联,资源数据不会进入服务端计算。
## 配置和运行实例
配置分为玩法和表现两部分,数值只由 `Config/Gameplay/greenfield.json` 的冻结副本解析。技能样例通过actorId、sourcePointer、template引用现有角色参数,不重复维护一份攻击力、射程或T1/T2数值。
| 数据 | 主要字段 |
| --- | --- |
| SkillDefinition | skillId、actorKind、slot、template、parameterSources、selector、timing、channel、priority、cost、cooldown、interruptPolicy |
| LogicalAction | actionId、phase或触发条件、type、targetSelector、effect参数、delivery策略 |
| SkillPresentation | presentationId、事件名、cue数组;每条cue为animation/vfx/sfx,含assetId、anchor、生命周期token |
| CastInstance | battleId、castId、skillId、sourceEntityId、targetIds、startTick、releaseTick、endTick、casterStatsSnapshot、阶段 |
| ProjectileInstance | projectileId、castId、targetId、releaseTick、arrivalTick、释放位置、目标位置、payload、失效策略 |
| StatusInstance | statusId、ownerId、sourceId、value、expiresTick、mergeGroup、来源记录 |
样例文件:
- `Config/Combat/skill_system_v1.proposal.json`:8种模板、25个技能绑定,覆盖每只伙伴的普攻/主动技能和每类敌人的普攻。
- `Config/Combat/skill_presentations_v1.proposal.json`:12个表现配置、2个现有动画引用、18项待制作的特效/音效引用。
- `Doc/Design/Sound/BattleSkills/manifest.json`:9项TangoFlux音效制作配方,状态planned_not_generated。
proposal文件显式 `runtimeEnabled=false`,现有CMake和客户端加载器不引用它们。接入时将技能逻辑定义加入正式配置的skillSystem字段,由CMake参与同一内容哈希并冻结入battleSnapshot;表现配置作为YooAsset资源按版本加载。禁止运行时把“当前最新技能表”混入旧挑战。
参数解析器至少支持以下白名单。配置字段的秒数转为整数tick时向上取整;UI仍可显示秒。
| 参数 | 来源与语义 |
| --- | --- |
| basic_cooldown / basic_range | 伙伴或敌人的cooldown;伙伴range;敌人近战接触距离首版为1世界单位 |
| actor_attack | 本场战斗初始化后的攻击力,已含共享等级/进化成长;敌人含stage.attackScale |
| ability_cooldown / ability_range | 对应伙伴ability.cooldown/range |
| ability_value / duration / radius / target_count | 按该单位冻结tier读取t1/t2、duration/t2Duration、radius/t2Radius、targets/t2Targets |
| boss_control_scale | ability.bossControlScale,控制首领减速强度 |
## 施法阶段与竞争规则
状态流为 `Ready → Windup → Released → Recovery → Ready`,另有Cancelled。冷却以绝对 `nextReadyTick` 保存,与施法阶段独立:从施法开始计冷却,后摇结束且冷却到期才可再次施放。
同一单位首版只有一个main_action通道。每tick先收集符合条件的主动技能候选,再普攻;主动技能优先级100,普攻10,同优先级按skillId稳定排序。未进入射程、治疗没有受伤目标、单位死亡或受硬控制时不开始,也不扣冷却/资源。首版没有额外蓝量,cost为0;将来扩展消耗须在CastStarted时原子扣除。
开始后预留动作通道直到endTick;新技能不叠播在普攻上,也不任意打断后摇。死亡/硬控制在释放前取消,清理蓄力,首版不退款、不退冷却;释放后的投射物独立存在,施法者死亡不撤销已经发出的攻击。缺失动画、特效或音效不会取消逻辑施法。
零前摇技能在开始的同tick释放,调度器必须处理新加入的到期任务。结束和取消只执行一次。恢复正常动作时依据当前移动状态回到Idle或Walk,不能把Attack布尔值长期置true。
## 固定时间和数据规则
逻辑tick为50ms,独立于Unity帧率、AnimationEvent、声音长度、Time.timeScale和网络到达时间。客户端用deltaTime累积播放tick并插值位置,所有逻辑事件按顺序消费;帧率降低可以合并表现更新,不能丢弃血量、状态、死亡或胜负事件。
建议新版内核使用int64中间计算:血量/攻击以千分之一单位保存,位置以毫米保存,倍率以万分比保存,时间以整数tick保存。配置编译时明确每次取整位置。此为新版规则,仍须以基准样例检查量化后的结果,不能把“使用整数”当成已经通过一致性验证。
伤害先按施法开始时攻击快照乘技能倍率;命中时读取目标防御和当前护盾。元素开启时按现行元素表计算、减防、向下取整到整点伤害且至少1;元素关闭时沿用raw伤害语义。护盾先吸收,再扣血;实际血量变化计入伤害/治疗统计,过量治疗和溢出伤害单独记录。死亡只允许Alive→Dead一次,不能重复累计击败数。漏怪为Exited状态,不计击败。
同tick采用固定阶段:
1. 生成本tick单位、处理到期状态和此前已发出投射物的到达;按稳定键应用结果并处理死亡。
2. 更新移动/阻挡关系,收集仍存活单位的自动施法请求。
3. 推进已有施法与本tick新施法,产生到期释放;先收集本阶段的有效释放,再结算其即时效果。
4. 以 `(dueTick, sourceEntityId, castSequence, actionIndex, hitIndex, targetEntityId)` 排序执行;目标已经死亡则跳过并记录失效结果。本阶段已经有效释放的行为不因稍后同tick施法者死亡而撤回。
5. 处理死亡、漏怪、动作结束和关卡胜负,输出最终事件序号。耐久归零/达到关卡超时优先判负,其后才判断全部敌人清除;同tick最后一敌死亡与超时相遇时也按此顺序。新触发的反应行为首版不支持递归执行,后续必须入队并限制连锁深度。
首版目标选择和技能结果不使用随机数;seed保留给确定的表现变化和未来扩展。将来加入暴击、闪避等概率效果时,须同时固定随机算法、种子和抽样顺序,并由服务端记录结果。
首版普通近战按释放tick结算。远程投射物从逻辑位置计算 `travelTicks=max(1,ceil(distanceMm/speedMmPerTick))`,固定arrivalTick;样例速度每tick800mm,即16世界单位/秒。飞行路径由客户端插值显示,到达是否命中由逻辑决定。范围在释放时检查,命中时检查目标仍存活且未离场;目标丢失时expire,不自动改打其它目标。目标移动期间表现追踪同一目标,到达tick保持不变。以后增加非追踪弹体、范围碰撞或地面落点需显式增加delivery类型。
## 选敌 治疗 护盾和减速
首版选择器覆盖当前玩法:同路最前敌人、自身、范围内血量比例最低的友方、同路最前阻挡伙伴。选敌按逻辑Z距离再entityId排序;最低血量比例用整数交叉相乘比较,再按slot排序。候选目标在开始时用于判断能否施法,释放时重新选择并冻结本次目标集;投射物发出后不重选。
治疗范围沿用路线的实际左右关系:lane0在中、lane1在左、lane2在右;相邻路线不是简单的laneId相差1。T2治疗radius=1可覆盖中路相邻的一路,具体候选集合按lane_position映射计算。burst和chain按targets/t2Targets选取同路前N个目标;当前chain是多目标伤害,首版不自动加入有延时的跳跃衰减或额外弹射目标。
| 效果 | 首版规则 |
| --- | --- |
| Damage | 普攻攻击倍率1;burst/chain为攻击×ability_value,按目标分别执行并记录结果 |
| Heal | ability_value为固定治疗量,不额外乘攻击;封顶MaxHp,满血友方不作为起手目标 |
| Shield | shield_main共享合并组:取当前剩余盾和新盾较大值,过期时间改为本次命中tick+duration;到期/耗尽移除 |
| Slow | slow_main共享合并组:取较小剩余移速倍率,过期取较晚值;首领倍率为1-(1-value)×bossControlScale,到期还原 |
上述合并方式对应现有规则的主要语义。以后需要各来源独立过期、叠层、驱散或免疫时,以新状态定义明确合并策略,不能默默改写旧技能效果。每次应用状态保留来源,用于状态特效归属和统计。
## 战斗事件与表现行为
所有事件携带battleId、eventSeq、tick、type、castId、skillId、sourceEntityId,以及按类型需要的targetId/projectileId/statusId。HitResolved包含validHit和本次命中的效果结果数组:原始值、吸收值、实际伤害/治疗、hpAfter、shieldAfter、是否死亡及失效原因。客户端直接应用这些结果,不再次调用伤害公式。命中cue要求validHit=true;被护盾完全吸收仍为有效命中,已经死亡/离场的目标则不播放命中cue,投射物通过ProjectileExpired回收。
| 事件 | 表现行为 |
| --- | --- |
| CastStarted | 播放技能动作、朝向目标、开启手部蓄力特效和蓄力声音 |
| CastReleased | 停止蓄力token,播放发射音;瞬时技能在此tick产生命中结果 |
| ProjectileSpawned | 从出手挂点创建/租用弹体表现,绑定projectileId及预计到达时间 |
| HitResolved | 停止对应弹体,更新血量,播放命中特效/命中音/飘字;一次命中可有多项逻辑结果 |
| StatusApplied / StatusRemoved | 按statusId添加或停止护盾/减速等持续表现,刷新现有实例而不重复堆节点 |
| CastEnded / CastCancelled | 回收施法局部token并恢复移动/待机;已经发射的弹体不归施法结束清理 |
| UnitDied / BattleEnded | 停止该单位或本场所属表现、回收对象池和音源,结束战斗视图 |
逻辑效果去重键为 `(battleId,castId,actionId,targetEntityId,hitIndex)`;表现去重键为 `(battleId,eventSeq,cueIndex)`。对象池索引不能作entityId,重连/换场必须隔离battleId。资源异步返回时检查所属battleId和token仍有效,过期回调立即释放handle,避免在新一场播放旧效果。
动作、特效、音效和UI共用BattlePlaybackClock。暂停时冻结播放时钟、暂停本场动作/粒子及本场持有的AudioSource,UI音效仍可使用;恢复不重复触发开始事件。倍速改变事件间隔、动画速度和弹体插值;首版短音效保持原音高,超过有效播放窗口的旧one-shot可以跳过。逻辑结果始终完整应用。初始音源上限建议12路,按技能重要性、距离和同类冷却控制抢占,实机再定预算。
重连默认重播同一已授权挑战;以后增加seek时从状态快照+事件游标重建血量、状态及在飞弹体,历史一次性声音/爆闪不补播。资源未就绪使用已制作原型表现或跳过装饰,不暂停权威结算。正式关卡需在播放前预加载本阵容和敌人所需的表现资源。
## 火喵施法样例
火喵已有Attack长1.1秒、释放标记0.55秒、非循环。普攻冷却0.9秒,因此普攻动作按0.9秒窗口播放,速度为1.1/0.9约1.222;释放发生在第9tick即0.45秒,结束第18tick。主动技能冷却6秒,动作按原速播放,释放第11tick即0.55秒,结束第22tick。
| 阶段 | 逻辑行为 | 动作 特效 音效 |
| --- | --- | --- |
| 开始 | 验证条件、占main_action、记录攻击快照、开始冷却 | Attack+双爪蓄力粒子+FireCharge |
| 释放 | 选取同路前方目标,创建逻辑投射物 | 停蓄力、FireLaunch、FireProjectile从Cast挂点飞出 |
| 到达 | 目标有效则按普攻×1或主动技能T1×1.3/T2×1.8造成伤害 | FireHit+命中音+伤害飘字 |
| 后摇结束 | 释放动作通道,等待下一次可施法 | 根据移动状态恢复Idle/Walk;在飞火球继续存在 |
例:以本次施法开始为相对tick0,T1主动技能在tick11释放;释放时目标距离4世界单位,以16单位/秒飞行5tick,在tick16结算伤害;tick22动作结束。多个火球可以在飞行中并存,每个有独立projectileId。当前该技能targets=1、radius=0,命中特效不得让玩家误认为有范围溅射。
现有 `OnCompanionAttackImpact` AnimationEvent保留为动作对齐诊断标记,不再独立发射或扣血。技能时钟事件是唯一表现调度源,避免事件回调和时间轴各发一颗。骨骼动画由已有.anim驱动;首版通过Animator动作适配器/局部速度参数接入,精确seek扩展可使用Playables手动采样。Unity Playables支持组织和混合动画、音频等数据源,详见[Unity 2022.3文档](https://docs.unity3d.com/2022.3/Documentation/Manual/Playables.html)。
## 角色挂点和资源归属
逻辑侧只认识entityId和逻辑位置。角色Prefab提供语义挂点Cast、Body、Hit、Head;表现配置映射到各自骨架,业务代码不硬编码bone_7等名称。已有火喵/岩团团尚未制作这些技能挂点,设计样例采用bounds fallback;正式接入须通过Pipeline制作挂点并在动作全过程检查位置。
新角色局部+Z为正面,与Unity的transform.forward一致,世界朝向通过Quaternion.LookRotation(direction)对准目标;不能把世界固定+Z当作角色当前朝向。现有-Z角色与旧SkillMuzzle挂点按各自历史配置兼容,不随新约定自动翻转。粒子挂点随动作,投射物释放后进入世界空间;护盾随目标,命中爆闪按HitResolved位置播放。根位移由逻辑驱动,动作Root Motion关闭。
资源加载走YooAsset,动画/特效/音效引用按地址和类型校验,资源handle由战斗资源集持有;动作实例持有租用对象和生命周期token。BattleEnded、切页和销毁都必须停止本场循环声音、清空粒子/Trail并归还池,禁止把旧轨迹带到下一次播放。
## TangoFlux音效制作
严格使用 `D:/UD/AI/XModel/TangoFlux_AI调用指南.md` 的TangoFluxService方法。现有 `Tools/generate_ui_sfx.py` 接受通用manifest,可复用其HTTP提交/轮询/下载流程制作首批战斗音效;长期应抽取共享客户端,以请求内容哈希校验缓存,避免只按文件存在判断有效。
1. GET /api/status,确认ready和内存;未加载时POST /api/warmup后复查。不为生成音效擅自停止其它3D/音乐服务。
2. 英文声学描述,固定seed;POST /api/generate,duration在1~30秒,steps=50、guidance_scale=4.5、sync=false。首批并发上限2,服务queued+running总上限4。
3. 每0.8秒GET /api/jobs/{id};429退避,失败记录error,不能无限重试。成功后从返回url或/api/jobs/{id}/audio下载。
4. 保留44.1kHz立体声WAV原稿、jobId、提示词、seed、参数和SHA256;检测静音、爆音和削波,并实际试听。服务最短生成1秒,实际几十到几百毫秒的技能声音需后期裁切、淡入淡出和增益调整,不能请求duration=0.2。
5. FireCharge、FireLaunch、FireHit分开生成;蓄力有独立token可在释放时停止。火喵之外补RockHit、Heal、Shield、Slow、Lightning、EnemyHit。原稿/后期输出分开,剪切起止点写制作记录。
6. 原始文件在Tools/output与Doc/Design/Sound,最终游戏文件在 `Assets/Bundles/Sound/SFX/BattleSkills/`。AudioClip导入、音源Prefab和混音设置经Unity Pipeline制作,检查音效开关、暂停、倍速、多实例及切场清理。
7. 生成并验收完成后登记 `Doc/ResDesc_Sound.md`;目前manifest只列制作需求,没有生成音频。指南载明模型权重为非商业研究用途,资源发布前按上游许可核查并保留结论,不能把此清单视为商用授权。
可复用命令:`python Tools/generate_ui_sfx.py --manifest Doc/Design/Sound/BattleSkills/manifest.json --max-inflight 2`。这是后续制作入口,本轮未执行。该旧脚本会复制原始WAV到Bundles,正式交付仍须完成后期、Pipeline导入与试听验收。
## 服务端协议和关卡过程
首版新增SkillRuntime在C++服务端执行一次,产生权威结果与事件轨迹;客户端新版消费轨迹,避免继续长期维护两套独立技能逻辑。C#纯数据参考实现可用于交叉测试,但不得覆盖服务端结果。战斗数据不依赖MonoBehaviour、Unity Physics或资源加载。
拟扩展battle.begin响应/冻结数据:rulesVersion、logicVersion、gameplayHash、compiledSkillsHash、seed、stage/formation快照、traceId、traceHash、eventCount、tickMs及事件首块。长轨迹用拟新增battle.events(cursor,limit)按本玩家已授权battleId获取;返回范围、nextCursor和校验值。预计算结果及轨迹在同一授权记录中提交,重试返回同一战斗,不重复开局或发奖。轨迹容量、分页上限和压缩格式需按20关最坏情况实测后设定。
单位移动用带起止tick/位置的分段记录,减速、到达阻挡点或目标变化时分段;客户端插值,不必把每个单位每tick的位置重复传一遍。首次实现可先保留完整逐tick开发轨迹,确认正确性后再压缩,压缩前后必须逐事件等价。
关卡过程:加载冻结配置/资源→建立单位和波次→按tick生成敌人→移动/阻挡→自动选技能和目标→施法/投射物/效果→状态与死亡/漏怪→后续波次→胜负→调用battle.finish获取服务器奖励回执。暂停/倍速只影响客户端播放;readyAt时间门槛和幂等奖励继续由服务端控制。
手动施法暂不启用。加入战中输入后,服务端须接收并验证commandId、battleId、目标、申请tick/可接受窗口、冷却和资源,并记录确认输入;当前“开局预计算结果”协议需要改为命令驱动模拟或经验证的输入日志重算,不能直接相信客户端的施法、伤害或won字段。
## 实施顺序和验收
| 阶段 | 改动 | 完成标准 |
| --- | --- | --- |
| 设计契约 当前 | 本设计、25技能/12表现样例、9音效需求、校验器 | 覆盖当前10伙伴/5敌人/20关,阶段/冷却/动画标记和资源状态检查通过 |
| 逻辑内核 | AIServer增加独立combat模块、typed action、状态/投射物、事件轨迹;接battleRules=3 | 无Unity依赖的逻辑测试、确定顺序、去重/死亡/失效测试;结果与轨迹一致 |
| 客户端播放器 | HotUpdate/Combat增加BattlePlaybackClock、事件读模型、动作/VFX/SFX适配器;PrototypeFlow接读模型 | 1×/2×、暂停恢复、低帧率、多投射物、重连/重播一致,奖励仍取服务端 |
| 火喵和岩团团样例 | Pipeline制作挂点/特效/音源,按TangoFlux指南生成并后期/试听 | 火喵出手/到达/扣血对齐;岩团团近战/护盾完整;池与音效开关正确 |
| 全关迁移 | 补10伙伴表现、20关回归、配置哈希与协议滚动升级 | 旧在途战斗原结果、退款/放弃/finish幂等不变,新规则平衡及资源预算达标 |
逻辑测试至少覆盖:同tick技能与普攻竞争、零前摇、目标死亡/离场、施法者释放前后死亡、护盾吸收/刷新/耗尽、减速刷新/首领折扣、T2相邻路线治疗与多目标上限、重复命中去重、冷却边界、漏怪不计击杀、超时和最后一敌人的胜负顺序。
表现测试至少覆盖:动画丢标记仍只发一次、动画播放速度、粒子挂点与世界空间、音频延迟/静音/抢占、异步资源过期返回、对象池Trail清空、暂停恢复、后台恢复时跳过过期声音、BattleEnded彻底清理。最终在竖屏实际战斗相机与微信目标设备测资源加载、活跃音源、粒子透明叠加及帧耗;开发机截图通过不等同实机性能通过。
配置校验命令:`python Tools/validate_skill_design.py`。测试命令:`python -m unittest discover -s Tools/tests -p test_skill_design.py`。报告位于 `Tools/output/skill_system_design/validation.json`,该proposal报告的design_contract_validated仅表示历史设计契约通过;其中runtimeIntegrated/generatedAudio=false不代表正式运行时未接通。正式状态使用 `Tools/validate_skill_runtime.py`(runtimeIntegrated=true、generatedAudio=true、9/9声音)。
## 已落地的敌人表现批次(2026-10-21)
五类敌人的攻击与普通/硬甲/护盾受击表现已作为现有battleRules=1/2的适配层接入。实际完成8套特效、8条TangoFlux短音效、32实例/8音源播放池;真实PrototypeFlow隔离战斗及暂停/倍速/静音通过。完整制作记录见 [EnemyCombatFx/Production.md](EnemyCombatFx/Production.md)。当批BattleSkills另有9条计划声音,不与本批8条敌人声音混算;后续已完成battleRules=3权威技能运行时、十伙伴表现和9/9技能声音,见本页末正式接入记录。
## 五敌人战场替换与技能闭环样例(2026-10-21)
火喵与岩团团已完成独立 C++ 事件轨迹→Unity 时钟/动作/5类特效/5条TangoFlux音效的可运行样例,详见 [SkillSlice/Production.md](SkillSlice/Production.md)。当批独立样例尚未接主线;后续已完成battle.begin/events协议、25技能全关迁移和9/9音效,下节记录正式状态。
## 权威技能协议与正式战场接入(2026-10-21)
本阶段已完成正式 `skill_runtime_v1.json`、25技能权威内核、分页协议和客户端正式战场接入;8080开发服已启用。原proposal仍为设计样例,正式验证器为 `Tools/validate_skill_runtime.py`。旧挑战不重算,新客户端使用快照rulesVersion3;新旧规则数值节奏不等价。详细边界、测试、部署和待补美术见 [Runtime/Production.md](Runtime/Production.md)。
## 正式伙伴技能表现补齐(2026-10-21)
十伙伴的专属效果与九条计划技能声音已接入正式权威战斗表现池,配置 `Config/Combat/partner_presentations_v1.json`,制作用 `BuildPartnerSkillFx`、`BuildBattleSkills`。每次cast同种声音去重、雷电连接源目标、治疗/减速按已结算事件播放;不改逻辑内核。见 `PartnerSkills/Production.md` 的资源、流程和验证回执。