[T.6] 团队项目:技术规格说明书

类目详情内容
所属课程 2026年春季软件工程
作业要求 [T.6] 团队项目:技术规格说明书
课程目标 经过两轮迭代完成一次完整的软件开发流程
作业价值 进行技术栈调研,明确系统架构设计与测试流程

技术栈

语言

  • 前端:GDScript
  • 后端:Go

应用开发框架

  • 前端:Godot4
  • 后端:Nakama 设计协议层部分,管理房间、游戏、玩家等,自动完成流量控制与断线重连等机制;内部逻辑、游戏引擎使用 Go 语言直接编写

运行环境

  • 前端:无特殊要求
  • 后端:
    • Go 1.22.4 + Nakama 3.22.0
    • 使用 Docker / Docker Compose 编译插件、拉起后端环境

架构设计

子系统

整个系统分为前端、后端、部署三个子系统。

前端

功能: 与用户交互,连接上权威服务器进行游玩
模块:

  • 包括 GODOT 模块

后端

功能: 游戏引擎,记录用户游玩数据、处理游玩逻辑
模块:

  • CockroachDB(游戏数据存储)
  • Nakama(网关、用户管理、实时服务)
  • Paradiced Go 插件(权威,处理游戏逻辑)

部署

功能: 提供游戏房间的公网访问
模块:

  • 腾讯云
  • Docker / Docker Compose

架构图

子系统关联

  1. Godot 前端只发送请求意图,后端返回权威状态。
  2. 对局主链路由 HSM 控制,任何中断均通过 Decision 机制恢复。
  3. 客户端断线重连后,以 FullSync / StateSync 为准重新对齐。

系统开发目标

前端

总体 UI 与交互

  • Godot 客户端完成登录、入房、发包、收包、断线重连。
  • 实现供玩家竞速的主地图场景。
  • 关键状态(位置、HP / LP、回合阶段、可操作列表)可正确显示。

后端

协议层

  1. 完成 Nakama 全生命周期对接:MatchInitMatchLoopMatchStop
  2. 设计状态同步信息:StateSyncTurnSyncDecisionAvailableGameOverFullSync
  3. Presence 管理:加入、离开、断线标记、重连恢复
  4. 客户端消息路由:OpRollDiceOpUseItemOpUseSkillOpUserChoiceOpMiniGameResultSubmit
  5. 拒绝机制:统一 OpActionRejected + ErrorCode 返回(如 ErrNotCurrentTurnErrInvalidState

分层状态机

  1. 第一层全局状态完整实现:match_init -> round_mini_game -> round_prep -> turn_loop -> boss_battle -> game_over
  2. 第二层回合状态完整实现:turn_upkeep -> main_action -> turn_moving -> turn_landed -> turn_event -> turn_end
  3. 第三层回合中断状态完整实现:wait_decision 入栈 / 出栈、超时默认选项执行
  4. Phase:HSM 发布状态时机 Phase,Action 发布动作时机 PhasePhase 用于触发事件系统
  5. Snapshot:支持保存并恢复关键状态(状态 ID、当前玩家、回合信息、决策等待态)

事件与行为

  1. 核心行为:damagehealmodify_lpmovedraw_eventadd_buffremove_buffrespawnfell_downteleport
  2. Trigger 机制:可在 pre_damage / pre_move / pre_event 等时机拦截、改写行为甚至派生新的行为
  3. EventBus 支持 Buff、道具、技能、事件多 Phase 订阅、优先级执行,用于接受信号
  4. NeedConfirm 流程:可触发 DecisionRequest,并在 UserChoice 后继续执行
  5. 信号广播:on_buff_appliedon_buff_removedPhase 可以被其他 Buff、道具、事件监听以修改其影响的行为

领域模型

  1. 领域实体:PlayerBuffItemGameEvent 分别抽象了各个游戏实体的属性与行为
  2. 常量类型:PhaseStateIDFactionCellTypeErrorCodeEntryType 等内容使用枚举常量定义,减少字符串或者数字的内涵使用
  3. ID 类型:PlayerID / BuffID / ItemID / ...,游戏引擎执行阶段全局唯一的 ID,用于代指某个领域实体

地图与随机引擎

  1. 地图引擎支持关键格类型:normal / fragile / fog / checkpoint / boss
  2. 路径计算可重复:输入相同状态与步数,输出路径与落点可预测
  3. 检查点恢复有效:死亡或坠落场景能回到最近检查点
  4. 随机引擎可复现:每局唯一随机源,固定 seed 可复现抽取序列
  5. 抽奖池语义明确:Good / Neutral / Bad 由调用方决定,LP 仅影响池内权重

错误处理

协议消息统一响应结构:

{
  "success": true,
  "code": 0,
  "message": "ok",
  "data": {}
}
  • 全局成功:0
  • 通用错误:-1
  • 系统错误:1
  • 业务错误:按模块分段(例如 1xx 登录、2xx 对局、3xx 协议)

单元测试

前端(待补)

  1. OpCode 路由测试:每个客户端消息都能进入正确处理器并返回正确反馈

后端

  1. hsm:三层状态转移、状态栈入出栈、决策超时、快照恢复
  2. action:可修改与不可修改 Action、前后触发、队列衍生执行
  3. event:Phase 发布、订阅优先级、NeedConfirm 分支
  4. gamemap:路径边界、Fragile / Fog / Checkpoint / Boss 行为
  5. rng:固定 seed 一致性、LP 权重影响、池类型边界
  6. errors:错误包装、errors.As 识别、上下文保留
  7. gamelog:回合分段起止、条目追加顺序、序列化正确性
  8. nakama:验证广播 / 单播消息数量与字段正确性
  9. net:状态、玩家、日志映射正确,构造信息正确

压力测试

前端

前端应该没有压力测试吧。

后端

  1. 高并发连接:单机 20 在线连接,持续运行无崩溃
  2. 自动测试:CLI 连续多少多少局,比如一个晚上,不发生崩溃
  3. 断线重连:CLI 测试时插入随机断线,恢复后 StateSync 关键字段一致
  4. 协议健壮:注入未知 OpCode、空字段、越权请求,服务端可拒绝且不中断全局对局

真实测试

前端

前端的真实测试,通过脚本模拟用户的真实物理输入,验证 UI 响应、表现层渲染以及与后端的网络握手是否正常。

  1. 使用 GUT 框架中的 InputSender 模块。编写 GDScript 测试脚本,通过代码直接向特定 Control 节点(如掷骰子按钮、道具确认按钮)注入 InputEventMouseButton 以模拟真实物理点击,验证事件总线的响应
  2. 前端依靠后端的 Action Log 驱动动画,测试脚本需要在短时间内瞬间向前端的消费者队列塞入 50 条连续的 MoveActionDamageAction。断言游戏表现层是否能按顺序平滑播完所有动画,而不发生信号丢失、协程死锁或动画卡顿
  3. 利用 Godot 的 --headless 命令行参数,编写外层 Shell 脚本瞬间拉起 3 个无头客户端和一个带 UI 的观察客户端,模拟多玩家真实对局中的点对点数据交互和断线重连表现

后端

直接利用 Nakama 的 SDK 建立 WebSocket 连接,完全绕过 Godot 前端的 UI 限制发包,测试一些恶意攻击的部分。

1. 越权

  • 在 A 玩家的回合(此时状态机应处于 TurnLoopState 的移动阶段),控制 B 玩家的 Bot 强行向服务端发送 OpRollDice(掷骰子)或 OpUseItem(使用道具)的数据包

2. 伪造

  • WaitDecisionState(等待玩家选择道具目标)阶段,恶意 Bot 故意构造 JSON / Protobuf 载荷,发送一个自己背包里根本不存在的道具 ID,或者把对敌人造成的伤害值手动修改为 9999

3. 重放

  • 攻击模拟:利用 Go 的协程(goroutine),让恶意 Bot 在 5 毫秒内并发向后端发送 100 次相同的“使用稀有回血道具”的网络请求

文档编写

  1. 协议文档:后端协议层的路由,以及返回的详细类型,用于前后端进行对接
  2. 状态机文档:后端状态转移实现一致
  3. 错误处理文档:覆盖错误类型到错误码映射
  4. 启动使用文档:README.mdstartup.mdcli.md 能指导构建可运行的后端
posted @ 2026-04-21 10:03  BitAction  阅读(18)  评论(0)    收藏  举报