交付一款可发布试玩、以自然语言指挥 AI 军团为核心的原创网页 RTS。完整验收包括两个情景、经济/生产/科技/兵团/战斗/迷雾/敌方 AI/事件/胜负/存档/暂停与倍速,并以自动测试和真实浏览器证据收口。
- 2026-07-16 初始目录为空,文件数 0,不是 Git 仓库。
- 无
AGENTS.md、README、源码、构建配置、测试或未提交修改。 - 采用 Vite + React + TypeScript + 原生 Canvas + Vitest + Playwright。
src/sim保存确定性模拟;src/commands保存统一命令管线;src/render只负责显示;src/app组合 UI。
玩家负责战争方向、时机、兵力分配、撤退和发展优先级;AI 军官负责解析、寻路、阵型、条件执行和风险汇报,但不会自行完成战略决策。
玩家是最高指挥官,通过清晰的口头意图调动多个兵团,而不是框选和逐单位微操。战场呈现为原创低魔工业战争指挥桌。
所有来源统一为 transcript -> normalize -> parse -> resolve context -> ambiguity check -> CommandBus -> simulation task。文字是调试、自动测试、无障碍和不支持麦克风浏览器的完整回退,不维护第二套逻辑。
- 固定步长 100ms。
- 渲染帧与模拟 tick 分离。
- 暂停阻断所有模拟 tick;速度使用 1×/2×/4×累积固定步长。
- 所有随机逻辑最终使用可注入种子。
作战军官管理任务与交战,情报军官只汇报可见或最后已知情报,后勤军官管理资源/队列/瓶颈。主动报告具有严重度、位置、冷却和聚合键。
InputSource -> TranscriptNormalizer -> CommandParser -> CommandContext -> ClarificationSystem -> CommandBus -> CommandExecutor/BattlePlanSystem -> World Systems -> OfficerSystem -> UI/SpeechSynthesis
核心模块将与 Canvas/React 分离并通过纯 TypeScript 测试。
单位、建筑、科技、事件、兵团规则和情景将放入数据配置;地图使用网格和原创程序化布局。
- 工程启动与最小命令闭环。
- 资源、建筑、生产与兵团。
- 语音、上下文与澄清。
- 战斗、寻路、阵型与战争迷雾。
- 复杂作战计划与敌方 AI。
- 两个情景、事件和胜负。
- 存档、设置、音画和响应式。
- 完整测试、浏览器实玩与收尾。
- 实际完成内容:Vite/React/TypeScript/Canvas 工程;主菜单;原创灰谷地图、双方总部和侦察兵;100ms 固定步长;统一 transcript 规范化、结构化解析、CommandBus、执行器;HUD、解析状态与主动抵达汇报。
- 修改文件:
package.json、package-lock.json、TypeScript/Vite/Vitest/Playwright/ESLint 配置、index.html、src/core/types.ts、src/sim/*、src/commands/*、src/render/BattlefieldCanvas.tsx、src/app/App.tsx、src/ui/styles.css、首批测试、README、EXECPLAN。 - 运行命令:
npm install;npm test;npm run lint;npm run typecheck;npm run build;npm run dev;agent-browser 的open/wait/snapshot/click/eval/console/errors/screenshot。 - 成功结果:2 个测试文件、4 个用例通过;lint 0 警告;TypeScript 通过;Vite 生产构建通过(36 modules);浏览器页面有内容、无 Vite 错误覆盖层,控制台与 page errors 为空;实际点击“开始演习”并下达“侦察兵去北方看看”,3.2 秒后 DOM 显示命令 completed 与抵达汇报。
- 失败现象:最初配置端口 4173,但环境审计发现该端口被相邻旧 Vite 项目占用,若直接测试会得到错误项目的假阳性。
- 复现步骤:检查 4173 监听进程,命令行工作目录指向
D:\java\项目\2026\RTS而非当前RTS-2。 - 根因:空仓库初始化时未先确认目标端口占用。
- 修复方式:将 Vite 与 Playwright baseURL/webServer 全部改为
127.0.0.1:5173并启用strictPort。 - 复测结果:agent-browser 标题为本项目“号令前线 / Command Frontline”,命令闭环截图保存在
output/playwright/milestone-1-command.png。 - 自动浏览器失败与修复:首次
npm run test:e2e -- --reporter=line因宽松getByText同时匹配目标进度和军官报告而 2 项失败;改为精确文本后桌面通过,但手机横屏因目标详情按设计折叠而toBeVisible失败。最终将状态数据断言改为toHaveText,并保留底部completed可见性断言。第三次复测结果为 3 passed、1 个非适用项目 skipped。 - 下一阶段:实现统一经济事务、采集、十类建筑、生产/科技队列与稳定兵团标识,并增加针对性测试。
- 实际完成内容:三资源统一事务与账本、储备、人口预留、资源节点与工人调配;10 种差异建筑的占地/施工/完成/损坏/修理/退款/集结点;8 兵种生产队列;8 科技及实际修正;稳定兵团 ID、命名/拆分/合并/补员/伤亡/规则/任务中断;领域状态接入真实游戏模拟与 HUD。
- 修改文件:
src/domain/*、src/config/gameContent.ts、src/systems/{ResourceSystem,EconomySystem,BuildingSystem,ProductionSystem,TechnologySystem,SquadSystem}.ts、src/sim/FactionRuntime.ts、重写src/sim/GameSimulation.ts、src/commands/GameCommandExecutor.ts、扩展src/core/types.ts、Canvas 与 App/CSS、相关测试。 - 运行命令:经济域定向 Vitest;
npx vitest run tests/GameSimulationIntegration.test.ts;npm test;npm run lint;npm run typecheck;npm run build;agent-browser 独立 session 的真实标记/建造/训练/编组流程。 - 成功结果:全量 18 个测试文件、86 个用例通过;lint 0;TypeScript 通过;Vite 构建 54 modules;浏览器真实放置标记、兵营开工和完成、训练 10 名剑盾兵、形成
squad-1 / 第一步兵团,成员 10、构成{swordsman:10}、默认规则KEEP_FORMATION;控制台和 page errors 为空。 - 失败现象 1:采集集成测试期望木材节点最终只有 3 人,但初始已有 2 人,命令调去另外 3 人后实际为 5 人。
- 根因与修复 1:测试把“让三个工人去采木头”误解为设置总人数;改为验证目标节点人数增加 3,并继续验证收入与账本。复测 4/4 通过。
- 失败现象 2:首次 M2 agent-browser snapshot 显示另一款“毛巾叠叠乐”,尽管 5173 进程确认属于当前仓库。
- 根因与修复 2:agent-browser 默认 daemon/session 状态被旧页面污染,tab 实际为
about:blank;关闭默认浏览器并以--session command-frontline创建隔离会话。复测 URL、标题与快照均为本项目。 - 失败现象 3:首轮集成后 lint 报未使用导入和参数 2 项。
- 根因与修复 3:重构遗留符号;删除后 lint、类型检查和构建全部通过。
- 浏览器证据:
output/playwright/milestone-2-economy-squad.png;运行快照明确显示训练前后资源变化、生产队列、10 名剑盾兵与第一步兵团。 - 下一阶段:把完整命令上下文、澄清/确认 UI、真实 Web Speech 状态、Push-to-talk、修改/取消与存档按钮整合为可持续对话体验。
- 实际完成内容:Web Speech Recognition 适配、权限/监听/识别/无语音/拒绝/超时/错误状态;空格 Push-to-talk;文字与语音统一进入
submitTranscript;中文数字、同义词、兵种/兵团/方位/路线/目标/条件/否定/时长/多子句;有限窗口上下文、代词补全、澄清、确认、拒绝、修改和取消。 - 修改文件:
src/input/*、src/commands/*、src/app/App.tsx、命令与语音测试。 - 运行命令:命令解析、上下文、澄清、语音适配定向 Vitest;全量 Vitest;TypeScript、ESLint、Vite 构建。
- 成功结果:自动测试已覆盖中文与阿拉伯数字、多种后方突袭同义表达、条件撤退、上下文补全和低置信度确认;语音注入和文字输入共用执行管线。
- 失败现象:当前自动化 Chromium 没有可注入的真实麦克风音频源,因此尚未完成真人口述;不能把转写注入冒充真实语音验证。
- 根因:浏览器自动化环境不提供真实音频采集设备与用户口述输入。
- 修复/回退:完整保留浏览器权限状态、一键重试和文字回退;后续浏览器验证使用注入转写验证语音后的统一链路,并在最终限制中保留人工口述步骤。
- 下一阶段:完成澄清 UI 的真实浏览器交互证据,并把设置中的语言和 Push-to-talk 键接入适配器。
- 实际完成内容:A*、动态障碍重规划、道路/森林/高地/河流/桥梁成本;五种阵型;多兵种克制、近战/远程投射物、护甲、追击、撤退和建筑伤害;战争迷雾、最后已知位置、情报过期;敌方联系人离开视野后不再显示实时状态。
- 修改文件:
src/systems/{MapGrid,NavigationGraph,Pathfinding,FogOfWar,FormationSystem,CombatSystem,IntelligenceSystem}.ts、GameSimulation.ts、Canvas 和相关测试。 - 成功结果:高级集成测试确认跨河路径必须经过桥梁、敌情从 confirmed 转为 last-known、长枪克制骑兵、条件长枪阈值触发撤退。
- 当前缺口:
CameraSystem与MinimapCanvas已有纯模块和测试,但此前尚未接入主 UI;正在补接 WASD/拖拽/缩放/镜头边界/兵团跟随与小地图视野框。 - 下一阶段:完成真实浏览器的迷雾、镜头、小地图、战斗提示和控制台验证。
- 实际完成内容:
BattlePlanSystem、统一优先级中断、正面佯攻与骑兵绕后的并行/条件触发、长枪阈值撤退、计划暂停/恢复/修改/取消;三类军官与报告冷却;敌方 AI 经济、建造、训练、侦察、正面进攻、回防、撤退和固定种子快照。 - 核心自动证据:
AdvancedSimulationIntegration.test.ts验证正面接敌信号真实启动骑兵后方任务,十名可见长枪兵使任务失败并执行向北、非原路撤退。 - 失败现象:固定种子灰谷实玩在建造兵营/马厩并训练后,骑兵绕后任务报告“路径不可达”,协同目标保持 0,敌方总部未受损。
- 复现步骤:地图标记建造生产建筑 → 完工 → 正常训练骑兵 → 编组 → 下达正面佯攻与森林绕后命令 → 推进模拟。
- 根因:新建生产建筑没有默认集结点,
ProductionSystem把训练单位生成在建筑左上角占用格;A* 正确拒绝不可通行起点。 - 修复方式:正在让新建生产建筑使用确定性的建筑外集结/出生点,并增加正常训练单位可移动的回归测试。
- 下一阶段:修复后用纯文字命令与地图标记完成灰谷真实胜利,不通过直接改 HP、直接记目标或隐藏胜利按钮。
- 首次当前全量门禁:lint 通过;类型检查/构建因高级集成测试中的可空数组未收窄失败;全量测试在 27 个 jsdom 文件高并发时有 1–2 个 5 秒超时。
- 根因与修复:为测试数组增加显式类型守卫;单独运行慢用例仅 2.4 秒,确认是 worker 争用,因此把 Vitest
maxWorkers固定为 4,而非跳过测试或放宽断言。 - 复测:
npm test -- --reporter=dot --maxWorkers=4为 27 files / 120 tests 全绿;npm run typecheck、npm run lint、npm run build均通过,Vite 构建 68 modules。
- 实际完成内容:双情景入口;事件、教程、目标、统计与胜负结算接入主运行时;完整
GameSimulation存档导出/恢复;60 秒模拟时间自动存档、手动保存/继续/删除和损坏存档回退;相机、小地图、战斗定位;设置持久化、程序化音频和响应式控制面;当前 Playwright 冒烟脚本覆盖文字移动、双情景入口、存档往返、损坏回退、断桥真实失败/重开以及桌面/手机横屏关键控件。 - 修改文件:
src/app/*、src/config/scenarios.ts、src/sim/GameSimulation.ts、src/systems/{ScenarioSystem,ObjectiveSystem,EventSystem,TutorialSystem,StatisticsSystem,SaveSystem,CameraSystem,AudioSystem}.ts、src/settings/*、src/render/*、e2e/smoke.spec.ts及相应 Vitest 测试。 - 最近一次全量命令:
npm.cmd test -- --reporter=dot。 - 成功结果:30 个测试文件中 136/137 用例通过;此前
SessionSystemsIntegration.test.ts5/5 通过,类型检查也已通过。当前结果不得记为全绿。 - 失败现象:
tests/AshValleyPlaythrough.test.ts在 400 秒模拟时仍处于playing;经济、生产、侦察目标完成,但兵力仅 4/10、协同计划 0/1、胜利 0/1。命令历史被重复的awaiting-clarification复杂命令填满。 - 复现步骤:运行该测试;脚本下达高风险的“第一步兵团正面佯攻 + 轻骑兵右侧森林绕后 + 接敌后攻击农民 + 长枪阈值北撤”命令后,没有回答系统要求的确认,并在后续 tick 重复下达原命令。
- 根因:产品正确将复杂高风险命令置为待确认,但通关脚本把
awaiting-clarification当成未下达,每 0.1 秒重发;同时初始前线在计划成立前损失,使兵力目标回落。 - 修复方式:通关脚本需在收到待确认状态时通过公开 transcript 管线发送“确认”,确认后只记录一次计划标志,并让新训练侦察兵继续执行侦察任务;不得直接修改生命、单位、目标或胜负状态。
- 复测要求:先定向运行
npm.cmd test -- tests/AshValleyPlaythrough.test.ts --reporter=verbose,再执行全量 Vitest、类型检查、lint、构建与当前 Playwright 冒烟。只有全部真实通过后才能把最终门禁记为完成。
- 内置
rg.exe在 WindowsApps 路径被拒绝执行;仓库搜索改用 PowerShellGet-ChildItem,不影响开发。 - 目标目录完全为空且不属于 Git 仓库,因此不存在需要合并或避让的旧实现。
- 端口 4173 已被相邻旧 Vite 项目占用;本项目与浏览器测试严格锁定 5173,避免误测旧页面。
- 动态事件首个测试生成了选项却无法 resolve;失败消息显示组合为
undefined:hold。根因是事件从目录定义复制时漏写由目录键提供的kind。创建事件时显式注入kind并把目录类型改为省略kind后,3 个确定性事件/目标测试全部通过。 - 浏览器自动化必须使用本任务独立 session;默认 agent-browser daemon 可能残留其他本地项目的页面状态,即使目标端口与服务进程正确。
- 2026-07-16:选择原生 Canvas 而非 Phaser。原因是空仓库首闭环需要最低依赖、明确模拟/渲染边界和可控性能。
- 2026-07-16:选择 React 组织高密度 HUD,但所有游戏规则保留为框架无关 TypeScript。
- 2026-07-16:先验证单单位命令闭环,再扩展大型系统,避免一次性写出未运行架构。
Web Speech API 已接入统一命令管线,包含权限、监听、识别、成功、无语音、拒绝、超时、错误和重试状态;不支持时文字回退不会阻塞游戏。真实麦克风口述仍未验证,当前不得声称已完成。
已支持中文数字、阿拉伯数字、兵团名、目标、路线、条件、否定、多子句、上下文、代词、澄清、确认、修改和取消。当前发现“在总部北边建马厩”中空间参照“总部”可能污染建筑类型槽位,正在增加优先级回归测试。
基础克制和编队数值已进入集成测试;灰谷完整胜利尚未完成平衡收口。当前首先修复训练单位出生在建筑占用格这一流程错误,再基于真实文字指挥通关调整兵力与敌军节奏。
Canvas 一次绘制 48×30 网格;模拟使用固定步长并限制单帧最多 20 tick,长帧最大吸收 0.5 秒,避免后台恢复造成“死亡螺旋”。
| 范围 | 自动测试 | 浏览器 | 状态 |
|---|---|---|---|
| 固定步长/暂停/4× | Vitest | 1× 浏览器推进 | 自动测试通过 |
| “侦察兵去北方”解析 | Vitest | agent-browser 实际下达 | 自动与浏览器通过 |
| 地图/基地/侦察兵显示 | 无 | 1440×900 截图检查 | 通过 |
| 资源/采集/建筑/生产/科技 | 14+ 集成/领域测试 | M2 真实流程 | 通过 |
| 兵团创建/拆分/合并/规则 | 3 领域 + 集成 | M2 创建兵团 | 通过 |
| 中文命令/上下文/澄清 | 35 定向 | 待完整浏览器澄清 | 自动测试通过 |
| 战斗/路径/迷雾 | 23 定向 | 待集成 | 自动测试通过 |
| 存档/设置/语音适配 | GameSaveRestore、SaveSystem、SessionSystemsIntegration、SpeechInput |
存档往返与损坏回退已写入当前 Playwright 冒烟 | 自动测试通过;真实麦克风未验证 |
| 事件/教程/统计/双情景 | EventObjective、TutorialSystem、StatisticsSystem、ScenarioSystem、SessionSystemsIntegration |
双情景入口与断桥失败/重开已写入当前 Playwright 冒烟 | 运行时已接线 |
| 灰谷完整文字通关 | AshValleyPlaythrough.test.ts |
尚无最终胜利浏览器证据 | 最近一次全量运行失败,修复中 |
- 2026-07-16,agent-browser / Chromium,1440×900:主菜单可见;进入灰谷演习;输入预填文字命令并提交;侦察兵从
(12,16)实际移动到北方目标;状态从 executing 变为 completed;情报军官产生抵达报告。 - 内容检测
HAS_CONTENT,错误覆盖层OK,agent-browser console无输出,agent-browser errors无输出。 - 截图:
output/playwright/milestone-1-command.png。 - 2026-07-16,agent-browser 独立 session / Chromium,1440×900:地图点击放置战术标记;文字输入“在这里建一座兵营”;开发调试入口用同一固定 tick 快进 20 秒并确认完工;文字输入“训练十个剑盾兵”,队列显示
0/10和训练进度;固定 tick 快进 190 秒后确认 10 个实体;文字输入编组命令后squad-1成立。截图output/playwright/milestone-2-economy-squad.png。 - 2026-07-16,Chromium,镜头/小地图集成截图:
output/playwright/camera-minimap-integration.png。 - 当前
e2e/smoke.spec.ts已定义 1440×900 与 844×390 Chromium 项目,流程包含真实 parser 文字移动、双情景入口、手动存档继续、SAVE_GAME命令、损坏存档回退、断桥失败结算与重开、关键命令控件可达性。此条仅记录已实现的浏览器测试流程;最终结果必须以提交前实际运行输出为准。
修复并复测灰谷完整通关脚本;执行最终全量 Vitest、类型检查、lint、构建和当前 Playwright 冒烟;补齐 1366×768 与 1920×1080 的浏览器证据。真实麦克风只能在具有音频采集设备和权限交互的环境中人工验证。
真实麦克风口述尚未验证。当前 Playwright 配置只覆盖 Chromium 1440×900 与 844×390,尚未覆盖其他浏览器及另外两个目标桌面尺寸。最近一次全量 Vitest 有 1 个灰谷通关用例失败,因此最终质量门禁尚未完成。
核心系统与双情景运行时已接线,存档、设置、事件、教程、结算、镜头和响应式控制面不再属于“待实现”项。项目仍处于最终门禁阶段;灰谷通关回归、当前浏览器冒烟和真实麦克风外部验证状态必须按实际结果收口。