Skip to content

Latest commit

 

History

History
200 lines (142 loc) · 19.7 KB

File metadata and controls

200 lines (142 loc) · 19.7 KB

EXECPLAN — 号令前线 / Command Frontline

Purpose

交付一款可发布试玩、以自然语言指挥 AI 军团为核心的原创网页 RTS。完整验收包括两个情景、经济/生产/科技/兵团/战斗/迷雾/敌方 AI/事件/胜负/存档/暂停与倍速,并以自动测试和真实浏览器证据收口。

Repository Orientation

  • 2026-07-16 初始目录为空,文件数 0,不是 Git 仓库。
  • AGENTS.md、README、源码、构建配置、测试或未提交修改。
  • 采用 Vite + React + TypeScript + 原生 Canvas + Vitest + Playwright。
  • src/sim 保存确定性模拟;src/commands 保存统一命令管线;src/render 只负责显示;src/app 组合 UI。

Player Promise

玩家负责战争方向、时机、兵力分配、撤退和发展优先级;AI 军官负责解析、寻路、阵型、条件执行和风险汇报,但不会自行完成战略决策。

Core Fantasy

玩家是最高指挥官,通过清晰的口头意图调动多个兵团,而不是框选和逐单位微操。战场呈现为原创低魔工业战争指挥桌。

Voice Command Model

所有来源统一为 transcript -> normalize -> parse -> resolve context -> ambiguity check -> CommandBus -> simulation task。文字是调试、自动测试、无障碍和不支持麦克风浏览器的完整回退,不维护第二套逻辑。

Simulation Model

  • 固定步长 100ms。
  • 渲染帧与模拟 tick 分离。
  • 暂停阻断所有模拟 tick;速度使用 1×/2×/4×累积固定步长。
  • 所有随机逻辑最终使用可注入种子。

Officer AI Model

作战军官管理任务与交战,情报军官只汇报可见或最后已知情报,后勤军官管理资源/队列/瓶颈。主动报告具有严重度、位置、冷却和聚合键。

Architecture and Data Flow

InputSource -> TranscriptNormalizer -> CommandParser -> CommandContext -> ClarificationSystem -> CommandBus -> CommandExecutor/BattlePlanSystem -> World Systems -> OfficerSystem -> UI/SpeechSynthesis

核心模块将与 Canvas/React 分离并通过纯 TypeScript 测试。

Content Configuration

单位、建筑、科技、事件、兵团规则和情景将放入数据配置;地图使用网格和原创程序化布局。

Milestones

  1. 工程启动与最小命令闭环。
  2. 资源、建筑、生产与兵团。
  3. 语音、上下文与澄清。
  4. 战斗、寻路、阵型与战争迷雾。
  5. 复杂作战计划与敌方 AI。
  6. 两个情景、事件和胜负。
  7. 存档、设置、音画和响应式。
  8. 完整测试、浏览器实玩与收尾。

Progress

Milestone 1 — completed

  • 实际完成内容:Vite/React/TypeScript/Canvas 工程;主菜单;原创灰谷地图、双方总部和侦察兵;100ms 固定步长;统一 transcript 规范化、结构化解析、CommandBus、执行器;HUD、解析状态与主动抵达汇报。
  • 修改文件:package.jsonpackage-lock.json、TypeScript/Vite/Vitest/Playwright/ESLint 配置、index.htmlsrc/core/types.tssrc/sim/*src/commands/*src/render/BattlefieldCanvas.tsxsrc/app/App.tsxsrc/ui/styles.css、首批测试、README、EXECPLAN。
  • 运行命令:npm installnpm testnpm run lintnpm run typechecknpm run buildnpm 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。
  • 下一阶段:实现统一经济事务、采集、十类建筑、生产/科技队列与稳定兵团标识,并增加针对性测试。

Milestone 2 — completed

  • 实际完成内容:三资源统一事务与账本、储备、人口预留、资源节点与工人调配;10 种差异建筑的占地/施工/完成/损坏/修理/退款/集结点;8 兵种生产队列;8 科技及实际修正;稳定兵团 ID、命名/拆分/合并/补员/伤亡/规则/任务中断;领域状态接入真实游戏模拟与 HUD。
  • 修改文件:src/domain/*src/config/gameContent.tssrc/systems/{ResourceSystem,EconomySystem,BuildingSystem,ProductionSystem,TechnologySystem,SquadSystem}.tssrc/sim/FactionRuntime.ts、重写 src/sim/GameSimulation.tssrc/commands/GameCommandExecutor.ts、扩展 src/core/types.ts、Canvas 与 App/CSS、相关测试。
  • 运行命令:经济域定向 Vitest;npx vitest run tests/GameSimulationIntegration.test.tsnpm testnpm run lintnpm run typechecknpm 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、修改/取消与存档按钮整合为可持续对话体验。

Milestone 3 — engine complete, browser evidence in progress

  • 实际完成内容: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 键接入适配器。

Milestone 4 — engine complete, visual integration in progress

  • 实际完成内容:A*、动态障碍重规划、道路/森林/高地/河流/桥梁成本;五种阵型;多兵种克制、近战/远程投射物、护甲、追击、撤退和建筑伤害;战争迷雾、最后已知位置、情报过期;敌方联系人离开视野后不再显示实时状态。
  • 修改文件:src/systems/{MapGrid,NavigationGraph,Pathfinding,FogOfWar,FormationSystem,CombatSystem,IntelligenceSystem}.tsGameSimulation.ts、Canvas 和相关测试。
  • 成功结果:高级集成测试确认跨河路径必须经过桥梁、敌情从 confirmed 转为 last-known、长枪克制骑兵、条件长枪阈值触发撤退。
  • 当前缺口:CameraSystemMinimapCanvas 已有纯模块和测试,但此前尚未接入主 UI;正在补接 WASD/拖拽/缩放/镜头边界/兵团跟随与小地图视野框。
  • 下一阶段:完成真实浏览器的迷雾、镜头、小地图、战斗提示和控制台验证。

Milestone 5 — engine complete, playthrough validation blocked by spawn bug

  • 实际完成内容:BattlePlanSystem、统一优先级中断、正面佯攻与骑兵绕后的并行/条件触发、长枪阈值撤退、计划暂停/恢复/修改/取消;三类军官与报告冷却;敌方 AI 经济、建造、训练、侦察、正面进攻、回防、撤退和固定种子快照。
  • 核心自动证据:AdvancedSimulationIntegration.test.ts 验证正面接敌信号真实启动骑兵后方任务,十名可见长枪兵使任务失败并执行向北、非原路撤退。
  • 失败现象:固定种子灰谷实玩在建造兵营/马厩并训练后,骑兵绕后任务报告“路径不可达”,协同目标保持 0,敌方总部未受损。
  • 复现步骤:地图标记建造生产建筑 → 完工 → 正常训练骑兵 → 编组 → 下达正面佯攻与森林绕后命令 → 推进模拟。
  • 根因:新建生产建筑没有默认集结点,ProductionSystem 把训练单位生成在建筑左上角占用格;A* 正确拒绝不可通行起点。
  • 修复方式:正在让新建生产建筑使用确定性的建筑外集结/出生点,并增加正常训练单位可移动的回归测试。
  • 下一阶段:修复后用纯文字命令与地图标记完成灰谷真实胜利,不通过直接改 HP、直接记目标或隐藏胜利按钮。

Current gate status — 2026-07-16

  • 首次当前全量门禁:lint 通过;类型检查/构建因高级集成测试中的可空数组未收窄失败;全量测试在 27 个 jsdom 文件高并发时有 1–2 个 5 秒超时。
  • 根因与修复:为测试数组增加显式类型守卫;单独运行慢用例仅 2.4 秒,确认是 worker 争用,因此把 Vitest maxWorkers 固定为 4,而非跳过测试或放宽断言。
  • 复测:npm test -- --reporter=dot --maxWorkers=4 为 27 files / 120 tests 全绿;npm run typechecknpm run lintnpm run build 均通过,Vite 构建 68 modules。

2026-07-19 implementation audit — final gate active

  • 实际完成内容:双情景入口;事件、教程、目标、统计与胜负结算接入主运行时;完整 GameSimulation 存档导出/恢复;60 秒模拟时间自动存档、手动保存/继续/删除和损坏存档回退;相机、小地图、战斗定位;设置持久化、程序化音频和响应式控制面;当前 Playwright 冒烟脚本覆盖文字移动、双情景入口、存档往返、损坏回退、断桥真实失败/重开以及桌面/手机横屏关键控件。
  • 修改文件:src/app/*src/config/scenarios.tssrc/sim/GameSimulation.tssrc/systems/{ScenarioSystem,ObjectiveSystem,EventSystem,TutorialSystem,StatisticsSystem,SaveSystem,CameraSystem,AudioSystem}.tssrc/settings/*src/render/*e2e/smoke.spec.ts 及相应 Vitest 测试。
  • 最近一次全量命令:npm.cmd test -- --reporter=dot
  • 成功结果:30 个测试文件中 136/137 用例通过;此前 SessionSystemsIntegration.test.ts 5/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 冒烟。只有全部真实通过后才能把最终门禁记为完成。

Surprises & Discoveries

  • 内置 rg.exe 在 WindowsApps 路径被拒绝执行;仓库搜索改用 PowerShell Get-ChildItem,不影响开发。
  • 目标目录完全为空且不属于 Git 仓库,因此不存在需要合并或避让的旧实现。
  • 端口 4173 已被相邻旧 Vite 项目占用;本项目与浏览器测试严格锁定 5173,避免误测旧页面。
  • 动态事件首个测试生成了选项却无法 resolve;失败消息显示组合为 undefined:hold。根因是事件从目录定义复制时漏写由目录键提供的 kind。创建事件时显式注入 kind 并把目录类型改为省略 kind 后,3 个确定性事件/目标测试全部通过。
  • 浏览器自动化必须使用本任务独立 session;默认 agent-browser daemon 可能残留其他本地项目的页面状态,即使目标端口与服务进程正确。

Decision Log

  • 2026-07-16:选择原生 Canvas 而非 Phaser。原因是空仓库首闭环需要最低依赖、明确模拟/渲染边界和可控性能。
  • 2026-07-16:选择 React 组织高密度 HUD,但所有游戏规则保留为框架无关 TypeScript。
  • 2026-07-16:先验证单单位命令闭环,再扩展大型系统,避免一次性写出未运行架构。

Voice Recognition Notes

Web Speech API 已接入统一命令管线,包含权限、监听、识别、成功、无语音、拒绝、超时、错误和重试状态;不支持时文字回退不会阻塞游戏。真实麦克风口述仍未验证,当前不得声称已完成。

Command Parsing Notes

已支持中文数字、阿拉伯数字、兵团名、目标、路线、条件、否定、多子句、上下文、代词、澄清、确认、修改和取消。当前发现“在总部北边建马厩”中空间参照“总部”可能污染建筑类型槽位,正在增加优先级回归测试。

Balance Notes

基础克制和编队数值已进入集成测试;灰谷完整胜利尚未完成平衡收口。当前首先修复训练单位出生在建筑占用格这一流程错误,再基于真实文字指挥通关调整兵力与敌军节奏。

Performance Notes

Canvas 一次绘制 48×30 网格;模拟使用固定步长并限制单帧最多 20 tick,长帧最大吸收 0.5 秒,避免后台恢复造成“死亡螺旋”。

Validation Matrix

范围 自动测试 浏览器 状态
固定步长/暂停/4× Vitest 1× 浏览器推进 自动测试通过
“侦察兵去北方”解析 Vitest agent-browser 实际下达 自动与浏览器通过
地图/基地/侦察兵显示 1440×900 截图检查 通过
资源/采集/建筑/生产/科技 14+ 集成/领域测试 M2 真实流程 通过
兵团创建/拆分/合并/规则 3 领域 + 集成 M2 创建兵团 通过
中文命令/上下文/澄清 35 定向 待完整浏览器澄清 自动测试通过
战斗/路径/迷雾 23 定向 待集成 自动测试通过
存档/设置/语音适配 GameSaveRestoreSaveSystemSessionSystemsIntegrationSpeechInput 存档往返与损坏回退已写入当前 Playwright 冒烟 自动测试通过;真实麦克风未验证
事件/教程/统计/双情景 EventObjectiveTutorialSystemStatisticsSystemScenarioSystemSessionSystemsIntegration 双情景入口与断桥失败/重开已写入当前 Playwright 冒烟 运行时已接线
灰谷完整文字通关 AshValleyPlaythrough.test.ts 尚无最终胜利浏览器证据 最近一次全量运行失败,修复中

Browser Test Evidence

  • 2026-07-16,agent-browser / Chromium,1440×900:主菜单可见;进入灰谷演习;输入预填文字命令并提交;侦察兵从 (12,16) 实际移动到北方目标;状态从 executing 变为 completed;情报军官产生抵达报告。
  • 内容检测 HAS_CONTENT,错误覆盖层 OKagent-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 命令、损坏存档回退、断桥失败结算与重开、关键命令控件可达性。此条仅记录已实现的浏览器测试流程;最终结果必须以提交前实际运行输出为准。

Remaining Work

修复并复测灰谷完整通关脚本;执行最终全量 Vitest、类型检查、lint、构建和当前 Playwright 冒烟;补齐 1366×768 与 1920×1080 的浏览器证据。真实麦克风只能在具有音频采集设备和权限交互的环境中人工验证。

Known Limitations

真实麦克风口述尚未验证。当前 Playwright 配置只覆盖 Chromium 1440×900 与 844×390,尚未覆盖其他浏览器及另外两个目标桌面尺寸。最近一次全量 Vitest 有 1 个灰谷通关用例失败,因此最终质量门禁尚未完成。

Outcomes & Retrospective

核心系统与双情景运行时已接线,存档、设置、事件、教程、结算、镜头和响应式控制面不再属于“待实现”项。项目仍处于最终门禁阶段;灰谷通关回归、当前浏览器冒烟和真实麦克风外部验证状态必须按实际结果收口。