[T.6]技术规格说明书

Z-Spire(植胜僵场)技术规格说明书

项目 内容
这个作业属于哪个课程 2026 年北航敏捷软件工程
这个作业的要求在哪里 [T.6] 团队项目:技术规格说明书
我们在这个课程的目标是 通过完整的敏捷开发流程,实践一款可玩、可发布的独立游戏产品
这个作业在哪个具体方面帮助我实现目标 凝练团队对项目技术方案的共识;为实现阶段提供统一技术依据
  • 项目名称:Z-Spire / 植胜僵场
  • 代码仓库aStringCat/Z-Spire
  • 项目版本:v0.1.0(对应 package.json

0. 目录


1. 写作目标与范围

1.1 写作目标

本技术规格说明书的目标是建立团队在实现阶段的技术共识,回答以下问题:

  1. 我们用什么技术栈?为什么这样选?
  2. 游戏由哪些子系统和模块组成,它们如何协作?
  3. 实现阶段要完成哪些代码编写和文档编写工作?
  4. 如何量化系统质量,定义发布出口条件?
  5. 面临哪些技术风险?如何应对?
  6. 如何部署和维护?

1.2 范畴与边界

在范围内 不在范围内
客户端代码(场景、战斗、卡牌、地图、存档)的架构与接口 游戏设计与数值平衡(见 doc/关于我们的游戏.md
技术栈、构建、打包、部署方案 美术资源管理、商业化运营
测试计划、性能量度、出口条件 用户调研与社区运营

配套文档:README.md(快速上手)。


2. 概念和术语

2.1 术语表

术语 英文 含义
Roguelike Roguelike 永久死亡程序生成两大特征的关卡式游戏类型
回合制 Turn-based 玩家与敌方交替行动的战斗模式
戴夫(Player) Player 玩家所操作的固定主角,名字来源于 PvZ 系列
节点(Node) Node 地图瓦片中的可交互点,含战斗 / 事件 / 商店 / 休息四类
行动意图(Intent) Intent 敌人下一回合将执行的动作,战斗 UI 中提前显示——核心策略信息
状态效果(StatusEffect) StatusEffect 玩家或敌人身上的持久增益/减益,共 7 种(strength / dexterity / weak / vulnerable / poison / thorns / regeneration)
能量(Energy) Energy 出牌资源,每回合开始恢复至 3 点
种子(Seed) Seed 用于可复现随机数生成的整数
一次性道具(Consumable) Consumable 不进入牌堆的战斗道具,跨战斗持有、使用即消耗。当前 3 种:毁灭菇 / 小推车 / 钉耙

2.2 特殊定义说明

上表加粗的术语在本文档中具有项目特化定义,与字面意思或其它游戏中的常见含义略有差别,请严格按本表含义理解。

2.3 易混淆术语对比

术语 A 术语 B 区别
卡牌(Card) 一次性道具(Consumable) 卡牌进入牌堆参与抽牌;道具独立存放于 GameState.consumables,战斗 UI 中直接点击使用、不占能量
牌库(Master Deck) 抽牌堆(Draw Pile) 前者是整局拥有的全部卡牌 ID 集合;后者是当前战斗中还未抽出的部分。战斗开始时 drawPile = [...masterDeck] 后洗牌
格挡(Block) 护甲(Armor) 本游戏只有格挡(回合结束时清零),不存在永久护甲

3. 技术栈

3.1 程序设计语言

TypeScript ^6.0.3,strict 模式开启。

  • 选择理由:类型严格,多人协作下能在编译期拦住大量低级 bug;与 Phaser 3 官方类型定义无缝集成;同一份源码可同时构建为 Web 版和 Electron 桌面版
  • 强约束:tsconfig.jsonstrict / noImplicitAny / strictNullChecks 全部打开,代码中不允许出现隐式 any

3.2 应用开发框架

类别 选型 版本 作用
游戏引擎 Phaser ^3.90.0 渲染、场景管理、输入、Tween、Arcade 物理
构建工具 Vite ^8.0.8 开发服务器 HMR + 生产打包
桌面打包 Electron ^41.2.1 dist/ 包装成 Windows / macOS 可执行程序
桌面发行 electron-builder ^26.8.1 portable .exe 与 DMG 产物生成
代码格式化 Prettier ^3.8.3 CI 强制格式校验

运行时唯一的第三方依赖是 Phaser,其它均为 devDependencies,供应链风险小。

3.3 运行环境

3.3.1 开发环境

要求
Node.js ≥ 18
npm ≥ 9
操作系统 跨平台(Windows / macOS / Linux)
推荐编辑器 VS Code + 官方 TypeScript 扩展

3.3.2 用户运行环境

形态 最低要求
Web 端 支持 WebGL 2.0 的现代浏览器:Chrome / Edge ≥ 90、Firefox ≥ 88、Safari ≥ 15
Windows 桌面端 Windows 10 64-bit 及以上;约 200 MB 磁盘空间
macOS 桌面端 macOS 11 (Big Sur) 及以上;Apple Silicon + Intel 双架构

不支持:移动端浏览器(触屏适配未完成,排到 Beta+)、IE 系列。

3.3.3 测试 / CI 环境

GitHub Actions ubuntu-latest runner,Node 18 LTS;npm run action 在 CI 中串联 npm ci + prettier:check + npm test

3.4 核心命令

命令 作用
npm run dev 启动开发服务器(localhost:3000)
npm run build 生产构建(tsc && vite build
npm run typecheck TypeScript 类型检查
npm test 运行 node --test 单元测试
npm run action CI 组合:ci + prettier:check + test
npm run build:exe / build:mac 打包 Windows portable exe / macOS DMG

4. 软件架构

Z-Spire 是单机离线游戏——无服务端、无数据库、无对外 API。整体只有一个客户端进程,内部按职责分 6 层;Electron 桌面版只是在 Web 版外加桌面壳,不增加新层。

4.1 子系统划分

4.1.1 总体架构图

graph TB subgraph "场景层 / Scenes" Scenes[BootScene / MainMenuScene<br/>MapScene / BattleScene<br/>RewardScene / EventScene / GameOverScene] end subgraph "UI 组件层" UI[ConsumableBar<br/>ShopPanel<br/>DeckPackPanel] end subgraph "核心层 / Core" Core[GameState 单例<br/>EventBus / SaveManager<br/>CardRegistry / ShopService<br/>DeckPackService / Logger] end subgraph "业务层 / Domain" Domain[card / battle / map<br/>纯逻辑,不依赖 Phaser] end subgraph "数据层 / Data" Data[cards / enemies / events<br/>balance / shop] end subgraph "工具层 / Utils" Utils[random / shuffle<br/>tween / GifSprite] end LocalStorage[(localStorage)] Scenes --> UI Scenes --> Core Scenes --> Domain UI --> Core Domain --> Core Domain --> Data Core --> Data Domain --> Utils Core <--> LocalStorage

4.1.2 各子系统的功能任务

# 子系统 路径 功能任务
1 场景层(Scenes) src/scenes/ Phaser Scene:渲染 + 输入响应;不含业务逻辑
2 UI 组件层 src/ui/ 可跨场景复用的 UI 组件;通过回调与 Core 交互;不持业务状态
3 核心层(Core) src/core/ 全局单例与静态服务:状态、事件总线、存档、注册表、业务 Service、日志
4 业务层(Domain) src/card/ src/battle/ src/map/ 纯逻辑模块(卡牌 / 战斗 / 地图三个子包);不依赖 Phaser,可独立单元测试
5 数据层(Data) src/data/ 纯静态数据;只能 import type,不依赖任何运行时模块
6 工具层(Utils) src/utils/ 随机数、洗牌、动画辅助、GIF 动画包装

4.1.3 子系统间的关系与工作模式

场景流转图:

stateDiagram-v2 [*] --> BootScene BootScene --> MainMenuScene: 资源加载完成 MainMenuScene --> MapScene: 新游戏 / 继续游戏 MapScene --> BattleScene: 撞到敌人节点 MapScene --> EventScene: 撞到事件节点 BattleScene --> RewardScene: 战斗胜利 BattleScene --> GameOverScene: 玩家死亡 RewardScene --> MapScene EventScene --> MapScene MapScene --> GameOverScene: 通关最终楼层 GameOverScene --> MainMenuScene

分层依赖原则(界面与业务逻辑分离的落地)

  • 按稳定性从内到外组织目录:utils → data → core → card/battle/map → ui → scenes。依赖方向单向、禁止反向。
  • Scene 不含战斗逻辑:通过订阅 EventBus 事件刷新 UI,业务决策全在 BattleManager / ShopService
  • UI 不触业务状态:构造函数接收 Options 对象(getXxx / onXxx 回调),不直接访问 GameState
  • 业务层零 import Phasersrc/battle / card / map / data 目录全部可在 Node 环境独立运行

4.2 各子系统内部模块

4.2.1 模块清单与功能任务

子系统 主要模块(文件) 功能任务
Scenes BootScene(219) / MainMenuScene(128) / MapScene(859) / BattleScene(1101) / RewardScene(165) / EventScene(346) / GameOverScene(102) 7 个 Phaser.Scene。MapScene 负责地牢探索;BattleScene 负责回合制战斗,是全项目最大的文件
UI ConsumableBar(136) / ShopPanel(238) / DeckPackPanel(124) 分别挂在 BattleScene 和 MapScene,通过回调与 Core Service 交互
Core GameState(单例,运行态全字段)/ EventBus(类型安全发布订阅,11 种事件)/ SaveManager(localStorage 封装)/ CardRegistry(卡牌索引)/ ShopService(购物业务)/ DeckPackService(牌组快照)/ Logger(分级日志) 有状态 → 单例;无状态业务 → 静态类 / 模块函数
Card CardData / CardEffect / CardRegistry / Deck / CardSprite 卡牌数据类型、7 种效果引擎、抽牌堆 / 弃牌堆 / 消耗堆管理
Battle BattleManager(332) / TurnManager / BattleUnit / Player / Enemy / StatusEffect 回合制战斗主控;敌人 AI 采用预设 pattern 循环(数据驱动)
Map MapNode / MapGenerator(141) 二叉空间分割(BSP)生成房间式地牢;曼哈顿距离 ≤ 4 的视野渲染
Data cards(31 张 + 3 道具) / enemies(8) / events(6) / balance / shop 纯静态常量,Vite 打包时内联到 bundle,运行时零 JSON.parse
Utils random(带种子 PRNG)/ shuffle(Fisher–Yates)/ tween / GifSprite 所有随机走统一 PRNG,保证 seed 可复现

4.2.2 模块间的关系与工作模式

核心层内部一个关键的协作模式是基于 EventBus 的发布-订阅

  • BattleManager 修改血量后 emit('PLAYER_HP_CHANGED', {...})BattleScene 订阅该事件后刷新血条 UI
  • 两者互不 import,只共享事件协议接口 GameEvents
  • 这使得 Core / Domain 层完全不感知 Phaser 的存在

设计原则在具体代码中的体现(对应课程"请考虑"的设计原则):

原则 落地方式
抽象 TS 字面量联合类型把"卡牌效果 7 种 / 状态 7 种 / 商品 2 种"锁成封闭集合,新增类型必然触发所有 switch 的编译期报错
内聚 每个模块单一职责:Deck 只管卡牌 ID 流转、BattleManager 只管战斗状态机、EventBus 只做订阅发布
耦合 跨层通信靠 EventBus + UI 层回调注入;ShopPanel 不 import GameState 也不 import ShopService
模块化 目录按稳定性梯度组织;Beta 阶段引入 ESLint no-restricted-imports 规则自动拦截违规依赖
信息隐藏与封装 GameState 通过 addCardToDeck / takeDamage / spendGold 等方法操作;禁止外部直接赋值字段
系统错误记录机制 src/core/Logger.ts 分级日志(dev 下 log / warn,prod 只留 error);日志不持久化、崩溃不上报、用户反馈走 GitHub Issues
应对需求变化的灵活性 新增卡牌 / 敌人 / 事件只改 src/data/*.ts 单文件;切换存档介质只改 SaveManager.ts

5. 软件设计和实现

5.1 功能点与代码编写任务

按优先级 P0(Alpha 必做)→ P1(Beta 必做)→ P2(Release 之后)排序:

优先级 模块 功能 涉及文件(预计)
P0 战斗 卡牌拖拽出牌(替代点击) src/scenes/BattleScene.ts src/card/CardSprite.ts
P0 战斗 完整伤害飘字与受击动画 src/scenes/BattleScene.ts src/utils/tween.ts
P0 地图 休息节点(恢复 30% HP / 升级一张牌) src/scenes/MapScene.ts 新建 RestPanel.ts
P0 测试 建立 node --test 最小单测套件 test/ 新建
P0 运维 提交 GitHub Actions workflow .github/workflows/ci.yml 新建
P1 战斗 Boss 战与精英战的差异化 UI BattleScene.ts data/enemies.ts
P1 卡牌 卡牌升级系统(提升数值) CardData.ts Deck.ts GameState.ts SaveManager.ts
P1 核心 EventBus.emit 订阅者异常隔离 src/core/EventBus.ts
P1 核心 全局 window.onerror 兜底转 Logger.error src/main.ts src/core/Logger.ts
P1 数据 扩充至 ≥ 50 张卡牌 / ≥ 15 种敌人 cards.ts enemies.ts
P1 系统 存档 schemaVersion 字段 + 迁移逻辑 SaveManager.ts GameState.ts
P2 系统 多周目难度 / 双语 / 音效 待设计

商店子系统在 v1.1 已完成,不列入本路线图。

5.2 系统文档编写清单

本项目配套的系统文档如下:

文档 详细程度
本《技术规格说明书》 架构分层、子系统职责、核心模块、测试计划、性能指标、风险、部署方案
《README》 项目概览、环境要求、安装与构建命令
《CLAUDE.md》 编码规范(命名、目录结构、导入顺序)、团队协作约定
《关于我们的游戏》 核心玩法、游戏机制、设计思路
《存档格式规范》(Beta 阶段补齐) 存档字段定义、版本兼容策略、迁移规则
《卡牌制作指南》(Beta 阶段补齐) 卡牌数据格式、效果组合范例、平衡参考数值

详细的数据结构定义和接口说明以 TypeScript interface + JSDoc 注释的形式内嵌在源码中,不单独另立文档。

5.3 功能的详细逻辑设计

按课程要求,本节暂不做要求,将在实现阶段补充完善。

实现时每个功能点的详细逻辑将以下列形式固化:

  • 关键算法以 TypeScript 函数 + JSDoc 注释写在源码里(如 src/card/CardEffect.ts 的伤害计算)
  • 状态机和回合流程以 TSDoc 标注状态转移条件(如 src/battle/BattleManager.ts 的回合主循环)
  • 跨模块协作以 EventBus 事件序列描述(见 §4.2.2)

5.4 数据库和 API 接口设计

按课程要求,本节暂不做要求。且本项目有如下特殊情况:

  • 无数据库:持久化只使用浏览器 localStorage,键名 z-spire-save,内容为 JSON.stringify(GameState) 的子集;相关字段约定见未来的《存档格式规范》文档
  • 无对外 API:不开接口给第三方,也不消费任何外部服务(除 GitHub Pages / CDN 托管的静态资源)
  • 内部模块接口:以 TypeScript interface 形式固化在源码中,典型如 CardData / EnemyData / ShopOffer / GameEvents;字段含义通过类型名和 JSDoc 自我说明

5.5 输入假设与异常处理

对应课程"业务流程层面"请考虑的内容:

输入来源 假设 不满足时的处理
键盘 / 鼠标事件 相邻事件间隔 ≥ 一帧、当前不在动画中 BattleManager 维护动画锁屏蔽重入
localStorage 存档 合法 JSON、字段类型匹配当前 schema SaveManager.load() 用 try/catch 包 JSON.parse,损坏则返回 null、视作无存档
src/data/*.ts 数据 编译期 ID 全局唯一、数值合法 依赖 TS strict 编译期校验,运行时不重复校验
EventBus 订阅者回调 不抛异常 当前无 try/catch 隔离(已知缺陷,P1 修复)
Enemy.actionPattern 非空数组、type 合法 currentActionIndex % pattern.length 防越界

数值防御:所有伤害 / 治疗 / 金币变更用 Math.max(0, x)Math.min(max, x) 夹紧;spendGold 扣费前先校验余额。


6. 软件测试和性能量度

6.1 测试计划

6.1.1 测试设计总览

测试按层级从低到高分为 5 类,越往上覆盖面越广、执行成本也越高:

层级 目的 执行者
单元测试 隔离单个模块,验证边界值与关键路径 CI 自动
集成测试 验证多模块协作,脚本化模拟真实游戏流程 CI 自动
性能测试 高密度渲染场景下的帧率与内存稳定性 手动 + DevTools
真实测试 人工 playtest,验证玩家视角下的功能与体验 团队成员 + 邀请玩家
防作弊 / 健壮性测试 手工模拟存档篡改、数值溢出等边界情况 手动

6.1.2 单元测试

模块 重点测试内容 Alpha 覆盖率 Beta 覆盖率
card/CardEffect.ts 7 种效果的边界值(0 / 最大 / 负数 / 含 buff/debuff 修正 / 格挡吸收) ≥ 80% ≥ 90%
card/Deck.ts 抽牌、洗牌、消耗堆、抽牌堆空时回流 ≥ 80% ≥ 90%
battle/StatusEffect.ts 状态叠加规则、永久效果、回合末结算 ≥ 70% ≥ 90%
battle/BattleManager.ts 完整战斗流程(出牌、敌人回合、胜负判定) ≥ 60% ≥ 80%
core/EventBus.ts on / off / emit、多订阅者、异常隔离 ≥ 80% ≥ 90%
core/SaveManager.ts 存档读写、损坏存档容错、版本不兼容容错 ≥ 60% ≥ 80%
map/MapGenerator.ts 给定 seed 的地图生成可复现性、连通性 ≥ 50% ≥ 70%

框架选型node --test(Node 18+ 内置测试运行器)+ node:assert/strict;无额外依赖,与 package.json"test": "node --test" 对齐。

整体覆盖率阈值:Alpha ≥ 50% / Beta ≥ 70% / Release ≥ 80%。

6.1.3 压力测试

关于"压力测试"的说明:Z-Spire 是单机离线游戏,没有服务器、没有 QPS、没有并发用户。课程原文里"压力测试 / 具体压力指标"在本项目中翻译为高密度渲染场景的压力测试——即同屏对象数、Tween 数、连续运行时长等维度下的帧率与内存稳定性。

场景 测量指标 具体压力指标(通过线)
战斗:3 敌人 + 10 手牌 + ≥ 20 飘字 帧率 ≥ 45 FPS
大地图(最大 BSP 深度)渲染 帧率 ≥ 60 FPS
连续游戏 30 分钟 内存占用增长 ≤ 50 MB(无明显泄漏)
快速连续出牌 10 次 无掉帧、无事件丢失 100%
存档一次 IO 耗时 ≤ 50 ms

测量工具:Chrome DevTools Performance + Memory snapshot;Phaser.Game.loop.actualFps 代码内读取。

6.1.4 真实测试

测试类型 具体测试细节 频率
功能性玩测 团队成员完整通关一周目,记录所有 Bug(崩溃 / 视觉异常 / 数值异常) 每次迭代结束
平衡性玩测 多名队员各自通关 5 次,统计平均通关率、最常死亡的楼层、胜率最高的卡组 每次数值改动后
新手测试 邀请 5 名非团队成员(且非 Roguelike 卡牌玩家)盲玩 30 分钟,记录"看不懂"和"卡住"的时刻 Alpha / Beta 节点各一次
存档兼容性测试 用旧版本存档加载新版本游戏,验证能正确兼容或友好提示 每次 GameState 结构变更后
兼容性测试 Chrome / Firefox / Safari / Edge 各跑一遍主流程;Windows / macOS 桌面端各跑一遍 每次发布前

6.2 软件性能

6.2.1 性能量度方式

测量环境基准:Intel i5-8250U / 8 GB RAM / Chrome 稳定版;Web 端走本地 npm run preview 或同局域网 HTTP;Electron 端走 build:exe 产物。低于此基准的机器不承诺达标,但必须"能运行不崩溃"。

指标 目标 测量方式
一般场景帧率 ≥ 60 FPS Phaser.Game.loop.actualFps 读数 / Chrome Performance 面板
高密度场景帧率 ≥ 45 FPS 3 敌 + 10 手牌 + ≥ 20 飘字
启动时间(本地) ≤ 3 秒 冷启动到 MainMenuScene 第一帧
启动时间(GitHub Pages) ≤ 6 秒 首次无缓存访问
存档大小 ≤ 50 KB JSON.stringify(state).length
Web 包体 ≤ 5 MB(gzip) dist/ 目录 gzip 后
Electron 包体 ≤ 200 MB release/ 目录产物大小
30 分钟内存增长 ≤ 50 MB DevTools Memory snapshot 前后对比
存档 IO ≤ 50 ms performance.now() 包裹 SaveManager.save()

6.2.2 能力边界(从技术实现角度)

维度 边界 推导依据
同屏战斗对象数 ≤ 5 敌人 + ≤ 15 手牌 + ≤ 50 飘字 Phaser 3 WebGL 批渲染可轻松过千 Sprite,真正瓶颈是 Tween 数量
单局游戏时长 ≤ 30 分钟维持 ≤ 50 MB 内存增长 无长对象池、所有订阅在 Scene 切换时通过 EventBus.clear() 释放
地图尺寸 BSP 递归深度 ≤ 5 超过会导致房间密度过高、寻路视觉拥挤
存档体积 目标 ≤ 50 KB 主要被 mapData(瓦片 + 节点)和 floorShopState 占据
启动时间 ≤ 3 秒本地 / ≤ 6 秒首次在线 主要耗时是 Phaser 库解析(~900 KB gzip)

6.3 出口条件

阶段 发布条件
Alpha ① 主流程不崩溃(BootScene → 通关 → GameOverScene);② ≥ 20 卡 / ≥ 5 敌 / ≥ 3 层;③ 单测覆盖 ≥ 50%;④ 60 FPS(一般场景);⑤ Web + Electron 双端构建成功
Beta ① P0 + P1 全部完成;② ≥ 35 卡 / ≥ 10 敌 / ≥ 1 Boss;③ 单测 ≥ 70%;④ 集成测试 IT-01 ~ IT-05 全过;⑤ 存档版本兼容机制就绪;⑥ ≥ 5 名非团队成员完成新手测试
Release ① ≥ 50 卡 / ≥ 15 敌 / ≥ 3 Boss;② 单测 ≥ 80%;③ 平均通关率 30%–60%;④ 30 min 玩测内存增长 ≤ 50 MB;⑤ Web 与 Electron 双端目标平台手动验收通过;⑥ 完整新手引导

7. 技术风险识别和评估

概率高 / 中 / 低 = 可能发生的风险;已发生 = 当前已观察到的现状。
严重度 = 阻塞发布或严重影响体验; = 影响部分玩家或需大规模返工; = 可容忍或易规避。

风险 严重度 概率 应对
缺失自动化测试 已发生 Alpha 优先建立 node --test + GitHub Actions(npm run action 已就位)
数值平衡难调 集中在 balance.ts;Beta 编写自动化模拟器按固定 seed 跑 1000 局评估通关率
存档版本不兼容 schemaVersion 字段;不兼容时优雅降级(清存档 + 通知)而非崩溃
多分支并行冲突 严格 PR review;高频 rebase;冲突高发文件专人 owner
浏览器兼容(Safari WebGL) CI 加 Playwright 跨浏览器测试;Electron 作为后备
手感反馈不足 已发生 Beta 引入 howler.js 音频 + Phaser tween 序列化
Phaser 3 学习曲线陡峭 BattleScene 由 1-2 人深入维护;其他人不直接改

8. 软件部署和维护

8.1 部署环境

目标平台 运行环境 产物
Web(GitHub Pages) 静态 HTTP 托管;客户端为现代浏览器(见 §3.3.2) dist/ 目录(Vite 构建产出)
Windows 桌面 Windows 10 64-bit+ release/植胜僵场 0.1.0.exe(portable,无需安装)
macOS 桌面 macOS 11+,双架构(Apple Silicon + Intel) release/植胜僵场-0.1.0.dmg

8.2 部署流程

graph LR Dev[开发者本地] -->|push| GH[GitHub Repo] GH -->|trigger| Action[GitHub Actions] Action -->|npm run action| Build[Vite 构建 + 测试] Build -->|dist/| Deploy[部署 gh-pages 分支] Deploy -->|GitHub Pages| Web[公网访问] GH -->|手动触发| Electron[Electron 打包] Electron --> Release[release/ 产物]
  • Web 构建命令npm run build(即 tsc && vite build
  • Web 部署目标gh-pages 分支根目录;vite.config.tsbase: './' 确保相对路径
  • Electron 打包命令npm run build:exe / npm run build:mac
  • 当前缺口.github/workflows/ 下的 YAML 尚未提交(已列入 §5.1 P0)

8.3 运行与维护

  • 日志策略:本地 console 分级输出(dev 保留 log / warn,prod 仅保留 error,由 Vite 在生产构建下 tree-shake 掉低级别调用)。日志不持久化、不做崩溃上报
  • 用户反馈:通过 GitHub Issues 收集
  • 故障复现:所有随机事件(BSP 切分、敌人投放、商品抽取、伤害骰子等)统一走带种子 PRNG,拿到玩家的 GameState.seed 即可本地复刻
  • 文档同步:技术设计文档与代码实现同步更新;对文档的修改通知到团队每一位成员
posted @ 2026-04-22 19:31  魔法细胞  阅读(21)  评论(0)    收藏  举报