Add rank, friends, fishing, and camp treasure with T2 studio models and skill presentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
udx
2026-10-21 23:01:31 +08:00
co-authored by Cursor
parent 89e0fa246f
commit 079313fb06
677 changed files with 395371 additions and 9692 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 775 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "BubbleTurtle T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "93a31063347b4add8964c4649ce4e753",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 104001,
"references": [
"Doc/Design/Character/BubbleTurtle/bubbleturtle.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A water-element evolution crown: a small rounded coral crown in soft pink and aqua with two smooth pearl spheres embedded in the front, all fused into one piece.",
"drafts": [
"Doc/Design/Character/BubbleTurtle/T2/drafts/T2_104001.png",
"Doc/Design/Character/BubbleTurtle/T2/drafts/T2_104002.png",
"Doc/Design/Character/BubbleTurtle/T2/drafts/T2_104003.png",
"Doc/Design/Character/BubbleTurtle/T2/drafts/T2_104004.png"
],
"generatedUtc": "2026-10-21T05:17:34Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 895 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "BudBud T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "40faf557e7994b3fa95a17b6b82411f7",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 102001,
"references": [
"Doc/Design/Character/BudBud/budbud.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A grass-element evolution bloom: one large open five-petal flower in soft yellow and white with a golden center, sitting on a small cluster of three thick mint leaves as the base.",
"drafts": [
"Doc/Design/Character/BudBud/T2/drafts/T2_102001.png",
"Doc/Design/Character/BudBud/T2/drafts/T2_102002.png",
"Doc/Design/Character/BudBud/T2/drafts/T2_102003.png",
"Doc/Design/Character/BudBud/T2/drafts/T2_102004.png"
],
"generatedUtc": "2026-10-21T05:10:32Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 824 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 KiB

@@ -0,0 +1,32 @@
# 伙伴 Studio 低模批量(2026-10-21)
对其余 9 个正式伙伴执行与岩团团相同流程:原高模 → 混元3D Studio 低模(02)→ Studio UV(03)→ 对齐原高模后 Blender 1024² 烘焙(04)→ 超出 2000×1.3 时保留 UV 减面(05)→ Blender 转回原骨架权重(含配方 skinOverrides/skinRegions)→ 直接复用原 Avatar、控制器与 Idle/Walk/Attack。脚本 `Tools/studio_lowpoly_trial.py`、`Tools/studio_lowpoly_finish.py`,批处理 `Tools/output/studio_trial/run_batch.sh`。原 Prefab/控制器/动作/rig 哈希前后一致。
| 伙伴 | Studio面数 | 最终三角面 | 骨 | 脚底范围 mm(121帧×3) | 结论 |
| --- | --- | --- | --- | --- | --- |
| 火喵 FireCat | 7368 | 3000 | 22 | Idle -0.39~0.00 Walk -0.47~1.22 Attack -0.67~1.34 | 已替换正式(第二轮:3000面+尾部覆盖限框) |
| 芽芽 BudBud | 8819 | 2999 | 22 | Idle -0.51~0.01 Walk -0.73~1.29 Attack -0.68~0.09 | 已替换正式(第二轮:3000面) |
| 闪闪雀 SparkBird | 7016 | 1999 | 28 | Idle -0.00~0.75 Walk 0.17~2.38 Attack -0.06~1.32 | 已替换正式 |
| 泡泡龟 BubbleTurtle | 7991 | 2000 | 26 | Idle -0.00~0.00 Walk -0.16~0.14 Attack -0.00~0.00 | 未采用:壳面水滴花纹糊化,壳下暗缝 |
| 岩甲犀 RockRhino | 7502 | 1999 | 29 | Idle -0.00~0.00 Walk -0.34~1.20 Attack -0.00~0.00 | 已替换正式 |
| 烈焰狮 FlameLion | 11473 | 2000 | 28 | Idle 0.00~0.00 Walk -0.90~1.82 Attack -0.02~0.00 | 未采用:鬃毛边缘破碎、爪部残缺、侧身黑块 |
| 藤蔓灵 VineSprite | 6280 | 1999 | 28 | Idle -0.27~0.14 Walk -0.98~0.74 Attack -1.45~0.54 | 已替换正式 |
| 雷鸣豹 ThunderLeopard | 5634 | 2000 | 31 | Idle -0.00~0.00 Walk -0.06~0.00 Attack -0.00~0.00 | 已替换正式 |
| 潮汐鲸 TideWhale | 5426 | 1999 | 22 | Idle -0.99~-0.00 Walk -2.24~0.06 Attack -2.71~1.79 | 已替换正式 |
九个均通过编辑 QA(绑定误差 <0.05mm、4 权重归一化、3mm 脚底门槛)与 Play 三状态检查;无需脚底局部适配。
目视对比(`AIClient/Assets/Screenshots/{actor}_studio_comparison.png`)后,Studio 面数越高(7.4k~11.5k)压到 2000 面时细薄部件与贴图细节损失越明显,首轮火喵/芽芽/泡泡龟/烈焰狮四个未采用,第二轮处理见下。候选 Prefab 仍留在 `Characters/Animal/{X}Studio/`,可提高目标面数或修权重后再评估。
战场替换:`BuildPrototype.FormalPets` 与 `BuildT2Visuals.Specs` 的 T1 改为 `{X}Studio/{X}Studio_Companion.prefab`(岩团团、火喵、芽芽、闪闪雀、岩甲犀、藤蔓灵、雷鸣豹、潮汐鲸),重跑 ApplyFormalHeroes → BuildT2Visuals.BuildPrefabs/ApplyArena/Verify;VerifyFormalHeroes.Assets 通过;隔离 18081 种子账号 1-5 实战(伙伴 0,3,5,7,8,9,T2 0,5,8)Attack 与 2 倍速通过,真实 8080 账号已还原。
## 第二轮修正(2026-10-21)
先在 Blender 分别渲染减面前 `model_baked.glb` 与减面后网格定位问题来源:
- 烈焰狮:减面前正常,2000/3000 面时爪部与鬃毛仍破碎,4000 面才基本恢复(为预算 2 倍),保留原版。
- 泡泡龟:壳面水滴花纹在 Studio UV 烘焙阶段已糊化,提高面数无效,保留原版。
- 芽芽:叶缘黑斑来自 2000 面减面;3000 面重跑 05 后消失。嘴部为 Studio 贴图中的细小微笑(原版为粉色张嘴),属风格差异,采用。
- 火喵:3000 面后 Walk 左耳尖刺仍在,确认为权重问题。原配方尾部测地覆盖(bone_0,fullDistance 0.43)在原网格只影响 175 个尾部顶点,在 Studio 网格扩散到 1593/1902 个顶点,连耳朵也被绑到根骨。`bl_transfer_skin.py` 的 skinOverrides 新增可选 `within` 归一化限框;`Config/Art/Companions/FireCat.json` 按原尾部范围外扩 0.03 设置限框后,影响 417 个顶点,耳朵正常。
Studio 版目标面数从回执 `targetTriangles` 读取(`StudioTrial.Verify` 容差为目标×1.3),这两个角色是 3000 面,超出原 2000 面伙伴预算 50%。隔离 18081 新种子账号 1-5 实战(伙伴 2,1,0,3,5,8,火喵 T2)全部播放 Attack 并跟随 2 倍速;真实 8080 正常。芽芽在后排时可能被同路火喵抢先击杀而没有出手,放到前排后验证。
@@ -189,3 +189,13 @@ shellRegionMin/Max在Unity归一化空间选取壳区,扣除shellBone刚性
## 敌人攻击/受击表现衔接(2026-10-21)
五类正式敌人已接入8套攻击/命中特效与8条TangoFlux短音效,受击不再只有缩放。资产放在 `Assets/Bundles/Effects/EnemyCombat/` 和 `Assets/Bundles/Sound/SFX/EnemyCombat/`;完整方案见 [../Combat/EnemyCombatFx/Production.md](../Combat/EnemyCombatFx/Production.md)。继续制作敌人时需检查类型映射、攻击与目标命中位置、硬甲分类、音效开关及池回收;不能让动画事件扣血或把减速Pulse当成实际命中。现有规则即时结算与动画前摇的对齐属于下一阶段技能时序改造。
## Studio低模/UV与原动作复用试验(2026-10-21)
大角首领已完整跑通官网Studio低模13,159面→官网UV→Blender坐标对齐/贴图烘焙→超过2000面目标30%后保留UV减面至2000→Blender转原22骨→直接复用原Avatar/控制器/三段成品动作。交付为独立GreatHornStudio,未替换正式角色;详情 [GreatHorn/StudioTrial.md](GreatHorn/StudioTrial.md)。
新增门禁:Studio模型可能被居中和归一化,必须先对齐高低模再烘焙,且保留官网原始下载文件与UV哈希;不能假设坐标沿用上传源。原动作脚底收尾依赖旧网格,新拓扑必须重新采样实际蒙皮;本例两个新脚底顶点各1毫米局部适配后通过3毫米贴地门槛,原骨骼/UV/动作不变。保留UV减面不等于保留Studio原13k网格的所有关节布线优势,最终2000面仍需目视评估。
## 四敌人Studio流程复验完成(2026-10-21)
Hornlet、Dashlet、Shellhorn、HornCaptain均按大角首领2~5步流程完成独立Studio版,绑定各自原骨架并直接复用原Avatar/控制器/三段成品动作。使用通用StudioTrial脚本按本角色骨数、尺寸及实际动作约束验收;禁止照搬大角首领骨编号或脚底顶点。生成、修正、Edit/Play及资源路径见 [StudioEnemies/Production.md](StudioEnemies/Production.md)。
@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "FireCat T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "0eb49a43c922480faccef87f7270f41e",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 101001,
"references": [
"Doc/Design/Character/FireCat/firecat.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A fire-element evolution crest: a single solid stylized flame shape in orange, yellow and red, three soft rounded flame tongues rising from a small golden band base.",
"drafts": [
"Doc/Design/Character/FireCat/T2/drafts/T2_101001.png",
"Doc/Design/Character/FireCat/T2/drafts/T2_101002.png",
"Doc/Design/Character/FireCat/T2/drafts/T2_101003.png",
"Doc/Design/Character/FireCat/T2/drafts/T2_101004.png"
],
"generatedUtc": "2026-10-21T05:07:01Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "FlameLion T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "c3c3ff197d614f82934d45c75a6c0efa",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 106001,
"references": [
"Doc/Design/Character/FlameLion/flamelion.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A fire-element evolution crown: a small golden crown with five rounded solid flame-shaped points in orange and red, a red gem embedded in the front.",
"drafts": [
"Doc/Design/Character/FlameLion/T2/drafts/T2_106001.png",
"Doc/Design/Character/FlameLion/T2/drafts/T2_106002.png",
"Doc/Design/Character/FlameLion/T2/drafts/T2_106003.png",
"Doc/Design/Character/FlameLion/T2/drafts/T2_106004.png"
],
"generatedUtc": "2026-10-21T05:24:42Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 739 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 KiB

@@ -0,0 +1,48 @@
# 大角首领:Studio低模/UV与原动作复用试验
2026-10-21,状态 validated。用户明确授权原始 greathorn.glb 上传腾讯混元3D Studio,实际完成截图流程第2~5步,并在本地Blender绑回原22骨。交付独立试验版;现有关卡继续使用原GreatHorn,未替换正式战场。没有重新调用TokenRig/UniMate,也没有修改原动作。
## 实际结果
| 阶段 | 实际执行与产物 |
| --- | --- |
| 原始高模 | `Tools/output/enemy_3d/GreatHorn/greathorn.glb`,49,976三角面,原文件保留 |
| 02 Studio低模生成 | 官网低模拓扑V1.5,三角面/低;得到13,159三角面。任务及下载记录 `hunyuan_studio.json`/`studio_lowPolyTopologyRsp.json` |
| 03 Studio UV展开 | 上传上一步的准确FBX继续展开;输出带TEXCOORD_0的GLB、FBX、OBJ与UV布局PNG;13,159面,8,120个含UV分裂的顶点;`studio_uvUnwrappingRsp.json`留证 |
| 烘焙前坐标对齐 | Studio将网格居中并归一化,原高模为底面原点。用等比缩放1.05257233、底面中心平移对齐到原高模;UV哈希前后一致;原Studio下载文件保留 |
| 04 Blender贴图烘焙 | 对官网UV网格做selected-to-active,1024² diffuse/normal/AO/metallic/roughness;输出 `model_baked.glb` 和 `bake_maps/`,不重新展UV |
| 05 保留UV减面 | 13,159 > 2,000×1.3,实际触发Collapse减面到2,000面;保留原UV层和烘焙贴图,无再次UV展开。记录 `model_decimated.json`/`decimate.log` |
| 项目格式 | Blender Y-up、底面中心、-Z正面导出FBX,五通道打包1024² XPbr base/mix;转格式前后UV哈希相同 |
| 绑回原骨骼 | Blender从原 `enemy_dgx/GreatHorn/high_rig/rigged.glb` 复制原22骨并转权重,每顶点最多4个归一化权重;骨骼路径/绑定局部TRS与原角色逐项核对 |
| 复用动作 | 试验Prefab的Animator直接引用原Avatar和 `GreatHorn_Animator.controller`,仍播放原 `Clips/Idle.anim`、`Walk.anim`、`Attack.anim`;无重导出/重生成动画 |
所有工作中间件位于 `Tools/output/enemy_studio_trial/GreatHorn/`;完整来源、最终哈希与原资源哈希快照见 `trial.json`。官方低模、UV、烘焙前/后及减面结果分别保存,能够定位差异。
## 关键修正
初次直接使用工作台烘焙函数时出现脸部贴图错投、身体黑块。原高模Blender Z范围约0~1.054628,而Studio原UV模型约-0.500000~0.501953;低模还丢失原来的中心偏移。`bl_align_studio_uv.py` 仅做坐标和尺寸对齐、保持UV,之后重烘焙恢复正确外观。错误烘焙原稿 `diagnostic_unaligned_baked.glb` 只作为诊断保留,未交付到正式资源。
原成品动作是在旧网格脚底上收尾的,新拓扑直接转权重时,Walk/Attack出现约3毫米脚底穿地。检查发现一个脚尖顶点在四个腿骨的任何凸组合下仍会穿地,因此仅调权重不能解决。最终在Blender对新蒙皮网格两个脚底顶点(706/1543)各做游戏空间1毫米的局部上移;原骨骼、全局Transform、三段动作、UV与三角面数均未改变。绑定对照静态试验模的最大顶点差1.0044毫米,仍低于2毫米门槛。此局部形状差异保留于 `sole_fit.json`,没有通过抬整个角色或放宽3毫米门槛处理。
## 交付与验收
- 试验根目录 `AIClient/Assets/Bundles/Characters/Enemy/GreatHornStudio/`:`GreatHornStudio.prefab`(静态)、`GreatHornStudio_Enemy.prefab`(动画)、`GreatHornStudio.fbx`、`Rigged/GreatHornStudio_Rigged.fbx`、`GreatHornStudio.mat`、`GreatHornStudio_base.png`/`GreatHornStudio_mix.png`。
- 独立场景 `AIClient/Assets/Bundles/Scenes/Review/Enemy_GreatHornStudio_Review.unity`:上排原版,下排Studio版,依次Static/Idle/Walk/Attack,使用独立27层与X=300位置;Additive制作与截图后关闭,未重建角色总验收场景。
- 对比图 `AIClient/Assets/Screenshots/greathorn_studio_comparison.png`,1800×900。已目视核对两版静态与三动作采样;坐标修复后脸部、角、披风及身体贴图正常。
- 编辑QA:2000面、22骨、绑定高0.8000002m,原Avatar/控制器/三动作引用逐项一致,所有动画曲线均绑定到现有节点,每顶点最多4权重且归一化。
- 每段121帧采样(共363帧):Idle底面约-0.002~0.044毫米;Walk约-2.178~1.562毫米;Attack约-2.556~1.266毫米,均满足3毫米门槛。三段首尾顶点差0;Idle/Walk水平根漂移接近0,Attack保留原动作约25.07毫米的前冲。报告 `unity_verification.json`。
- 实际Play观察到Idle/Walk/Attack三状态,最大根骨倾角9.736°,外层角色根固定;报告 `play_verification.json`。验证后退出Play。
- `trial.json` 原Prefab、Avatar来源rig、控制器与三段成品动作的SHA256快照复核一致。
## 复现
```powershell
# 使用3D工作台已配置的依赖环境;已完成的Studio产物会复用
D:/UD/AI/XModel/LLM3DGraphics/.venv/Scripts/python.exe Tools/greathorn_studio_trial.py
# 本地格式转换、原骨架转权重、局部脚底适配、Pipeline入库与原动作QA
python Tools/greathorn_studio_finish.py --play-check
```
制作脚本不改写XModel外部工作台代码。Studio调用依赖已有项目混元会话,外传需用户授权;本次已明确授权该模型。Unity操作统一Pipeline并显式指定AIClient项目;有其他Play占用时先保留离线产物,协调后入库。
本次证明Studio低模/UV→烘焙→条件减面→原骨架/原动作复用可以跑通。两版最终同为2000面,Studio减面前13k拓扑的优势在进一步Collapse后需要重新评估;最终新网格为1783个源顶点(包含UV分裂),不能将这个数字与旧版950个焊接源顶点直接当成性能提升结论。正式替换前可结合近景布线、材质接缝、动作极值与目标设备预算决定采用哪版;本试验没有宣称全面优于原版。
@@ -0,0 +1,41 @@
# 岩团团:Studio 低模/UV 与原动作复用试验
2026-10-21,状态 validated。用户要求岩团团严格走混元 3D 生成高模后的第 2~5 步,再在 Blender 绑回原骨骼复用原动作。原始 `Tools/output/rockball_3d/rockball.glb` 上传腾讯混元 3D Studio(用户授权)。交付独立试验版 `RockBallStudio`,正式战场仍使用原 RockBall,未替换;没有调用 TokenRig/UniMate,也没有修改原动作。
| 阶段 | 实际执行与产物 |
| --- | --- |
| 原始高模 | `rockball.glb`(原 TokenRig 骨架与原静态模的同一来源),原文件保留 |
| 02 Studio 低模生成 | 官网低模拓扑:6946 三角面。`hunyuan_studio.json`/`studio_lowPolyTopologyRsp.json` |
| 03 Studio UV 展开 | 上一步 FBX 继续展开,输出带 UV 的 GLB/FBX/OBJ 与 UV 图。`studio_uvUnwrappingRsp.json` |
| 烘焙前对齐 | Studio 网格被居中归一化;`bl_align_studio_uv.py` 等比缩放 1.018444、底面中心对齐到原高模,UV 哈希前后一致 |
| 04 Blender 贴图烘焙 | 对 Studio UV 网格 selected-to-active 烘焙 1024² diffuse/normal/AO/metallic/roughness,不重新展 UV |
| 05 超目标 30% 保留 UV 减面 | 6946 > 2000×1.3,触发 Collapse 到 2000 面,UV 层保留(uv_mode=preserved_no_unwrap) |
| 项目格式 | Y-up、底面中心、-Z 正面 FBX;五通道打包 1024² XPbr |
| 绑回原骨骼 | `bl_transfer_skin.py` 从原 `rockball_dgx/high_rig/rigged.glb` 复制原 12 骨并转权重,骨路径与绑定局部 TRS 逐项核对;绑定对照静态模最大顶点差 0.032 mm |
| 复用动作 | Animator 直接引用原 Avatar 与 `RockBall_Animator.controller`,播放原 `Clips/Idle/Walk/Attack.anim` |
| 脚底修正 | 导出 306 个脚底顶点 × 363 帧原动作约束;没有顶点穿地超过 3 mm,未做任何局部修改 |
## 验收
| 动作(121 帧实际蒙皮) | 脚底范围 | 其他 |
| --- | --- | --- |
| Idle | -0.41~0.20 mm | 首尾差 0.000 mm,倾角 0.0° |
| Walk | -1.72~0.78 mm | 首尾差 0.000 mm,倾角 0.3° |
| Attack | -2.57~1.33 mm | 首尾差 0.000 mm,倾角 14.1° |
实际 Play 观察到 Idle/Walk/Attack 三状态,最大根骨倾角 13.71°,外层根固定。原 Prefab、控制器、三段动作与 rig 的 SHA256 在流程前后一致(`trial.json` originals)。
对比图 `AIClient/Assets/Screenshots/rockball_studio_comparison.png`(上排原版,下排 Studio 版:Static/Idle/Walk/Attack),两版外观与动作姿态一致。最终同为 2000 面;Studio 6946 面拓扑在减面后的布线优势需要结合近景再判断。
## 交付与复现
- 试验目录 `AIClient/Assets/Bundles/Characters/Animal/RockBallStudio/`:`RockBallStudio.prefab`(静态)、`RockBallStudio_Companion.prefab`(动画)、`RockBallStudio.fbx`、`Rigged/RockBallStudio_Rigged.fbx`、`.mat`、`_base.png`/`_mix.png`。
- 验收场景 `AIClient/Assets/Bundles/Scenes/Review/Studio_RockBall_Review.unity`(X=320,第 27 层),制作后关闭。
- 中间件与回执 `Tools/output/studio_trial/RockBall/`(trial.json、unity_verification.json、play_verification.json、sole_fit.json、foot_constraints.json)。
```powershell
D:/UD/AI/XModel/LLM3DGraphics/.venv/Scripts/python.exe Tools/studio_lowpoly_trial.py --actor RockBall --kind Animal --source Tools/output/rockball_3d/rockball.glb --rig Tools/output/rockball_dgx/high_rig/rigged.glb --prefab RockBall_Rigged.prefab
python Tools/studio_lowpoly_finish.py --actor RockBall --height 0.55 --play-check
```
`studio_lowpoly_trial.py`/`studio_lowpoly_finish.py`/`AgentScripts/StudioTrial.cs` 由大角首领试验泛化:角色、类型、原 Prefab、身高作为参数,骨数从原 Prefab 读取,脚底约束改用每个顶点自身四个骨骼权重;`bl_prepare_studio_trial.py`/`bl_fit_studio_soles.py` 增加可选角色名参数,大角首领原调用方式不变。
@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "RockBall T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "add8b48e49ad4f1784d82cdce4294e98",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 100001,
"references": [
"Doc/Design/Character/RockBall/rockball.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A rock-element evolution crown: a ring of three chunky faceted cyan crystals rising from a rounded grey stone base, the middle crystal tallest.",
"drafts": [
"Doc/Design/Character/RockBall/T2/drafts/T2_100001.png",
"Doc/Design/Character/RockBall/T2/drafts/T2_100002.png",
"Doc/Design/Character/RockBall/T2/drafts/T2_100003.png",
"Doc/Design/Character/RockBall/T2/drafts/T2_100004.png"
],
"generatedUtc": "2026-10-21T05:03:27Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "RockRhino T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "593da508895a45a587a913cc9fc1bf28",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 105001,
"references": [
"Doc/Design/Character/RockRhino/rockrhino.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A rock-element evolution helm crest: a chunky faceted teal crystal ridge, three crystals in a row from front to back, set in a rounded grey stone base.",
"drafts": [
"Doc/Design/Character/RockRhino/T2/drafts/T2_105001.png",
"Doc/Design/Character/RockRhino/T2/drafts/T2_105002.png",
"Doc/Design/Character/RockRhino/T2/drafts/T2_105003.png",
"Doc/Design/Character/RockRhino/T2/drafts/T2_105004.png"
],
"generatedUtc": "2026-10-21T05:21:08Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 841 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "SparkBird T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "67541eb9b41e43b082ef0337af4d0125",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 103001,
"references": [
"Doc/Design/Character/SparkBird/sparkbird.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A lightning-element evolution crest: a small golden crown with three solid zigzag lightning-bolt points in bright yellow and cyan.",
"drafts": [
"Doc/Design/Character/SparkBird/T2/drafts/T2_103001.png",
"Doc/Design/Character/SparkBird/T2/drafts/T2_103002.png",
"Doc/Design/Character/SparkBird/T2/drafts/T2_103003.png",
"Doc/Design/Character/SparkBird/T2/drafts/T2_103004.png"
],
"generatedUtc": "2026-10-21T05:14:03Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 816 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 KiB

@@ -0,0 +1,44 @@
# 剩余四敌人Studio低模/UV及原动作复用
2026-10-21完成。用户明确授权四份高模上传腾讯混元3D Studio,批处理配方 `Config/Art/StudioTrials/Enemies.json`。沿用大角首领已验证的2~5步,交付四个独立Studio版本;原版模型、Avatar、控制器和成品动画保留,未替换正式战场。
| 角色 | 源高模面数 | Studio UV面数 | 最终三角面 | 原骨数 | 高度 | 局部脚底校正顶点数 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 小角怪 Hornlet | 50000 | 6236 | 1999 | 22 | 0.50m | 0 |
| 疾跑怪 Dashlet | 50000 | 6162 | 1999 | 22 | 0.50m | 0 |
| 硬壳怪 Shellhorn | 50000 | 9550 | 1999 | 28 | 0.50m | 0 |
| 角怪队长 HornCaptain | 48236 | 9391 | 2000 | 22 | 0.60m | 0 |
## 制作过程
1. 官网Studio低模拓扑V1.5,三角面/低。逐角色上传自己的高模,再把精确下载的低模FBX提交Studio UV展开;保留任务ID、原始GLB/FBX/OBJ及UV布局PNG。
2. 烘焙前对齐Studio居中/归一化的网格和原高模,使用等比缩放、底面中心平移;UV哈希前后一致。角怪队长使用 `horncaptain_main.glb`,与原22骨的生成源哈希完全一致;原始50k及清理版均保留。
3. Blender在官网UV上烘焙1024²颜色/法线/AO/金属度/粗糙度。超过目标2000面的30%时再Collapse减面,保留UV层和贴图,不重复展开UV。小角怪、疾跑怪和硬壳怪得到1999面属于减面整数舍入,未添加无用面凑数。
4. Blender转回各自原骨架,应用各自原角色配方中的权重规则,最多4个归一化权重。候选Prefab直接引用原Avatar、原AnimatorController及原Clips/Idle、Walk、Attack;没有重新生成、重新收尾或复制成品动作。
5. 每角色重新检查实际蒙皮。仅在363帧约束中出现超过3毫米穿地的新脚底顶点才做游戏空间1毫米的局部几何校正;原骨骼、UV、动作与外层根Transform不变。无穿地的角色不套用大角首领的两个顶点编号。是否校正及数量以表格和每角色sole_fit.json为准。
## 资产与验证
- 四角色根目录 `AIClient/Assets/Bundles/Characters/Enemy/{Actor}Studio/`,包含 `{Actor}Studio.prefab`、`{Actor}Studio_Enemy.prefab`、静态/蒙皮FBX、XPbr材质和1024² base/mix贴图。
- 独立场景 `AIClient/Assets/Bundles/Scenes/Review/Studio_{Actor}_Review.unity`;截图 `Assets/Screenshots/{actor小写}_studio_comparison.png`,1800×900,上原版/下Studio版,Static/Idle/Walk/Attack。场景以Additive生成、采样后关闭,不覆盖原角色总验收场景。
- 五敌人总览 `Assets/Screenshots/enemy_studio_batch_overview.png`,对应独立场景 `Studio_Enemies_Overview.unity`;包含先前大角首领,统一0.8m展示高度仅供视觉比较,实际角色Prefab尺寸仍为表中数值。
- 每角色均核对原骨路径和绑定局部TRS、原Avatar/控制器引用、原动作所有曲线绑定、蒙皮权重、底面和尺寸。绑定对照误差低于2毫米。
- 三动作各121帧,共每角色363帧、四角色1452帧:没有塌陷或无效顶点;底面在±3毫米内,循环接缝小于1毫米,动作可见,倾角小于25°。Attack保留原动作的短距离前冲,不视作外层根漂移。
- 同一次Play检查四个角色,各观察到Idle/Walk/Attack三状态、方向正确、外层角色根固定。原Prefab/控制器/成品动作/rig哈希再次复核一致。
- 生成与QA回执 `Tools/output/studio_trial/{Actor}/`:trial.json、hunyuan_studio.json、studio_*Rsp.json、bake_alignment.json、model_decimated.json、static_export.json、sole_fit.json、unity_verification.json、play_verification.json。以status=validated为最终状态。
## 批处理复现
```powershell
python Tools/process_enemy_studio_batch.py --stage cloud
python Tools/process_enemy_studio_batch.py --stage finish
python Tools/process_enemy_studio_batch.py --stage play
python Tools/process_enemy_studio_batch.py --stage verify
```
云端阶段调用已安装的3D工作台集成,依赖已有项目登录会话;本次四模型外传已获明确授权。Unity资产、导入设置、Prefab、材质和场景均经Pipeline,显式指定AIClient项目。原始下载与中间件保持可追溯,结果作为独立候选供比较;最终同面数的画质和目标设备性能应分别评估。
## 五敌人战场替换与技能闭环样例(2026-10-21)
此后五敌人已全部替换正式 `PrototypeArena`,9槽×5类型。`BuildPrototype.FormalEnemies` 与验收检查同步;原 Avatar/控制器/动作继续复用。五类在真实 `PrototypeFlow` 内存隔离战斗观察到 Walk/Attack,攻击/受击特效音效正常(158次特效、122次声音),截图 `Assets/Screenshots/enemy_studio_arena.png`。回执 `Doc/Design/Combat/EnemyCombatFx/studio_arena.json`。
@@ -0,0 +1,197 @@
{
"status": "validated",
"actors": [
{
"actor": "Hornlet",
"name": "小角怪",
"source": "Tools/output/enemy_3d/Hornlet/hornlet.glb",
"sourceTriangles": 50000,
"studioTriangles": 6236,
"triangles": 1999,
"bones": 22,
"height": 0.5,
"bindErrorMm": 0.0281908069,
"soleVertices": 0,
"maxTilt": 10.8752375,
"motionSamples": [
{
"name": "Idle",
"originalClip": "Assets/Bundles/Characters/Enemy/Hornlet/Clips/Idle.anim",
"frames": 121,
"minY": -0.000115096569,
"maxY": 5.96046448e-08,
"movement": 0.008423355,
"tilt": 0.182384253,
"drift": 0.0,
"seam": 0.0
},
{
"name": "Walk",
"originalClip": "Assets/Bundles/Characters/Enemy/Hornlet/Clips/Walk.anim",
"frames": 121,
"minY": -0.0006853491,
"maxY": 0.00068333745,
"movement": 0.04498485,
"tilt": 3.06841588,
"drift": 0.0,
"seam": 0.0
},
{
"name": "Attack",
"originalClip": "Assets/Bundles/Characters/Enemy/Hornlet/Clips/Attack.anim",
"frames": 121,
"minY": -0.000669121742,
"maxY": 0.0003812611,
"movement": 0.121637732,
"tilt": 11.0213184,
"drift": 0.0249544084,
"seam": 0.0
}
]
},
{
"actor": "Dashlet",
"name": "疾跑怪",
"source": "Tools/output/enemy_3d/Dashlet/dashlet.glb",
"sourceTriangles": 50000,
"studioTriangles": 6162,
"triangles": 1999,
"bones": 22,
"height": 0.5,
"bindErrorMm": 0.0261153382,
"soleVertices": 0,
"maxTilt": 11.0649471,
"motionSamples": [
{
"name": "Idle",
"originalClip": "Assets/Bundles/Characters/Enemy/Dashlet/Clips/Idle.anim",
"frames": 121,
"minY": -0.0006045401,
"maxY": 4.85777855e-05,
"movement": 0.0115007143,
"tilt": 0.6205508,
"drift": 1.11758709e-08,
"seam": 0.0
},
{
"name": "Walk",
"originalClip": "Assets/Bundles/Characters/Enemy/Dashlet/Clips/Walk.anim",
"frames": 121,
"minY": -0.000568091869,
"maxY": 0.00143431127,
"movement": 0.03515787,
"tilt": 4.238314,
"drift": 1.86264515e-08,
"seam": 0.0
},
{
"name": "Attack",
"originalClip": "Assets/Bundles/Characters/Enemy/Dashlet/Clips/Attack.anim",
"frames": 121,
"minY": -0.0007119626,
"maxY": 0.000396505,
"movement": 0.1429233,
"tilt": 11.3336916,
"drift": 0.0251499582,
"seam": 0.0
}
]
},
{
"actor": "Shellhorn",
"name": "硬壳怪",
"source": "Tools/output/enemy_3d/Shellhorn/shellhorn.glb",
"sourceTriangles": 50000,
"studioTriangles": 9550,
"triangles": 1999,
"bones": 28,
"height": 0.5,
"bindErrorMm": 0.0279905289,
"soleVertices": 0,
"maxTilt": 11.324461,
"motionSamples": [
{
"name": "Idle",
"originalClip": "Assets/Bundles/Characters/Enemy/Shellhorn/Clips/Idle.anim",
"frames": 121,
"minY": -0.000730574131,
"maxY": 2.98023224e-08,
"movement": 0.0173166543,
"tilt": 1.60327649,
"drift": 7.450581e-09,
"seam": 0.0
},
{
"name": "Walk",
"originalClip": "Assets/Bundles/Characters/Enemy/Shellhorn/Clips/Walk.anim",
"frames": 121,
"minY": -0.000426262617,
"maxY": -0.000110596418,
"movement": 0.0472506844,
"tilt": 7.10674572,
"drift": 1.49011612e-08,
"seam": 0.0
},
{
"name": "Attack",
"originalClip": "Assets/Bundles/Characters/Enemy/Shellhorn/Clips/Attack.anim",
"frames": 121,
"minY": -0.00196000934,
"maxY": 0.0009786487,
"movement": 0.173831984,
"tilt": 11.7986069,
"drift": 0.0249543861,
"seam": 0.0
}
]
},
{
"actor": "HornCaptain",
"name": "角怪队长",
"source": "Tools/output/enemy_3d/HornCaptain/horncaptain_main.glb",
"sourceTriangles": 48236,
"studioTriangles": 9391,
"triangles": 2000,
"bones": 22,
"height": 0.6,
"bindErrorMm": 0.0319501669,
"soleVertices": 0,
"maxTilt": 12.1147614,
"motionSamples": [
{
"name": "Idle",
"originalClip": "Assets/Bundles/Characters/Enemy/HornCaptain/Clips/Idle.anim",
"frames": 121,
"minY": -0.000101685524,
"maxY": 0.0003542602,
"movement": 0.0129548572,
"tilt": 0.6308707,
"drift": 0.0,
"seam": 0.0
},
{
"name": "Walk",
"originalClip": "Assets/Bundles/Characters/Enemy/HornCaptain/Clips/Walk.anim",
"frames": 121,
"minY": -0.00204786658,
"maxY": 0.00033596158,
"movement": 0.09477278,
"tilt": 2.27967358,
"drift": 1.11758709e-08,
"seam": 0.0
},
{
"name": "Attack",
"originalClip": "Assets/Bundles/Characters/Enemy/HornCaptain/Clips/Attack.anim",
"frames": 121,
"minY": -0.00267779827,
"maxY": 0.00102874637,
"movement": 0.1298844,
"tilt": 12.6954126,
"drift": 0.0249544121,
"seam": 0.0
}
]
}
]
}
@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "ThunderLeopard T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "cabd4efe55d74a5f825cfe2eebf9bd3d",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 108001,
"references": [
"Doc/Design/Character/ThunderLeopard/thunderleopard.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A lightning-element evolution crown: a small silver-violet crown with three solid cyan zigzag lightning-crystal spikes, the middle one tallest.",
"drafts": [
"Doc/Design/Character/ThunderLeopard/T2/drafts/T2_108001.png",
"Doc/Design/Character/ThunderLeopard/T2/drafts/T2_108002.png",
"Doc/Design/Character/ThunderLeopard/T2/drafts/T2_108003.png",
"Doc/Design/Character/ThunderLeopard/T2/drafts/T2_108004.png"
],
"generatedUtc": "2026-10-21T05:31:50Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "TideWhale T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "3ff11134613d499b86a24fa0a29016fc",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 109001,
"references": [
"Doc/Design/Character/TideWhale/tidewhale.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A water-element evolution crown: a rounded seashell crown in pale blue and white, a spiral shell in the middle flanked by two smaller shells, fused into one piece with a pearl in front.",
"drafts": [
"Doc/Design/Character/TideWhale/T2/drafts/T2_109001.png",
"Doc/Design/Character/TideWhale/T2/drafts/T2_109002.png",
"Doc/Design/Character/TideWhale/T2/drafts/T2_109003.png",
"Doc/Design/Character/TideWhale/T2/drafts/T2_109004.png"
],
"generatedUtc": "2026-10-21T05:35:24Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

@@ -0,0 +1,27 @@
{
"id": "T2",
"name": "VineSprite T2 accessory",
"role": "T2 evolution head accessory",
"jobId": "a6523d8cae734158acdf90873aa2e79b",
"status": "completed",
"error": null,
"model": "Qwen/Qwen-Image-2.1-Turbo (LAN LLM3DGraphics local-images)",
"profile": "concept",
"size": [
1024,
1024
],
"seedStart": 107001,
"references": [
"Doc/Design/Character/VineSprite/vinesprite.png",
"Doc/Design/Character/FireCat/firecat.png"
],
"prompt": "Image 1 shows the companion creature that will wear this accessory: use it ONLY for its palette and element theme, do NOT draw the creature. Image 2 is STYLE ONLY: match its friendly polished chibi 3D mobile-game render and clean rounded readable shapes. Draw exactly ONE small evolution accessory object ALONE, as a game asset for image-to-3D: a chunky solid head-top piece with a flat or gently curved base that would sit on top of a round creature head, compact and roughly as wide as it is tall. Every part is one continuous attached solid piece: no floating gems, no separate sparks, droplets, petals or particles, no thin wires, no chains, no strings. Centered, front three-quarter view from slightly above, whole object in frame with generous margin. Pure solid white #FFFFFF background to all corners, soft studio light, tiny contact shadow. Simple smooth stylized surfaces suitable for a 400-triangle model with a 512 texture. No creature, no head, no body, no text, no watermark, no UI, no stand, no scenery. A grass-element evolution wreath crown: a thick ring of overlapping forest-green leaves with three fused pink blossoms on the front, solid and chunky.",
"drafts": [
"Doc/Design/Character/VineSprite/T2/drafts/T2_107001.png",
"Doc/Design/Character/VineSprite/T2/drafts/T2_107002.png",
"Doc/Design/Character/VineSprite/T2/drafts/T2_107003.png",
"Doc/Design/Character/VineSprite/T2/drafts/T2_107004.png"
],
"generatedUtc": "2026-10-21T05:28:16Z"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 801 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

@@ -0,0 +1,26 @@
{
"status": "pass",
"realFlow": true,
"isolatedInMemory": true,
"networkRewardRequests": false,
"allFiveTypes": true,
"studio": true,
"walked": [
0,
1,
2,
3,
4
],
"attacked": [
0,
1,
2,
3,
4
],
"effects": 158,
"sounds": 122,
"captured": true,
"Defeated": 9
}
@@ -0,0 +1,67 @@
# 伙伴技能特效与音效制作记录
2026-10-21:十位伙伴的技能表现已接入正式 `PrototypeArena`。本批补齐四条 TangoFlux 音效,九条计划音效均有真实产物及生成回执。
## 已制作资源
特效目录:`AIClient/Assets/Bundles/Combat/Partners/`。各行文件名均以 `Vfx_` 开头、`.prefab` 结尾。
| 伙伴 | 特效文件名 | 触发与形态 |
| --- | --- | --- |
| 石球 | RockBallGuard | shield:琥珀护环与石甲颗粒,跟随目标直到护盾耗尽/到期 |
| 火喵 | FireCatFlare | hit:火花与橙色冲击环;复用火焰蓄力、发射与弹道 |
| 芽芽 | BudBudBloom | heal:绿环、粉色花瓣与治疗十字 |
| 闪闪雀 | SparkBirdBolt | hit:连接施法挂点与命中目标的蓝色折线雷电 |
| 泡泡龟 | BubbleTurtleBubbles | slow:围住目标的蓝色泡泡 |
| 岩甲犀 | RockRhinoQuake | slow:贴地震波与飞散石块;石击沿用岩石命中 |
| 烈焰狮 | FlameLionBreath | ability release:面向目标的锥形喷焰;hit:火焰命中 |
| 藤灵 | VineSpriteVines | heal:上升藤蔓、叶片与绿环 |
| 雷纹豹 | ThunderLeopardClaw | hit:紫色雷电连接与三道爪痕 |
| 潮汐鲸 | TideWhaleTide | shield:半球水罩与涟漪,状态结束清理 |
Pipeline 同时制作六个共用低多边形网格:`SkillStone`、`SkillLeaf`、`SkillHealCross`、`SkillBubble`、`SkillWaterDome`、`SkillVineHelix`(`.asset`)。`PartnerSkillGlow.mat` 使用现有 `AIGame/EnemyCombatParticle` Shader,白纹理及顶点色;不修改敌人共用材质。所有 Prefab、材质、网格均在编辑器内持久化。
新增音效位于 `AIClient/Assets/Bundles/Sound/SFX/BattleSkills/`:
| 文件 | 用途 | 成品长度 | 实际 seed |
| --- | --- | --- | --- |
| Sfx_Heal.wav | 治疗 | 0.55s | 52005 |
| Sfx_Slow.wav | 减速 | 0.50s | 52007 |
| Sfx_Lightning.wav | 雷电命中 | 0.38s | 52008 |
| Sfx_EnemyHit.wav | 软受击 | 0.26s | 52009 |
按 `D:/UD/AI/XModel/TangoFlux_AI调用指南.md` 调用本地 `127.0.0.1:8012`。每条源音频2秒、50步、guidance 4.5,最多2条并发;65Hz高通、起音裁切、5ms淡入/50ms淡出、峰值约 -1.94dBFS。成品 PCM16/44.1kHz/双声道,Unity 导入为 PCM、DecompressOnLoad、保留采样率。源文件与请求缓存:`Tools/output/partner_skill_sfx/`;回执:`Doc/Design/Sound/BattleSkills/Partners/generation.json`;九条连听文件:同目录 `preview_all_nine.wav`。前五条保留 Slice 原始回执和真实 seed。本批未声称完成主观听审;发布授权审查沿用原 manifest 的 pending 状态。
## 标准制作与接入步骤
1. 在 `Config/Combat/partner_presentations_v1.json` 配置角色、效果索引、声音索引、地面效果、持续时间与池容量。数据效果仍由 `skill_runtime_v1.json` 的服务器逻辑决定。
2. 用 `BuildPartnerSkillFx.Build` 经 Unity Pipeline 制作/更新持久化美术资产,再用 `BuildBattleSkills.Build` 构建正式表现池并嵌入已有战场。
3. 声音按 TangoFlux 指南生成,保留 request/job/source/output 哈希;补登记 manifest,设置 Unity 导入参数。维护共用音效优先于按角色重复生成。
4. `BattleSkillPresentation` 仅消费已结算的 cast_start、release、projectile、hit、shield、heal、slow 等事件;原 Attack 仍按既有15种角色的 attackImpact 对齐。19个既有 SkillMuzzle 随角色朝向与T2缩放;表现组件不计算伤害/治疗/减速。
5. 验证索引与文件、音频格式及回执、真实轨迹、播放清理和画面,追加资源登记后完成。
正式池当前15类效果、76个根粒子实例、8个音源、9条音效、10个伙伴配置。雷电折线复用池中的 LineRenderer;运行时不创建材质、粒子或声音对象。雷电/群体治疗/减速同一次 cast 同种声音只播一次;普通软受击避免旧敌人声音与新伙伴声音重复叠播,硬壳/护盾反馈仍保留。
暂停与倍速作用于表现时钟及粒子;声音保留原始音高。过期的一次性事件跳过,未到期护盾和弹道可恢复。取消/死亡/目标消失/状态到期/battle_end/禁用均清理对应租约,代数标识避免旧租约停止刚复用的粒子。战斗结束保留计数供验收、清空播放对象。
## 验收证据
- `audio_config_validation.json`:十个配置与 Prefab、九条音效的源/请求/成品哈希、成功任务、起音/淡出/响度/零削波通过。
- `behavior.json`:十种专属效果与九种声音均触发;连接端点、多目标音效去重、超池复用、过期跳过、暂停/2倍速/静音、死亡/到期/取消/结束/禁用清理通过。23份既有服务器轨迹覆盖十个伙伴,全部回放至末尾无残留。
- `battle_visual.json`:真实 `PrototypeFlow` 消费服务器第20关T2轨迹并截图,验证正式战场、既有挂点和雷电命中。测试夹具不写真实账号。
- `Assets/Screenshots/partner_skills_overview.png`:十角色独立特效总览;`partner_skills_battle.png`:正式场景命中。已目视检查颜色、形态、源点到目标及亮背景可见度。
- `VerifyBattleRuntime.Assets`:正式战场76实例/8音源/9音效、19个局部-Z挂点、10伙伴/5敌人动作相位绑定通过。
- `python -m unittest discover -s Tools/tests -p test_skill_design.py`:8项通过;`python Tools/verify_partner_skills.py`、`python Tools/validate_skill_runtime.py` 通过。
尚未进行微信真机帧耗、内存与混音主观验收;本次为编辑器功能及视觉验收。本批不改服务器逻辑、数值或现有账号,未重启8080服务。收尾退出测试 Play,保留原编辑场景。
重建入口:
```text
python Tools/generate_partner_skill_sfx.py
Unity Pipeline: BuildPartnerSkillFx.Build -> BuildBattleSkills.Build
python Tools/verify_partner_skills.py
Unity Pipeline (Play): VerifyPartnerSkillFx.Behavior / ContactSheet
Unity Pipeline (Play): VerifyBattleRuntime.VisualSkills
Unity Pipeline (Stop): VerifyPartnerSkillFx.Finish / VerifyBattleRuntime.Assets
```
@@ -0,0 +1,92 @@
{
"status": "pass",
"profiles": 10,
"signaturePrefabs": 10,
"poolRoots": 76,
"voices": 8,
"audio": [
{
"id": "Sfx_FireCharge",
"seconds": 0.48,
"peakDb": -1.9386641491007355,
"rmsDb": -14.407821284878423,
"clippedSamples": 0,
"sha256": "686f9799eb264fcf310edb63dd69f75d16be94092bda40b3c341b0df18765217",
"actualSeed": 62100
},
{
"id": "Sfx_FireLaunch",
"seconds": 0.28,
"peakDb": -1.9386641491007355,
"rmsDb": -14.786814954199185,
"clippedSamples": 0,
"sha256": "e6f40a6d9a7e57f6fd56051c2393315c0610554921f5e26459eab2cbde40bbd2",
"actualSeed": 62101
},
{
"id": "Sfx_FireHit",
"seconds": 0.4,
"peakDb": -1.9386641491007355,
"rmsDb": -12.397172372455682,
"clippedSamples": 0,
"sha256": "d7c39fe8d2a270ab1241ee655f13d775f0e9c7cc0c3d38fdd6da2b33da493039",
"actualSeed": 62102
},
{
"id": "Sfx_RockHit",
"seconds": 0.32,
"peakDb": -1.9386641491007355,
"rmsDb": -17.7350875982902,
"clippedSamples": 0,
"sha256": "092735b139b22e0e5a1cd851c493fb1d6c9ff320cfdd33fdefc73db725a37a59",
"actualSeed": 62103
},
{
"id": "Sfx_Heal",
"seconds": 0.55,
"peakDb": -1.9386641491007355,
"rmsDb": -14.50466159857536,
"clippedSamples": 0,
"sha256": "61ab8a7cd7feed49646752ad921c50dbfbec33ce8d3b534d4451f3638ff5df89",
"actualSeed": 52005
},
{
"id": "Sfx_Shield",
"seconds": 0.65,
"peakDb": -1.9386641491007355,
"rmsDb": -14.618990028368117,
"clippedSamples": 0,
"sha256": "52119154552ac4fbbde0d94d34011be1749c019dec3764c31ecb7fae1b8fff37",
"actualSeed": 62104
},
{
"id": "Sfx_Slow",
"seconds": 0.5,
"peakDb": -1.9386641491007355,
"rmsDb": -18.172440503372695,
"clippedSamples": 0,
"sha256": "e191cc6baa46fa6e1c46f77eaa072495c52b4c75d47be98cfd7a81ca14a134c9",
"actualSeed": 52007
},
{
"id": "Sfx_Lightning",
"seconds": 0.38,
"peakDb": -1.9386641491007355,
"rmsDb": -15.270460646000476,
"clippedSamples": 0,
"sha256": "a8e6f806b3e62e8916929d39b63f9d6cfd1f534dc44f49f79d99a490753ed00a",
"actualSeed": 52008
},
{
"id": "Sfx_EnemyHit",
"seconds": 0.26,
"peakDb": -1.9386641491007355,
"rmsDb": -17.505279728308555,
"clippedSamples": 0,
"sha256": "2cdb0a6f272f1bd5fac3ffab34fffaa52104a38056debe944e7913d7cf6ef93f",
"actualSeed": 52009
}
],
"subjectiveListening": "not_asserted",
"releaseLicenseReview": "pending_upstream_review_per_guide"
}
@@ -0,0 +1,10 @@
{
"status": "pass",
"authoritative": true,
"persistentMuzzles": 19,
"t2ScaleApplied": true,
"flight": false,
"signature": true,
"effects": 14,
"networkAccountWrites": false
}
@@ -0,0 +1,191 @@
{
"status": "pass",
"profiles": 10,
"effectKinds": 15,
"poolRoots": 76,
"voices": 8,
"audioClips": 9,
"signatureEffectPlays": [
3,
1,
0,
2,
0,
1,
1,
1,
17,
1,
1,
2,
1,
1,
1
],
"soundPlays": [
3,
2,
2,
1,
2,
2,
2,
15,
1
],
"chainSoundOnce": true,
"beamEndpoints": true,
"poolReuse": true,
"pause": true,
"speed2": true,
"staleSkip": true,
"death": true,
"expiry": true,
"cancel": true,
"mute": true,
"endCleanup": true,
"disableCleanup": true,
"traceCases": 23,
"traceActors": 10,
"rows": [
{
"trace": "stage_10_t1_f1.json",
"events": 2894,
"effects": 225,
"sounds": 156
},
{
"trace": "stage_11_t1_f2.json",
"events": 2225,
"effects": 143,
"sounds": 121
},
{
"trace": "stage_12_t1_f0.json",
"events": 2338,
"effects": 174,
"sounds": 157
},
{
"trace": "stage_13_t1_f1.json",
"events": 3380,
"effects": 285,
"sounds": 196
},
{
"trace": "stage_14_t1_f2.json",
"events": 2458,
"effects": 184,
"sounds": 158
},
{
"trace": "stage_15_t1_f0.json",
"events": 2587,
"effects": 215,
"sounds": 198
},
{
"trace": "stage_16_t1_f1.json",
"events": 3626,
"effects": 361,
"sounds": 262
},
{
"trace": "stage_17_t1_f2.json",
"events": 2512,
"effects": 195,
"sounds": 167
},
{
"trace": "stage_18_t1_f0.json",
"events": 2866,
"effects": 240,
"sounds": 210
},
{
"trace": "stage_19_t1_f1.json",
"events": 3321,
"effects": 311,
"sounds": 221
},
{
"trace": "stage_1_t1_f1.json",
"events": 2920,
"effects": 185,
"sounds": 133
},
{
"trace": "stage_20_t1_f2.json",
"events": 2738,
"effects": 237,
"sounds": 210
},
{
"trace": "stage_20_t2_f0.json",
"events": 2476,
"effects": 193,
"sounds": 179
},
{
"trace": "stage_20_t2_f1.json",
"events": 3099,
"effects": 254,
"sounds": 177
},
{
"trace": "stage_20_t2_f2.json",
"events": 2488,
"effects": 180,
"sounds": 159
},
{
"trace": "stage_2_t1_f2.json",
"events": 2001,
"effects": 110,
"sounds": 105
},
{
"trace": "stage_3_t1_f0.json",
"events": 1758,
"effects": 98,
"sounds": 88
},
{
"trace": "stage_4_t1_f1.json",
"events": 3005,
"effects": 198,
"sounds": 133
},
{
"trace": "stage_5_t1_f2.json",
"events": 2188,
"effects": 134,
"sounds": 120
},
{
"trace": "stage_6_t1_f0.json",
"events": 2171,
"effects": 131,
"sounds": 111
},
{
"trace": "stage_7_t1_f1.json",
"events": 2770,
"effects": 204,
"sounds": 139
},
{
"trace": "stage_8_t1_f2.json",
"events": 2004,
"effects": 116,
"sounds": 97
},
{
"trace": "stage_9_t1_f0.json",
"events": 2199,
"effects": 151,
"sounds": 133
}
],
"networkAccountWrites": false
}
@@ -0,0 +1,7 @@
{
"status": "captured",
"profiles": 10,
"screenshot": "AIClient/Assets/Screenshots/partner_skills_overview.png",
"sampleSeconds": 0.14,
"networkAccountWrites": false
}
+64
View File
@@ -0,0 +1,64 @@
# 权威技能协议与正式战场接入
2026-10-21完成。独立火喵/岩团团样例已推广到正式战斗:十伙伴的普攻/主动技能及五敌人普攻,共25个技能;覆盖20主线关卡和5个属性挑战。8080本地开发服已更新,health返回combatProtocol=1;未发布Player或生产服。
## 版本与配置
- `Config/Combat/skill_runtime_v1.json` 是正式逻辑表,protocol=1、logicVersion=1,新战斗快照标记rulesVersion=3。原proposal保持design_only/runtimeEnabled=false,两个校验器分别报告设计和正式运行时状态,避免把旧设计文件当成正式入口。
- `greenfield.json` 保持battleRules=2,兼容旧客户端及旧挑战。新版客户端只在battle.begin/challenge.begin发送combatProtocol=1;没有该字段的旧客户端仍得到原规则。新客户端连接旧服务端时,也能接收旧规则战斗。
- CMake将正式技能表编入程序。开战原子保存原玩法配置、技能定义、gameplayHash、skillsHash、权威结果及完整事件轨迹;旧进行中战斗不会因新配置或程序重启重新计算。
## 逻辑内核
`combat_slice` 已由独立样例内核推广为共享纯数据内核,`combat_runtime` 从冻结玩法参数与正式技能表构造战斗。单位id为伙伴id或100+敌人槽;时间50ms整数tick、血量/攻击千分之一单位、位置毫米、倍率万分比。数值量化及前摇会改变新规则的节奏,不宣称与旧规则结果等价。
三波刷怪、多路前排阻挡/移动/漏怪、主动技能优先的单动作通道、前摇/释放/后摇、绝对冷却、投射物到达伤害、伤害/治疗/护盾/减速类型化行为、首领控制折扣、护盾和减速的刷新/过期均已接入。行为数组按actionId顺序执行;同cast/action/target不能重复命中。释放前死亡取消,释放后的火球独立存续,目标丢失不换目标,死亡和战斗结束只发一次。
开局预计算仍由服务端授权。battle.finish继续使用已冻结结果,忽略客户端won和elapsed字段;最早结算时间由readyAt约束,放弃/重试/首通奖励沿用原幂等事务。没有战中手动输入。
## 分页与恢复
| 操作 | 行为 |
| --- | --- |
| battle.begin/challenge.begin | 新客户端声明combatProtocol=1;返回snapshot和不含events的trace manifest |
| GET /game/state | 返回原场次的traceId/traceHash/初态/终态摘要,供重连恢复 |
| POST /game/command:battle.events | 按本玩家pendingBattle、activityId、traceId鉴权;cursor与limit读取事件,limit≤256 |
| battle.finish/abandon | 原事务结算;关闭后删除活动轨迹,后续分页返回activity_missing |
分页读取不修改日历、revision、钱包或operation log。每页返回原始JSON payload字符串及SHA256;客户端逐页校验、按原顺序拼接并核对整条traceHash,再开始播放。错误页、缺页、重复/乱序事件或不支持的版本不会回退成本地算伤害。请求可重试,持久化命令队列与分页读取分开。恢复当前实现从头重播原轨迹,沿用同一battleId及readyAt,不重新开战或发奖。
事件上限50000,正式内核最多2400tick。当前120组矩阵最大3626事件/299734字节(事件JSON),按需分页预载后开始播放;不是把全事件塞进每次存档响应。
## 客户端与表现
- `CombatTrace.cs`:协议DTO、版本/实体/事件顺序校验;`PrototypeApi.LoadCombat`:授权分页、哈希校验与有界重试。
- `PrototypeBattle.Trace.cs`:只读战斗模型。Tick只应用事件,不运行旧伤害/技能计算;血量、护盾、减速、死亡、漏怪、技能次数和统计都取服务器轨迹。
- `PrototypeFlow`:新旧战斗分支共存。新分支由同一时钟驱动动作、弹道、VFX/SFX与数据;低帧率仍消费全部数据事件,跳过过期一次性声音。结束、放弃、换页与禁用清理池。
- `BattleSkillPresentation.prefab`:5类特效、36个池实例、8个技能音源,复用已有5条TangoFlux音效和敌人反馈池。火焰伙伴有蓄力/发射/命中,其他投射物按元素着色;治疗/减速沿用现有标识。各伙伴更丰富的专属美术及余下4条计划音效未在本批补制。
- 15种角色的attackImpact读取各自原制作配方,分段采样原Attack以对齐逻辑释放点;零前摇护盾保持Idle并播放护盾。AnimationEvent不授权伤害。
- 战场持久化19个`SkillMuzzle`(10伙伴+9敌人槽),局部-Z为前,随角色朝向和T2体型缩放,可在Prefab调节;不在运行时创建挂点/材质/粒子对象。BuildPrototype重建、后续敌人替换均保留此约定。
## 验证
- 三组CTest全部通过:原样例、旧事务/规则5192项断言、正式技能协议与120组关卡/进化/阵容矩阵(覆盖25技能,超过30万项事件断言)。涵盖治疗相邻路线、首领减速、复合行为、未来波次、确定性、分页只读、账号隔离、快照变化不重算、旧客户端、属性挑战及幂等奖励。
- 23份C++导出轨迹→C#只读模型,覆盖全部20关及3套T2终章阵容;最终血量、护盾、减速、位置、死亡/漏怪、统计完全一致,错误序列被拒绝。
- 真正EventSystem UI+HTTP,18083专用数据库的1-5全T2六人阵容,1876事件。服务端进程重启后恢复相同battleId与traceHash,2×实播后最终状态与服务器奖励/统计一致;暂停、静音、火球、护盾、敌人攻击和结束清理通过。
- 最终Prefab挂点实播通过,T2火喵发射点与持久化挂点世界坐标一致;截图 `Assets/Screenshots/battle_skills_anchors.png`。完整UI截图 `battle_skills_network.png`。
- 真实账号与偏好已恢复。开发服更新前一致性SQLite备份及旧程序保留;重启后全部账号game_states与备份比较一致,包括已有冻结战斗。期间Windows旧进程文件锁曾延迟替换,确认进程完全退出后更新成功。部署回执 `deployment.json`。
矩阵用于验证执行、确定性和代表阵容可通关;首日实际解锁阵容的细致平衡、微信真机帧耗/内存、全部伙伴专属特效音效仍需后续验收。
## 入口
```powershell
cmake --build AIServer/build-g1 --config Release --target aiserver combat_runtime_tests game_tests combat_slice_tests
ctest --test-dir AIServer/build-g1 -C Release --output-on-failure
AIServer/build-g1/Release/combat_runtime_tests.exe Doc/Design/Combat/Runtime/server_validation.json Tools/output/combat_runtime/traces
python Tools/validate_skill_runtime.py
```
Unity Pipeline:`BuildBattleSkills.Build`(制作/挂点)、`VerifyBattleRuntime.Assets`/`Domain`(检查);实战测试使用专用18083账号,Begin→重启专用服务→ResumeAndFinish→Cleanup,勿对真实账号运行测试入口。开发服实际程序在AIServer/build/Release,运行中Windows会锁定exe;不要直接构建覆盖运行中的文件。新版本应先在其他输出目录验证,等待旧进程完全退出后替换。
## 后续完成:伙伴专属技能表现(2026-10-21)
上文记录的“专属特效/余四条音效待补”已完成:新增十种伙伴专属Prefab、四条TangoFlux音效,正式池现为15类/76根实例/8音源/9音效/10角色配置。治疗与减速也消费权威事件播放,真实轨迹23例、复用/去重/清理与正式战场截图通过。详见 `../PartnerSkills/Production.md`。微信真机性能、内存与主观混音仍待验收。
@@ -0,0 +1,23 @@
{
"status": "formal_runtime_contract_validated",
"runtimeIntegrated": true,
"generatedAudio": true,
"generatedSfxCount": 9,
"skills": 25,
"pets": 10,
"enemies": 5,
"stages": 20,
"presentationProfiles": 12,
"existingAssets": 2,
"plannedAssets": 18,
"sfxRecipes": 9,
"note": "Formal runtime table is separate from disabled proposals; nine audio clips generated; ten formal partner presentation profiles validated by verify_partner_skills.py",
"formalPartnerProfiles": 10,
"formalEffectKinds": 15,
"formalAudioClips": 9,
"protocol": 1,
"logicVersion": 1,
"rulesVersion": 3,
"runtimeSource": "Config/Combat/skill_runtime_v1.json",
"runtimeSourceSha256": "6125b71e519c9c35579e36be0d9b1f9810d9de898643b8eb9ba81d9f342e5ddb"
}
+10
View File
@@ -0,0 +1,10 @@
{
"combatProtocol": 1,
"pid": 62304,
"previousExe": "D:\\UD\\AI\\AIGame\\Tools\\output\\combat_runtime\\aiserver-before-combat-20261021-213915.exe",
"executableSha256": "173fd1c4df0e087f36a4ecb8b85b5857d1bba17e40f118f54b0a086d24dc1c6c",
"status": "enabled",
"backup": "D:\\UD\\AI\\AIGame\\AIServer\\data\\aiserver-before-combat-20261021-213915.db",
"gameStatesUnchanged": true,
"accounts": 1
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,9 @@
{
"status": "pass",
"authoritative": true,
"persistentMuzzles": 19,
"t2ScaleApplied": true,
"flight": true,
"effects": 3,
"networkAccountWrites": false
}
@@ -0,0 +1,11 @@
{
"status": "pass",
"effects": 15,
"profiles": 10,
"audioClips": 9,
"poolInstances": 76,
"voices": 8,
"anchors": 19,
"petPhases": 10,
"enemyPhases": 5
}
+123
View File
@@ -0,0 +1,123 @@
{
"status": "pass",
"cases": 23,
"all20Stages": true,
"rows": [
{
"stage": 10,
"events": 2894,
"won": true
},
{
"stage": 11,
"events": 2225,
"won": true
},
{
"stage": 12,
"events": 2338,
"won": true
},
{
"stage": 13,
"events": 3380,
"won": true
},
{
"stage": 14,
"events": 2458,
"won": true
},
{
"stage": 15,
"events": 2587,
"won": true
},
{
"stage": 16,
"events": 3626,
"won": true
},
{
"stage": 17,
"events": 2512,
"won": true
},
{
"stage": 18,
"events": 2866,
"won": true
},
{
"stage": 19,
"events": 3321,
"won": true
},
{
"stage": 1,
"events": 2920,
"won": true
},
{
"stage": 20,
"events": 2738,
"won": true
},
{
"stage": 20,
"events": 2476,
"won": true
},
{
"stage": 20,
"events": 3099,
"won": true
},
{
"stage": 20,
"events": 2488,
"won": true
},
{
"stage": 2,
"events": 2001,
"won": true
},
{
"stage": 3,
"events": 1758,
"won": true
},
{
"stage": 4,
"events": 3005,
"won": true
},
{
"stage": 5,
"events": 2188,
"won": true
},
{
"stage": 6,
"events": 2171,
"won": true
},
{
"stage": 7,
"events": 2770,
"won": true
},
{
"stage": 8,
"events": 2004,
"won": true
},
{
"stage": 9,
"events": 2199,
"won": true
}
],
"corruptTraceRejected": true
}
@@ -0,0 +1,22 @@
{
"status": "pass",
"endpoint": "http://127.0.0.1:18083",
"stage": 5,
"tier": 2,
"authoritative": true,
"hashVerified": true,
"serverRestartRecovery": true,
"pause": true,
"mute": true,
"speed2": true,
"flight": true,
"shield": true,
"enemyAttack": true,
"finalStateExact": true,
"statsMatch": true,
"events": 1876,
"won": true,
"sounds": 83,
"cleanup": true,
"realAccountWrites": false
}
@@ -0,0 +1,40 @@
# 火喵/岩团团技能闭环样例
2026-10-21完成独立样例。五敌人 Studio 模型已替换正式 PrototypeArena;本页的新技能逻辑则在独立验收场景运行。主线仍是 battleRules=2,未接 battle.begin/battle.events,未重启或部署开发服,未改变旧在途挑战、账号或奖励协议。
## 已完成
- `AIServer/src/combat_slice.hpp/.cpp`:纯 C++ 逻辑内核;50ms整数 tick,千分之一血量/攻击、毫米位置。实现施法通道、主动技能优先、前摇/释放/后摇、冷却、投射物、伤害/护盾、过期、死亡与取消。无 Unity、墙上时钟、数据库依赖;当前只编入独立 combat_slice_tests 目标,未编入线上 aiserver。
- `Config/Combat/skill_slice.json`:隔离样例配置;岩团团前排、火喵后排、三个小角怪。敌人血量为原配置×2以覆盖护盾与近战,属于验收场景参数,不是20关的新平衡。原玩法和技能 proposal 的冻结副本保存在 trace 中,校验其内容及 SHA256。
- `AIClient/Assets/Bundles/Combat/SkillSlice/trace.json`:由 C++ 导出,219为最后 tick、366事件、36次施法、12颗火球、30次唯一命中。客户端只播放事件,不再计算该样例的伤害。`Tools/export_skill_slice.py` 先保存输入原始字节到 `Tools/output/skill_slice_inputs/`,回执 `export.json` 记录输入及轨迹哈希;验证/Play回执绑定同一轨迹哈希,最新配置变化不会混入旧轨迹。
- `SkillSlicePlayer.cs`:前摇、释放、到达和血量变化使用同一播放时钟;原 Attack 按各角色制作配方的 attackImpact 分段采样,火球在到达事件才扣血。拱形弹道仅影响外观;逻辑到达 tick 不变。已经释放的火球不因施法者死亡而撤回;释放前死亡取消。
- 持久化 `SkillSlice.prefab`:五实体的模型/Muzzle/Animator绑定,5类特效、24个池实例、8个技能音源;复用现有敌人反馈池。蓄力按 castId、护盾按 entityId、火球按实例租约清理。音效开关、暂停/恢复、1×/2×、低帧率过期声音跳过、结束/禁用清理已实现。
- 五条 TangoFlux 音效:FireCharge 0.48s、FireLaunch 0.28s、FireHit 0.40s、RockHit 0.32s、Shield 0.65s。按项目指南英文提示、2秒原稿、50步、guidance4.5、并发≤2生成,再裁切/淡入淡出。实际 seed/请求/任务ID/哈希以 `Doc/Design/Sound/BattleSkills/Slice/generation.json` 为准;原始计划 seed 保留在计划表中,没有冒称与生成请求相同。
## 验证与查看
- C++ 30项断言:起手无伤害、延迟到达、同 tick 零前摇护盾、动作互斥、后摇、冷却边界、死亡前取消、释放后存续、丢失目标不换目标、唯一死亡、护盾刷新不叠加、过期、元素防御、确定性与输入边界。
- `Tools/verify_skill_slice.py`:事件顺序/唯一命中/火球到达 tick/冻结输入哈希、五条音效源稿及输出哈希、格式、起音、尾部淡出和零削波通过。人工听感未由自动检查代替;试听 `Doc/Design/Sound/BattleSkills/Slice/preview.wav`。
- Unity实际 Play:火球到达前后血量检查通过;1×、2×、0.73秒低帧率步进的最终血量、护盾、位置、死亡/离场状态与 C++ 一致;暂停不前进、静音、重复结束、禁用清理通过。回执 `assets.json`、`play.json`、`validation.json`。
- 直接打开 `Assets/Bundles/Scenes/Review/SkillSlice_Review.unity` 后 Play 可看独立样例。它不会载入账号或发奖励;结束后保持结果,重进 Play 可重播。未覆盖当前 Boot 场景。
- 截图 `Assets/Screenshots/skill_slice_fireball.png`、`skill_slice_shield.png`。截图为暂停时刻,粒子额外推进30ms刷新几何,仅供视觉检查,不推进逻辑时钟。
## 复现
```powershell
cmake --build AIServer/build-g1 --config Release --target combat_slice_tests
python Tools/export_skill_slice.py
python Tools/verify_skill_slice.py
python Tools/validate_skill_design.py
```
Unity经Pipeline依次运行 `BuildSkillSlice.Build`、`VerifySkillSlice.Assets`;Play中运行 `VerifySkillSlice.Play`,结束后停止。TangoFlux重制入口为 `Tools/generate_skill_slice_sfx.py`,有效源稿按请求哈希复用。
## 后续接入边界
完整25技能、治疗/减速、多路波次、trace分页和网络协议兼容仍待实现;不能把独立样例视为 battleRules=3 主线迁移完成。下一阶段将该内核接入服务端授权战斗与冻结配置,客户端加载权威轨迹,覆盖10伙伴/20关平衡及旧挑战恢复后再切换规则。当前计划音效清单为5/9已生成,Heal/Slow/Lightning/EnemyHit仍待制作。TangoFlux权重依项目指南为非商业研究用途,保留许可核查边界,未宣称商用放行。
## 权威技能协议与正式战场接入(2026-10-21)
后续已将独立样例推广到正式技能协议与全关战场,见 [../Runtime/Production.md](../Runtime/Production.md)。本页保留独立样例的原始制作记录;正式配置、分页、恢复与客户端入口以Runtime文档为准。
+9
View File
@@ -0,0 +1,9 @@
{
"status": "pass",
"prefab": "Assets/Bundles/Combat/SkillSlice/SkillSlice.prefab",
"actors": 5,
"effectKinds": 5,
"poolInstances": 24,
"voices": 8,
"audioClips": 5
}
+27
View File
@@ -0,0 +1,27 @@
{
"status": "exported",
"inputs": [
{
"source": "Config/Gameplay/greenfield.json",
"snapshot": "Tools/output/skill_slice_inputs/greenfield.json",
"field": "frozenGameplay",
"sourceSha256": "2787887803fd365816e0d7d3f3a06386daddb1bbf08d0e7e40a9ec5393d6d5e2",
"payloadSha256": "5c2229d1c4701d889b239ff036966bd1dab872eeccf202c0e1726f5d7a6a32a4"
},
{
"source": "Config/Combat/skill_system_v1.proposal.json",
"snapshot": "Tools/output/skill_slice_inputs/skill_system_v1.proposal.json",
"field": "skillDefinitions",
"sourceSha256": "9749629b3914ec9135389f2f6ccaffb072010c26feb7d2680e90ae9f4994fc6c",
"payloadSha256": "5b64a277ee3d246e864f20285406ec8087756a6d7ae4a66c0779377c6e594df6"
},
{
"source": "Config/Combat/skill_slice.json",
"snapshot": "Tools/output/skill_slice_inputs/skill_slice.json",
"field": "scenario",
"sourceSha256": "2af74ebfca1dd556b5512efcc18983aa99a3ebca34b0f22776dc4aef1b178607",
"payloadSha256": "5e429157decd5ad6a1ef7d3c16f9cc08498942ff09c29450d85dbf841b7c0de8"
}
],
"traceSha256": "cb5e34b8c625d58700cff87aec357764f475bb1db19208a006320eb209124827"
}
@@ -0,0 +1,23 @@
[
{
"name": "Vfx_Skill_Fireball",
"count": 1,
"position": "(200.00, 1.80, 0.08)",
"bounds": "Center: (199.99, 1.79, 0.11), Extents: (0.32, 0.32, 0.32)",
"layer": 30
},
{
"name": "BrightCore",
"count": 1,
"position": "(200.00, 1.80, 0.08)",
"bounds": "Center: (200.03, 1.82, 0.07), Extents: (0.14, 0.14, 0.14)",
"layer": 30
},
{
"name": "Vfx_Skill_Shield",
"count": 1,
"position": "(200.00, 0.80, 0.48)",
"bounds": "Center: (199.99, 0.81, 0.45), Extents: (1.46, 1.46, 1.46)",
"layer": 30
}
]
@@ -0,0 +1,23 @@
[
{
"name": "Vfx_Skill_FireHit",
"count": 14,
"position": "(200.00, 0.80, 0.77)",
"bounds": "Center: (200.01, 0.81, 0.76), Extents: (0.18, 0.17, 0.16)",
"layer": 30
},
{
"name": "ImpactRing",
"count": 1,
"position": "(200.00, 0.80, 0.77)",
"bounds": "Center: (200.01, 0.76, 0.78), Extents: (1.31, 1.31, 1.31)",
"layer": 30
},
{
"name": "Vfx_Skill_Shield",
"count": 1,
"position": "(200.00, 0.80, 0.48)",
"bounds": "Center: (200.00, 0.77, 0.48), Extents: (1.46, 1.46, 1.46)",
"layer": 30
}
]
+19
View File
@@ -0,0 +1,19 @@
{
"status": "pass",
"traceSha256": "cb5e34b8c625d58700cff87aec357764f475bb1db19208a006320eb209124827",
"authoritativeCppTrace": true,
"productionRulesChanged": false,
"events": 366,
"won": true,
"pause": true,
"speed2": true,
"lowFrameRate": true,
"arrivalDamage": true,
"finalStateExact": true,
"mute": true,
"disableCleanup": true,
"liveSounds": 44,
"fireballScreenshot": true,
"shieldScreenshot": true,
"networkAccountWrites": false
}
@@ -0,0 +1,49 @@
{
"status": "pass",
"events": 366,
"casts": 36,
"projectiles": 12,
"hits": 30,
"deaths": 3,
"traceSha256": "cb5e34b8c625d58700cff87aec357764f475bb1db19208a006320eb209124827",
"frozenInputs": {
"Config/Gameplay/greenfield.json": "2787887803fd365816e0d7d3f3a06386daddb1bbf08d0e7e40a9ec5393d6d5e2",
"Config/Combat/skill_system_v1.proposal.json": "9749629b3914ec9135389f2f6ccaffb072010c26feb7d2680e90ae9f4994fc6c",
"Config/Combat/skill_slice.json": "2af74ebfca1dd556b5512efcc18983aa99a3ebca34b0f22776dc4aef1b178607"
},
"currentSourceChanged": [],
"audio": [
{
"id": "Sfx_FireCharge",
"seconds": 0.48,
"rmsDb": -14.407821284878423,
"clippedSamples": 0
},
{
"id": "Sfx_FireLaunch",
"seconds": 0.28,
"rmsDb": -14.786814954199185,
"clippedSamples": 0
},
{
"id": "Sfx_FireHit",
"seconds": 0.4,
"rmsDb": -12.397172372455682,
"clippedSamples": 0
},
{
"id": "Sfx_RockHit",
"seconds": 0.32,
"rmsDb": -17.7350875982902,
"clippedSamples": 0
},
{
"id": "Sfx_Shield",
"seconds": 0.65,
"rmsDb": -14.618990028368117,
"clippedSamples": 0
}
],
"subjectiveListening": "not_asserted",
"productionIntegrated": false
}
+14
View File
@@ -207,3 +207,17 @@ proposal文件显式 `runtimeEnabled=false`,现有CMake和客户端加载器
## 已落地的敌人表现批次(2026-10-21)
五类敌人的攻击与普通/硬甲/护盾受击表现已作为现有battleRules=1/2的适配层接入。实际完成8套特效、8条TangoFlux短音效、32实例/8音源播放池;真实PrototypeFlow隔离战斗及暂停/倍速/静音通过。完整制作记录见 [EnemyCombatFx/Production.md](EnemyCombatFx/Production.md)。此前BattleSkills的9条计划音效清单仍保持原计划状态,不能与本批8条敌人音效混算;battleRules=3技能逻辑内核、动作冲击相位与伤害同步、伙伴元素技能仍按上文阶段实施。
## 五敌人战场替换与技能闭环样例(2026-10-21)
火喵与岩团团已完成独立 C++ 事件轨迹→Unity 时钟/动作/5类特效/5条TangoFlux音效的可运行样例,详见 [SkillSlice/Production.md](SkillSlice/Production.md)。这一步未接主线 battle.begin/events,未切换 battleRules=3;原25技能的全关迁移仍待完成。计划音效清单现为5/9已生成、4/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` 的资源、流程和验证回执。
+38 -2
View File
@@ -322,10 +322,46 @@ UI 音效换成 v2 一次性短音效(0.12~0.8 秒)并接入运行时。`U
## G4 属性挑战(2026-10-21)
首页「活动」在通过 1-1 后打开五场元素试炼。火、草、岩、电、水各一场,只自动上阵已拥有的对应元素伙伴,主线阵容不变,不消耗弹珠。首次胜利给该元素指定伙伴 10 碎片和一枚徽章;再次胜利只在用时更短时刷新纪录。没有对应伙伴时提示去捕捉,不要求付费。存档从 schema 9 迁到 10,只补空的徽章和纪录,不发奖励。好友和操作活动模板还没做。服务端 `game_tests` 覆盖锁定、缺伙伴、放弃、首次发奖和重复不发奖。
首页「活动」在通过 1-1 后打开五场元素试炼。火、草、岩、电、水各一场,只自动上阵已拥有的对应元素伙伴,主线阵容不变,不消耗弹珠。首次胜利给该元素指定伙伴 10 碎片和一枚徽章;再次胜利只在用时更短时刷新纪录。没有对应伙伴时提示去捕捉,不要求付费。存档从 schema 9 迁到 10,只补空的徽章和纪录,不发奖励。操作活动模板还没做。服务端 `game_tests` 覆盖锁定、缺伙伴、放弃、首次发奖和重复不发奖。
- 2026-10-21 10 个伙伴全部换成正式模型并接入战斗与肖像(新做藤蔓灵/雷鸣豹/潮汐鲸,烈焰狮等由另一工具完成)。隔离 18081 种子账号 1-5 实战验收通过。
## 排行榜(2026-10-21)
首页「排行」读取服务器已确认的主线通关数和五场试炼最短用时。同成绩先比达成时间,再比玩家编号;没有成绩不上榜,页面显示前 20 名。客户端不能提交分数。存档从 schema 10 迁到 11 时,只给已有成绩盖上本次进入的时间,不发奖励。没有时间的旧成绩排在同成绩之后。正在进行的弹珠或战斗也可以看榜,不会被榜单请求结算。当前 8080 仍是上一版程序,要重启后玩家才会看到榜;在那之前点击排行会提示服务正在更新。
首页「排行」读取服务器已确认的主线通关数和五场试炼最短用时。同成绩先比达成时间,再比玩家编号;没有成绩不上榜,页面显示前 20 名。客户端不能提交分数。存档从 schema 10 迁到 11 时,只给已有成绩盖上本次进入的时间,不发奖励。没有时间的旧成绩排在同成绩之后。正在进行的弹珠或战斗也可以看榜,不会被榜单请求结算。8080 已在 2026-10-21 15:07 重启,排行已接通。
## 好友(2026-10-21)
首页「好友」按玩家编号查找,支持申请、接受、拒绝、撤回、删除、屏蔽、查看阵容和营地布置。好友、申请、屏蔽各最多 20 人。赠礼每天最多送出 5 次、收到 5 次,每次给对方 20 金币;不能送给自己,同一对好友每天只允许一个方向,重复提交同一次请求不会再次入账。存档从 schema 11 迁到 12 时只补空名单,不发金币。进行中的战斗也可以打开好友页。留言、实时聊天和突袭未做。8080 已在 2026-10-21 15:07 重启,好友和排行已接通。服务端 `game_tests` 覆盖互访、单向赠礼、次数上限和空迁移。
## 钓鱼(2026-10-21)
属性挑战页的「小镇钓鱼」进入钓鱼。通过 1-1 后可玩,每局消耗 1 枚弹珠,每天 5 局,放弃也占次数。服务器开始时冻结 8 条鱼汛,单局 20 秒,超时后再等 3 秒,之后只能放弃。客户端回传点击的鱼和时间,服务器重算积分;不能直接提交分数,超出当前时间的点击整单拒绝。3 分得 10 金币,5 分得 20 金币,8 分得 30 金币和 5 糖果。低于 3 分不返还弹珠。个人最佳只刷新纪录。同一请求重放不重复入账。进行中的弹珠、战斗或钓鱼互相挡住。存档从 schema 12 迁到 13 时只补 0 次和最佳 0 分,不发奖励。寻宝、派对、画册、温泉和首领挑战未做。服务端 `game_tests` 5101 项断言通过,覆盖锁定、消耗、伪造分数、未来点击、重放、放弃、次数上限、日切和空迁移。8080 已在 2026-10-21 16:42 重启,重启前备份为 `AIServer/data/aiserver-before-schema13-20261021-164141.db` 及其 wal、shm。未向真实账号发送请求;玩家下次进入时迁到 schema 13,只补 0 次和最佳 0 分。未构建 Player。
## 营地寻宝(2026-10-21)
好友页在双方已是好友、并且自己通过 1-1 之后,可以对这位好友寻宝。每天 3 次,同一位好友每天一次。服务器按自己的通关数从活动池发奖:1 关 10 金币,4 关 20 金币,10 关 30 金币和 5 糖果。客户端不能指定抽到哪一件。奖励不加给对方,也不减少对方的金币、弹珠或装饰。同一请求重放不重复入账。进行中的战斗也可以寻宝。存档从 schema 13 迁到 14 时只补 0 次,不发奖励。突袭仍会播放战斗,这次没做。服务端 `game_tests` 5192 项断言通过,覆盖未结交、未通关、伪造事件、战斗进行中发奖、对方营地不变、重放、同一营地当天一次、每日 3 次、次日恢复、10 关分档和空迁移。8080 已在 2026-10-21 20:38 重启,重启前备份为 `AIServer/data/aiserver-before-schema14-20261021-203836.db` 及其 wal、shm。未向真实账号发送请求;玩家下次进入时迁到 schema 14,只补 0 次寻宝。未改伙伴模型和战场。
- 2026-10-21 伙伴 T2 进化外观:T1 模型+骨骼挂件(9/10,潮汐鲸待混元额度),战斗按 tier 切换 Visual/VisualT2;隔离 18081 全 T2 阵容 1-5 实战通过。
## 五敌人战场替换与技能闭环样例(2026-10-21)
五类敌人的 Studio 低模已替换正式战场,原Avatar/控制器/三动作不变;45个模型引用、尺寸/贴地和五类型 Walk/Attack、攻击受击反馈通过。保留现有伙伴及T2,不重建整体战场。
火喵/岩团团独立技能样例实现 C++ 50ms整数tick逻辑、动作通道和阶段、投射物到达伤害、护盾及特效音效播放。C++30项检查、Unity1×/2×/暂停/低帧率最终状态一致、静音和清理通过;生成5条TangoFlux音效。生产服务器和主线仍旧规则,未进行网络轨迹协议接入或20关规则迁移。记录 `Doc/Design/Combat/SkillSlice/Production.md`。
## 权威技能协议与正式战场接入(2026-10-21)
新客户端battle.begin/challenge.begin声明combatProtocol1,服务端冻结25技能与配置、结果和事件,分页只读获取。PrototypeBattle.Trace仅应用权威事件,统一动作/特效/音效及数据时钟;旧客户端与旧战斗仍走原规则。正式战场持久化技能池和19个可调挂点,T2缩放同步。
120组C++关卡/进化/阵容矩阵覆盖25技能;23份跨关轨迹在C#最终状态与统计一致;18083真实UI全T2的1-5经服务重启恢复相同场次,实播/结算通过。8080开发服已更新,旧程序与SQLite一致性备份保留,全部game_states核对不变。制作记录 `Doc/Design/Combat/Runtime/Production.md`。未发布Player或生产服,真机性能与完整伙伴专属音效特效仍待完成。
### 2026-10-21:伙伴技能表现补齐
已完成十伙伴专属技能VFX及剩余四条TangoFlux声音,正式战场15类效果/76池根/8音源/9音效。23份服务器轨迹表现回放、暂停倍速静音、去重与生命周期清理、正式战场视觉验收通过;资源已登记。记录 `Doc/Design/Combat/PartnerSkills/Production.md`。后续为微信真机性能和混音验收。
### 2026-10-21:最新技能规则的首日前五关验收
隔离新账号只用初始岩团团/火喵及教学芽芽,正常两次发射、训练至Lv.5、领取基础补给和推荐布阵,真实UI走通1-1~1-5,全程T1,无资源或通关状态预置。五份权威轨迹哈希、结果、奖励、统计和最终钱包与C++事务路径一致;重打1-5不重复发奖。最终金币720/糖果110/弹珠62。修复训练资源不足时仍要求直接训练的引导及隐藏敌人Animator逐帧警告,专项UI/实战通过。新增首日CTest,四组服务端回归通过。结果与边界见 [G3/FirstFiveAcceptance.md](G3/FirstFiveAcceptance.md)。真实账号恢复,18085测试服关闭,Boot无脏状态;未构建Player或重启8080,真机性能仍待测。
@@ -0,0 +1,8 @@
{
"status": "pass",
"inactiveParent": true,
"disabledAnimator": true,
"reenabledSampling": true,
"hiddenUnit": true,
"warnings": 0
}
+18
View File
@@ -0,0 +1,18 @@
{
"status": "pass",
"realAccountRestored": true,
"coinsCandyLevelShotsRosterFormationUnchanged": true,
"playMode": "stopped",
"scene": "Assets/Scenes/Boot.unity",
"sceneDirty": false,
"gameView": [
1080,
1920
],
"isolatedPort": 18085,
"isolatedServerStopped": true,
"developmentPort8080Healthy": true,
"postfixConsoleCursor": 350546,
"postfixConsoleErrors": 0,
"postfixConsoleWarnings": 0
}
+42
View File
@@ -0,0 +1,42 @@
{
"status": "pass",
"cases": [
{
"stage": 1,
"traceHashExact": true,
"outcomeExact": true,
"rewardExact": true,
"statsExact": true
},
{
"stage": 2,
"traceHashExact": true,
"outcomeExact": true,
"rewardExact": true,
"statsExact": true
},
{
"stage": 3,
"traceHashExact": true,
"outcomeExact": true,
"rewardExact": true,
"statsExact": true
},
{
"stage": 4,
"traceHashExact": true,
"outcomeExact": true,
"rewardExact": true,
"statsExact": true
},
{
"stage": 5,
"traceHashExact": true,
"outcomeExact": true,
"rewardExact": true,
"statsExact": true
}
],
"finalWalletRosterFormationExact": true,
"repeatClearNoReward": true
}
@@ -0,0 +1,7 @@
{
"status": "pass",
"authoritative": true,
"finalStateExact": true,
"animatorWarnings": 0,
"errors": 0
}
+973
View File
@@ -0,0 +1,973 @@
{
"battles": [
{
"formation": [
0,
1,
-1,
-1,
-1,
-1
],
"level": 2,
"result": {
"chest": 0,
"configVersion": "greenfield-1-2787887803fd",
"defeated": 9,
"durability": 10,
"duration": 64.15,
"firstClear": true,
"id": "first-day-command-9",
"leaks": [
0,
0,
0
],
"logicVersion": 1,
"reward": {
"balls": 3,
"candy": 40,
"coins": 80
},
"rulesVersion": 3,
"stageId": 1,
"stats": [
{
"absorbed": 0.0,
"damage": 16.04,
"healing": 0.0,
"pet": 0,
"skills": 8,
"slot": 0
},
{
"absorbed": 0.0,
"damage": 775.96,
"healing": 0.0,
"pet": 1,
"skills": 7,
"slot": 1
}
],
"traceHash": "134ea42cbb43ac95049c5fd27797134f5184f8cf52cc36d2516f3552e001b912",
"won": true
},
"shots": 2,
"stage": 1
},
{
"formation": [
0,
1,
-1,
-1,
-1,
-1
],
"level": 2,
"result": {
"configVersion": "greenfield-1-2787887803fd",
"defeated": 9,
"durability": 10,
"duration": 64.3,
"firstClear": true,
"id": "first-day-command-18",
"leaks": [
0,
0,
0
],
"logicVersion": 1,
"reward": {
"balls": 3,
"candy": 50,
"coins": 90
},
"rulesVersion": 3,
"stageId": 2,
"stats": [
{
"absorbed": 0.0,
"damage": 15.0,
"healing": 0.0,
"pet": 0,
"skills": 8,
"slot": 0
},
{
"absorbed": 0.0,
"damage": 838.65,
"healing": 0.0,
"pet": 1,
"skills": 7,
"slot": 1
}
],
"traceHash": "11b1bc2504da5de50cc683b82fc9257645d9229c743f79201bf6130598f0e574",
"won": true
},
"shots": 2,
"stage": 2
},
{
"formation": [
0,
2,
1,
-1,
-1,
-1
],
"level": 3,
"result": {
"chest": 1,
"configVersion": "greenfield-1-2787887803fd",
"defeated": 9,
"durability": 10,
"duration": 76.55,
"firstClear": true,
"id": "first-day-command-23",
"leaks": [
0,
0,
0
],
"logicVersion": 1,
"reward": {
"balls": 3,
"candy": 60,
"coins": 100
},
"rulesVersion": 3,
"stageId": 3,
"stats": [
{
"absorbed": 64.0,
"damage": 321.2,
"healing": 0.0,
"pet": 0,
"skills": 10,
"slot": 0
},
{
"absorbed": 0.0,
"damage": 260.4,
"healing": 0.0,
"pet": 1,
"skills": 4,
"slot": 2
},
{
"absorbed": 0.0,
"damage": 191.2,
"healing": 170.0,
"pet": 2,
"skills": 18,
"slot": 1
}
],
"traceHash": "698b4a6bca55d662c25e24400225f49b7fe45313006574829e2dedb797a2f94d",
"won": true
},
"shots": 2,
"stage": 3
},
{
"formation": [
0,
2,
1,
-1,
-1,
-1
],
"level": 4,
"result": {
"configVersion": "greenfield-1-2787887803fd",
"defeated": 9,
"durability": 10,
"duration": 74.3,
"firstClear": true,
"id": "first-day-command-28",
"leaks": [
0,
0,
0
],
"logicVersion": 1,
"reward": {
"balls": 3,
"candy": 70,
"coins": 110
},
"rulesVersion": 3,
"stageId": 4,
"stats": [
{
"absorbed": 46.0,
"damage": 257.4,
"healing": 0.0,
"pet": 0,
"skills": 10,
"slot": 0
},
{
"absorbed": 0.0,
"damage": 364.1,
"healing": 0.0,
"pet": 1,
"skills": 4,
"slot": 2
},
{
"absorbed": 0.0,
"damage": 279.4,
"healing": 122.0,
"pet": 2,
"skills": 13,
"slot": 1
}
],
"traceHash": "e835b75654fbe68b87a0e0369d6cdfd7389a4f2a6bb37223695c3e637852c66d",
"won": true
},
"shots": 2,
"stage": 4
},
{
"formation": [
0,
-1,
1,
-1,
2,
-1
],
"level": 5,
"result": {
"chest": 2,
"configVersion": "greenfield-1-2787887803fd",
"defeated": 8,
"durability": 5,
"duration": 87.10000000000001,
"firstClear": true,
"id": "first-day-command-33",
"leaks": [
0,
0,
1
],
"logicVersion": 1,
"reward": {
"balls": 5,
"candy": 100,
"coins": 200
},
"rulesVersion": 3,
"stageId": 5,
"stats": [
{
"absorbed": 78.0,
"damage": 313.3,
"healing": 0.0,
"pet": 0,
"skills": 11,
"slot": 0
},
{
"absorbed": 0.0,
"damage": 279.5,
"healing": 0.0,
"pet": 1,
"skills": 3,
"slot": 2
},
{
"absorbed": 0.0,
"damage": 305.9,
"healing": 280.0,
"pet": 2,
"skills": 25,
"slot": 4
}
],
"traceHash": "d26d25c5f159375339d2d2f3090b871db56e41c7f049efd1259d4891906d9fca",
"won": true
},
"shots": 2,
"stage": 5
}
],
"final": {
"ballRecoveryUnix": 1900040000,
"balls": 62,
"campInteractions": 0,
"campLayout": [
-1,
-1,
-1
],
"candy": 110,
"captureCount": 0,
"captureTutorialDone": true,
"challengeBadges": [
0,
0,
0,
0,
0
],
"challengeBestMs": [
0,
0,
0,
0,
0
],
"challengeRankAt": [
0,
0,
0,
0,
0
],
"chestDailyClaimed": 0,
"chests": [
0,
1,
1
],
"cleared": true,
"clearedStages": [
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"coins": 720,
"dailyClaimed": [
0,
0,
0
],
"dailyDay": 21991,
"dailyProgress": [
2,
1,
0
],
"decorations": [
0,
0,
0
],
"duplicateStreak": 0,
"fishBest": 0,
"fishPlayed": 0,
"formation": [
0,
-1,
1,
-1,
2,
-1
],
"friendBlocked": [],
"friendIds": [],
"friendIn": [],
"friendOut": [],
"giftFrom": [],
"giftSent": [],
"goalClaimed": true,
"lastBattle": "first-day-command-35",
"lastCandy": 20,
"lastCoins": 40,
"lastShot": "first-day-command-4",
"level": 5,
"mails": [
{
"body": "欢迎和伙伴一起开启冒险!\n这份小小补给可用于弹珠发射和伙伴训练,请在有效期内领取。",
"claimed": true,
"expired": false,
"expiresAt": 1900644800,
"mailId": "welcome_supply_v1",
"read": true,
"reward": {
"balls": 5,
"candy": 20,
"coins": 0,
"tickets": 0
},
"sentAt": 1900040000,
"title": "欢迎来到小镇"
},
{
"body": "冒险首通、每日任务和七日登录都有独立奖励。\n邮件附件只有点击领取后才会到账;没有附件的通知只需阅读。",
"claimed": false,
"expired": false,
"expiresAt": 1900644800,
"mailId": "camp_notice_v1",
"read": false,
"reward": {
"balls": 0,
"candy": 0,
"coins": 0,
"tickets": 0
},
"sentAt": 1900040000,
"title": "营地来信"
}
],
"pendingAim": 0,
"pendingBattle": "",
"pendingFish": "",
"pendingShot": "",
"restPet": 0,
"revision": 33,
"schema": 14,
"selectedStage": 5,
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"shopBought": [
1,
0,
0
],
"shots": 2,
"signinClaimed": [
1,
0,
0,
0,
0,
0,
0
],
"signinDays": 1,
"stages": [
1,
1,
1,
0,
0,
0,
0,
0,
0,
0
],
"storyRankAt": 1900040195,
"tickets": 0,
"treasurePlayed": 0,
"treasureSeen": []
},
"initial": {
"ballRecoveryUnix": 1900040000,
"balls": 20,
"campInteractions": 0,
"campLayout": [
-1,
-1,
-1
],
"candy": 0,
"captureCount": 0,
"captureTutorialDone": false,
"challengeBadges": [
0,
0,
0,
0,
0
],
"challengeBestMs": [
0,
0,
0,
0,
0
],
"challengeRankAt": [
0,
0,
0,
0,
0
],
"chestDailyClaimed": 0,
"chests": [
0,
0,
0
],
"cleared": false,
"clearedStages": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"coins": 0,
"dailyClaimed": [
0,
0,
0
],
"dailyDay": 21991,
"dailyProgress": [
0,
0,
0
],
"decorations": [
0,
0,
0
],
"duplicateStreak": 0,
"fishBest": 0,
"fishPlayed": 0,
"formation": [
0,
1,
-1,
-1,
-1,
-1
],
"friendBlocked": [],
"friendIds": [],
"friendIn": [],
"friendOut": [],
"giftFrom": [],
"giftSent": [],
"goalClaimed": false,
"lastBattle": "",
"lastCandy": 0,
"lastCoins": 0,
"lastShot": "",
"level": 1,
"mails": [
{
"body": "欢迎和伙伴一起开启冒险!\n这份小小补给可用于弹珠发射和伙伴训练,请在有效期内领取。",
"claimed": false,
"expired": false,
"expiresAt": 1900644800,
"mailId": "welcome_supply_v1",
"read": false,
"reward": {
"balls": 5,
"candy": 20,
"coins": 0,
"tickets": 0
},
"sentAt": 1900040000,
"title": "欢迎来到小镇"
},
{
"body": "冒险首通、每日任务和七日登录都有独立奖励。\n邮件附件只有点击领取后才会到账;没有附件的通知只需阅读。",
"claimed": false,
"expired": false,
"expiresAt": 1900644800,
"mailId": "camp_notice_v1",
"read": false,
"reward": {
"balls": 0,
"candy": 0,
"coins": 0,
"tickets": 0
},
"sentAt": 1900040000,
"title": "营地来信"
}
],
"pendingAim": 0,
"pendingBattle": "",
"pendingFish": "",
"pendingShot": "",
"restPet": 0,
"revision": 1,
"schema": 14,
"selectedStage": 1,
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"shopBought": [
0,
0,
0
],
"shots": 0,
"signinClaimed": [
0,
0,
0,
0,
0,
0,
0
],
"signinDays": 1,
"stages": [
1,
1,
0,
0,
0,
0,
0,
0,
0,
0
],
"storyRankAt": 0,
"tickets": 0,
"treasurePlayed": 0,
"treasureSeen": []
},
"injectedClock": true,
"operations": [
{
"action": "shot.begin",
"balls": 19,
"candy": 0,
"coins": 0,
"level": 1,
"shots": 0
},
{
"action": "shot.finish",
"balls": 19,
"candy": 20,
"coins": 40,
"level": 1,
"shots": 1
},
{
"action": "capture",
"balls": 19,
"candy": 20,
"coins": 40,
"level": 1,
"shots": 1
},
{
"action": "shot.begin",
"balls": 18,
"candy": 20,
"coins": 40,
"level": 1,
"shots": 1
},
{
"action": "shot.finish",
"balls": 18,
"candy": 40,
"coins": 80,
"level": 1,
"shots": 2
},
{
"action": "train",
"balls": 18,
"candy": 10,
"coins": 80,
"level": 2,
"shots": 2
},
{
"action": "stage.select",
"balls": 18,
"candy": 10,
"coins": 80,
"level": 2,
"shots": 2
},
{
"action": "autoDeploy",
"balls": 18,
"candy": 10,
"coins": 80,
"level": 2,
"shots": 2
},
{
"action": "battle.begin",
"balls": 18,
"candy": 10,
"coins": 80,
"level": 2,
"shots": 2
},
{
"action": "battle.finish",
"balls": 21,
"candy": 50,
"coins": 160,
"level": 2,
"shots": 2
},
{
"action": "goal.claim",
"balls": 26,
"candy": 50,
"coins": 160,
"level": 2,
"shots": 2
},
{
"action": "mail.claimAll",
"balls": 31,
"candy": 70,
"coins": 160,
"level": 2,
"shots": 2
},
{
"action": "signin.claim",
"balls": 41,
"candy": 70,
"coins": 160,
"level": 2,
"shots": 2
},
{
"action": "shop.buy",
"balls": 46,
"candy": 70,
"coins": 160,
"level": 2,
"shots": 2
},
{
"action": "chest.open",
"balls": 48,
"candy": 100,
"coins": 220,
"level": 2,
"shots": 2
},
{
"action": "stage.select",
"balls": 48,
"candy": 100,
"coins": 220,
"level": 2,
"shots": 2
},
{
"action": "autoDeploy",
"balls": 48,
"candy": 100,
"coins": 220,
"level": 2,
"shots": 2
},
{
"action": "battle.begin",
"balls": 48,
"candy": 100,
"coins": 220,
"level": 2,
"shots": 2
},
{
"action": "battle.finish",
"balls": 51,
"candy": 150,
"coins": 310,
"level": 2,
"shots": 2
},
{
"action": "train",
"balls": 51,
"candy": 90,
"coins": 310,
"level": 3,
"shots": 2
},
{
"action": "stage.select",
"balls": 51,
"candy": 90,
"coins": 310,
"level": 3,
"shots": 2
},
{
"action": "autoDeploy",
"balls": 51,
"candy": 90,
"coins": 310,
"level": 3,
"shots": 2
},
{
"action": "battle.begin",
"balls": 51,
"candy": 90,
"coins": 310,
"level": 3,
"shots": 2
},
{
"action": "battle.finish",
"balls": 54,
"candy": 150,
"coins": 410,
"level": 3,
"shots": 2
},
{
"action": "train",
"balls": 54,
"candy": 60,
"coins": 410,
"level": 4,
"shots": 2
},
{
"action": "stage.select",
"balls": 54,
"candy": 60,
"coins": 410,
"level": 4,
"shots": 2
},
{
"action": "autoDeploy",
"balls": 54,
"candy": 60,
"coins": 410,
"level": 4,
"shots": 2
},
{
"action": "battle.begin",
"balls": 54,
"candy": 60,
"coins": 410,
"level": 4,
"shots": 2
},
{
"action": "battle.finish",
"balls": 57,
"candy": 130,
"coins": 520,
"level": 4,
"shots": 2
},
{
"action": "train",
"balls": 57,
"candy": 10,
"coins": 520,
"level": 5,
"shots": 2
},
{
"action": "stage.select",
"balls": 57,
"candy": 10,
"coins": 520,
"level": 5,
"shots": 2
},
{
"action": "autoDeploy",
"balls": 57,
"candy": 10,
"coins": 520,
"level": 5,
"shots": 2
},
{
"action": "battle.begin",
"balls": 57,
"candy": 10,
"coins": 520,
"level": 5,
"shots": 2
},
{
"action": "battle.finish",
"balls": 62,
"candy": 110,
"coins": 720,
"level": 5,
"shots": 2
},
{
"action": "battle.begin",
"balls": 62,
"candy": 110,
"coins": 720,
"level": 5,
"shots": 2
},
{
"action": "battle.finish",
"balls": 62,
"candy": 110,
"coins": 720,
"level": 5,
"shots": 2
}
],
"repeatClearNoReward": true,
"seededResources": false,
"status": "pass"
}
+217
View File
@@ -0,0 +1,217 @@
{
"kind": "guide",
"status": "pass",
"operations": [
{
"action": "shot",
"before": {
"coins": 0,
"candy": 0,
"balls": 20,
"tickets": 0,
"level": 1,
"shots": 0,
"stages": [
1,
1,
0,
0,
0,
0,
0,
0,
0,
0
],
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"formation": [
0,
1,
-1,
-1,
-1,
-1
]
},
"after": {
"coins": 40,
"candy": 20,
"balls": 19,
"tickets": 1,
"level": 1,
"shots": 1,
"stages": [
1,
1,
0,
0,
0,
0,
0,
0,
0,
0
],
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"formation": [
0,
1,
-1,
-1,
-1,
-1
]
}
},
{
"action": "shot",
"before": {
"coins": 40,
"candy": 20,
"balls": 19,
"tickets": 0,
"level": 1,
"shots": 1,
"stages": [
1,
1,
1,
0,
0,
0,
0,
0,
0,
0
],
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"formation": [
0,
1,
-1,
-1,
-1,
-1
]
},
"after": {
"coins": 80,
"candy": 40,
"balls": 18,
"tickets": 0,
"level": 1,
"shots": 2,
"stages": [
1,
1,
1,
0,
0,
0,
0,
0,
0,
0
],
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"formation": [
0,
1,
-1,
-1,
-1,
-1
]
}
}
],
"step": "guide complete",
"updatedUtc": "2026-10-21T14:44:01.2279718Z",
"current": {
"coins": 80,
"candy": 10,
"balls": 18,
"tickets": 0,
"level": 2,
"shots": 2,
"stages": [
1,
1,
1,
0,
0,
0,
0,
0,
0,
0
],
"shards": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"formation": [
0,
1,
-1,
-1,
-1,
-1
]
},
"shortage": "发射弹珠,补足训练糖果",
"ready": "用糖果做一次共享训练",
"trained": "布阵并完成教学关 1-1"
}
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
# G3 新账号至 1-5 验收
2026-10-21。新账号以初始20枚弹珠、岩团团和火喵出发,教学捕捉获得芽芽,使用正常奖励、训练和推荐布阵,通过最新技能规则的1-1~1-5。无需普通随机捕捉、T2或注入资源。本轮不调整战斗数值。
## 路径与结果
两次零度发射共得糖果40、金币80;第一发的券用于教学芽芽。先训练至Lv.2完成1-1,再领取教学目标、欢迎邮件、第1日签到、商店免费补给和1-1掉落的绿野补给箱。此后用通关收益依次训练至Lv.3/4/5,全程三只伙伴均为T1。
| 关卡 | 训练等级 | 布阵(每条路线前/后) | 服务端逻辑时长 | 击退 | 剩余耐久 |
| --- | --- | --- | --- | --- | --- |
| 1-1 | 2 | 岩团团/火喵 | 64.15秒 | 9/9 | 10/10 |
| 1-2 | 2 | 岩团团/火喵 | 64.30秒 | 9/9 | 10/10 |
| 1-3 | 3 | 岩团团/芽芽;火喵/空 | 76.55秒 | 9/9 | 10/10 |
| 1-4 | 4 | 岩团团/芽芽;火喵/空 | 74.30秒 | 9/9 | 10/10 |
| 1-5 | 5 | 岩团团/空;火喵/空;芽芽/空 | 87.10秒 | 8/9 | 5/10 |
客户端最后事件时钟比服务端总时长少一个50ms tick,非回放偏差。真实UI使用2倍速,最早结算时间约束仍生效。
最终金币 **720**、糖果 **110**、弹珠 **62**、券 **0**,Lv.5、发射数2。训练共花糖果300。未领取每日任务、每日宝箱、1-3碎片自选箱及1-5大礼箱;这不是首日全部资源上限。没有普通捕捉或进化开销,不能据此断言所有抽取/消费选择都同样顺畅。
## 修复
1. 教学捕捉后仅有20糖果时,旧引导直接要求训练,但训练需30。`MainHudView.GuideTask`现在根据服务端训练费用和实际余额提示:糖果不足且有弹珠→先发射补糖果;弹珠也不足→免费补给;够用→训练;训练后→布阵。复用原JSON/Prefab骨架,真实新账号验证20→40→训练后10糖果的文案切换和显示。
2. 隐藏的敌人/模型仍逐帧调用`Animator.Play/Update`,产生大量警告。`BattleSkillPresentation.Animate`跳过未激活或禁用的Animator;恢复显示后按绝对战斗时钟采样,不改逻辑事件。实际Prefab隐藏父节点、禁用/重启Animator和隐藏单位检查通过。修复后真实新账号实播1-1,权威终态一致,Animator警告和错误均为0。
## 证据与复验
- [FirstFive/ui_run.json](FirstFive/ui_run.json):18085隔离数据库、新注册账号、真实EventSystem射线点击,覆盖发射、教学捕捉、训练、选关、推荐布阵、五场完整权威战斗和首通奖励。UI路径没有注入时钟、随机数或存档。
- [FirstFive/server_run.json](FirstFive/server_run.json):`first_day_tests`在独立临时数据库经相同业务命令推进,仅推进测试时钟越过播放等待。没有预置钱包/拥有/通关状态;额外重打1-5,钱包和宝箱不增加。
- [FirstFive/parity.json](FirstFive/parity.json):五份轨迹SHA256、胜负、耐久、击退、奖励、统计和最终钱包/伙伴/阵容一致。
- `FirstFive/ui_guide.json`、`animation_lifecycle.json`、`postfix_battle.json`:两处修复的专项回执;`VerifyG3.Domain`另覆盖零弹珠和训练费用变化。
- CTest四组通过:权威战斗、技能样例、原玩法事务、首日推进;Python技能契约8项通过;Unity编译完成。
- 截图:`AIClient/Assets/Screenshots/first_five_formation{1..5}.png`、`first_five_result{1..5}.png`、`first_five_guide_shortage.png`/`first_five_guide_ready.png`。已目视检查三路布阵、结算和新文案。
- [FirstFive/cleanup.json](FirstFive/cleanup.json):原账号与端点恢复,金币/糖果/等级/发射数/伙伴/阵容不变;退出Play,Boot无脏状态,Game View 1080×1920。18085进程按可执行路径/端口/数据库核对后关闭,8080健康且未重启;修复后日志游标350529~350546无新增警告/错误。
```powershell
cmake --build AIServer/build-g1 --config Release --target first_day_tests
AIServer/build-g1/Release/first_day_tests.exe Tools/output/first_five/server_run.json
ctest --test-dir AIServer/build-g1 -C Release --output-on-failure
```
UI:启动独立`127.0.0.1:18085`,数据库仅置于`Tools/output/first_five/`;Pipeline在Boot Play Mode运行`VerifyFirstFive.Begin`,从`ui_run.json`轮询完成,再`Cleanup`恢复原账号。`BeginGuide`/`AnimationLifecycle`/`BeginBattleSmoke`是专项入口;`BeginBattleSmoke`接在`BeginGuide`后运行,异步状态写入同目录。每批结束先`Cleanup`再退出Play,不对真实端点或活动中账号启动验收。
## 后续
首日前五关未发现资源硬卡点;1-5已有损失,保留当前数值进入试玩。仍需真人首次操作、微信真机帧率/内存/首屏加载、主包与热更资源体积实测。本轮未构建或发布Player,不构成微信性能达标证据。
@@ -0,0 +1,175 @@
{
"status": "generated",
"service": "http://127.0.0.1:8012",
"guide": "D:/UD/AI/XModel/TangoFlux_AI\u8c03\u7528\u6307\u5357.md",
"items": [
{
"id": "Sfx_Heal",
"request": {
"prompt": "One gentle magical healing chime, warm bell sparkle with a short soft airy tail, friendly pastoral fantasy game, no music bed, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52005
},
"requestHash": "0cca07dac2d48b20cde778c50c42502a364d1e4543820f363523a956e2281685",
"job": {
"id": "f87190112d6b48e49938d96a9b4b9c07",
"status": "succeeded",
"prompt": "One gentle magical healing chime, warm bell sparkle with a short soft airy tail, friendly pastoral fantasy game, no music bed, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2.0,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52005,
"created_at": "2026-10-21T14:02:56.450767+00:00",
"started_at": "2026-10-21T14:02:56.528051+00:00",
"finished_at": "2026-10-21T14:03:14.994210+00:00",
"error": null,
"sample_rate": 44100,
"channels": 2,
"bytes": 352844,
"elapsed_sec": 18.466,
"url": "/api/jobs/f87190112d6b48e49938d96a9b4b9c07/audio",
"download_url": "/api/jobs/f87190112d6b48e49938d96a9b4b9c07/audio"
},
"source": "Tools\\output\\partner_skill_sfx\\Sfx_Heal_source.wav",
"sourceSha256": "ea61c7ddb154220799d3430c543868aceec2f6e99c2e00b66a4965bd4cf0e62e",
"output": "AIClient\\Assets\\Bundles\\Sound\\SFX\\BattleSkills\\Sfx_Heal.wav",
"outputSha256": "61ab8a7cd7feed49646752ad921c50dbfbec33ce8d3b534d4451f3638ff5df89",
"seconds": 0.55,
"trimStartSeconds": 0.015011337868480726,
"sampleRate": 44100,
"channels": 2,
"peakDb": -1.938200260161128,
"rmsDb": -14.503833274488535,
"postprocess": "65Hz highpass; onset trim; 5ms fade in / 50ms fade out; peak -1.94 dBFS",
"license": "declare-lab/TangoFlux: noncommercial research weights per project guide"
},
{
"id": "Sfx_Slow",
"request": {
"prompt": "One gentle icy magical pulse, light crystalline tick with a soft watery freeze texture, short isolated cartoon game effect, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52007
},
"requestHash": "cf69e07c9e1836a1a7e2afe45220db8cf0578c8116586f46e89152c77cad23f8",
"job": {
"id": "c0a8afed8ba041dcb027ae0ad7de3861",
"status": "succeeded",
"prompt": "One gentle icy magical pulse, light crystalline tick with a soft watery freeze texture, short isolated cartoon game effect, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2.0,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52007,
"created_at": "2026-10-21T14:02:56.451765+00:00",
"started_at": "2026-10-21T14:03:14.994210+00:00",
"finished_at": "2026-10-21T14:03:34.600333+00:00",
"error": null,
"sample_rate": 44100,
"channels": 2,
"bytes": 352844,
"elapsed_sec": 19.605,
"url": "/api/jobs/c0a8afed8ba041dcb027ae0ad7de3861/audio",
"download_url": "/api/jobs/c0a8afed8ba041dcb027ae0ad7de3861/audio"
},
"source": "Tools\\output\\partner_skill_sfx\\Sfx_Slow_source.wav",
"sourceSha256": "8e1aadb6c639b83360d5c8da66013d3b908204ff7d685466efa8f3d2e0a109f3",
"output": "AIClient\\Assets\\Bundles\\Sound\\SFX\\BattleSkills\\Sfx_Slow.wav",
"outputSha256": "e191cc6baa46fa6e1c46f77eaa072495c52b4c75d47be98cfd7a81ca14a134c9",
"seconds": 0.5,
"trimStartSeconds": 1.8250113378684807,
"sampleRate": 44100,
"channels": 2,
"peakDb": -1.938200260161128,
"rmsDb": -18.17168819734519,
"postprocess": "65Hz highpass; onset trim; 5ms fade in / 50ms fade out; peak -1.94 dBFS",
"license": "declare-lab/TangoFlux: noncommercial research weights per project guide"
},
{
"id": "Sfx_Lightning",
"request": {
"prompt": "One short small magical electric zap, crisp bright crackle and a soft pop, friendly cartoon fantasy, no harsh buzz, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52008
},
"requestHash": "c1eaa41f49464a4eaf5553abd03ed5014085811aebe983766ef0529e7c4b74db",
"job": {
"id": "085b9e7c191e4d4dac672aec626ceead",
"status": "succeeded",
"prompt": "One short small magical electric zap, crisp bright crackle and a soft pop, friendly cartoon fantasy, no harsh buzz, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2.0,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52008,
"created_at": "2026-10-21T14:03:15.769688+00:00",
"started_at": "2026-10-21T14:03:34.600333+00:00",
"finished_at": "2026-10-21T14:03:47.005917+00:00",
"error": null,
"sample_rate": 44100,
"channels": 2,
"bytes": 352844,
"elapsed_sec": 12.406,
"url": "/api/jobs/085b9e7c191e4d4dac672aec626ceead/audio",
"download_url": "/api/jobs/085b9e7c191e4d4dac672aec626ceead/audio"
},
"source": "Tools\\output\\partner_skill_sfx\\Sfx_Lightning_source.wav",
"sourceSha256": "3e5d8abf5cca567db79ef773bc63297546b2e931b42640714e12acca8e6735d8",
"output": "AIClient\\Assets\\Bundles\\Sound\\SFX\\BattleSkills\\Sfx_Lightning.wav",
"outputSha256": "a8e6f806b3e62e8916929d39b63f9d6cfd1f534dc44f49f79d99a490753ed00a",
"seconds": 0.38,
"trimStartSeconds": 0.7150113378684807,
"sampleRate": 44100,
"channels": 2,
"peakDb": -1.938200260161128,
"rmsDb": -15.269655589624424,
"postprocess": "65Hz highpass; onset trim; 5ms fade in / 50ms fade out; peak -1.94 dBFS",
"license": "declare-lab/TangoFlux: noncommercial research weights per project guide"
},
{
"id": "Sfx_EnemyHit",
"request": {
"prompt": "One short soft cartoon creature hit, compact muted thump, dry isolated mobile fantasy game effect, no voice, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52009
},
"requestHash": "1af9f9a223d4a9a50a9c6953483ba6ba3ca428942072a32b37b4bdc748c6a0f5",
"job": {
"id": "b366b215280240a18b86c055b9a2527f",
"status": "succeeded",
"prompt": "One short soft cartoon creature hit, compact muted thump, dry isolated mobile fantasy game effect, no voice, no music, no speech, single isolated event at the beginning, silence afterwards, no music, no speech, no ambience",
"duration": 2.0,
"steps": 50,
"guidance_scale": 4.5,
"seed": 52009,
"created_at": "2026-10-21T14:03:35.039882+00:00",
"started_at": "2026-10-21T14:03:47.005917+00:00",
"finished_at": "2026-10-21T14:03:59.381002+00:00",
"error": null,
"sample_rate": 44100,
"channels": 2,
"bytes": 352844,
"elapsed_sec": 12.374,
"url": "/api/jobs/b366b215280240a18b86c055b9a2527f/audio",
"download_url": "/api/jobs/b366b215280240a18b86c055b9a2527f/audio"
},
"source": "Tools\\output\\partner_skill_sfx\\Sfx_EnemyHit_source.wav",
"sourceSha256": "fa744f2b8972824d41fe5c54bfb60e19c9081d06bc29d3f07de55f402a4f6272",
"output": "AIClient\\Assets\\Bundles\\Sound\\SFX\\BattleSkills\\Sfx_EnemyHit.wav",
"outputSha256": "2cdb0a6f272f1bd5fac3ffab34fffaa52104a38056debe944e7913d7cf6ef93f",
"seconds": 0.26,
"trimStartSeconds": 1.9150113378684808,
"sampleRate": 44100,
"channels": 2,
"peakDb": -1.9382002601611268,
"rmsDb": -17.50460549386468,
"postprocess": "65Hz highpass; onset trim; 5ms fade in / 50ms fade out; peak -1.94 dBFS",
"license": "declare-lab/TangoFlux: noncommercial research weights per project guide"
}
]
}

Some files were not shown because too many files have changed in this diff Show More