712 lines
21 KiB
Markdown
712 lines
21 KiB
Markdown
# 设计文档
|
||
|
||
## 概述
|
||
|
||
本项目是一款基于 Godot 4.x 引擎开发的 2D 多人在线 AI 小镇游戏,采用客户端-服务器架构。游戏的核心特性是持久化的多人世界,玩家创建的角色在玩家离线时会作为 NPC 继续存在于游戏世界中。游戏优先支持网页端(HTML5 导出),并预留移动端适配接口。
|
||
|
||
### 技术栈
|
||
|
||
- **游戏引擎**: Godot 4.x
|
||
- **编程语言**: GDScript
|
||
- **网络协议**: WebSocket (用于实时通信)
|
||
- **数据格式**: JSON (用于数据序列化)
|
||
- **导出平台**: HTML5 (Web), 预留 Android/iOS 支持
|
||
- **后端服务**: 简单的 WebSocket 服务器 (可使用 Node.js + ws 或 Python + websockets)
|
||
|
||
## 架构
|
||
|
||
### 整体架构
|
||
|
||
游戏采用客户端-服务器架构,分为以下主要层次:
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ 客户端 (Godot HTML5) │
|
||
├─────────────────────────────────────────┤
|
||
│ 表现层 (UI/Rendering) │
|
||
│ ├─ 场景渲染 │
|
||
│ ├─ UI 界面 │
|
||
│ └─ 动画系统 │
|
||
├─────────────────────────────────────────┤
|
||
│ 游戏逻辑层 │
|
||
│ ├─ 角色控制器 │
|
||
│ ├─ 对话系统 │
|
||
│ ├─ 输入处理 │
|
||
│ └─ 状态管理 │
|
||
├─────────────────────────────────────────┤
|
||
│ 网络层 │
|
||
│ ├─ WebSocket 客户端 │
|
||
│ ├─ 消息序列化/反序列化 │
|
||
│ └─ 状态同步 │
|
||
└─────────────────────────────────────────┘
|
||
↕ WebSocket
|
||
┌─────────────────────────────────────────┐
|
||
│ 服务器 (WebSocket Server) │
|
||
├─────────────────────────────────────────┤
|
||
│ 连接管理 │
|
||
│ ├─ 客户端连接池 │
|
||
│ ├─ 身份验证 │
|
||
│ └─ 心跳检测 │
|
||
├─────────────────────────────────────────┤
|
||
│ 游戏状态管理 │
|
||
│ ├─ 世界状态 │
|
||
│ ├─ 角色状态 │
|
||
│ └─ 消息广播 │
|
||
├─────────────────────────────────────────┤
|
||
│ 数据持久化 │
|
||
│ ├─ 角色数据存储 │
|
||
│ ├─ 世界状态存储 │
|
||
│ └─ JSON 文件系统 │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
### 客户端架构
|
||
|
||
客户端采用 Godot 的场景树结构,主要节点组织如下:
|
||
|
||
```
|
||
Main (Node)
|
||
├─ NetworkManager (Node) - 网络连接管理
|
||
├─ GameStateManager (Node) - 游戏状态管理
|
||
├─ UILayer (CanvasLayer) - UI 层
|
||
│ ├─ LoginScreen (Control) - 登录界面
|
||
│ ├─ CharacterCreation (Control) - 角色创建界面
|
||
│ ├─ HUD (Control) - 游戏内 UI
|
||
│ └─ DialogueBox (Control) - 对话框
|
||
└─ GameWorld (Node2D) - 游戏世界
|
||
├─ TileMap (TileMap) - 场景地图
|
||
├─ Characters (Node2D) - 角色容器
|
||
│ ├─ PlayerCharacter (CharacterBody2D) - 本地玩家
|
||
│ └─ RemoteCharacter (CharacterBody2D) - 其他角色
|
||
└─ Camera (Camera2D) - 摄像机
|
||
```
|
||
|
||
### 服务器架构
|
||
|
||
服务器采用事件驱动架构,主要模块包括:
|
||
|
||
- **ConnectionManager**: 管理 WebSocket 连接
|
||
- **AuthenticationService**: 处理玩家身份验证
|
||
- **WorldState**: 维护游戏世界状态
|
||
- **CharacterManager**: 管理所有角色(在线/离线)
|
||
- **MessageRouter**: 路由和广播消息
|
||
- **PersistenceService**: 数据持久化服务
|
||
|
||
## 组件和接口
|
||
|
||
### 1. 网络管理器 (NetworkManager)
|
||
|
||
**职责**: 管理客户端与服务器的 WebSocket 连接
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name NetworkManager extends Node
|
||
|
||
signal connected_to_server()
|
||
signal disconnected_from_server()
|
||
signal connection_error(error: String)
|
||
signal message_received(message: Dictionary)
|
||
|
||
func connect_to_server(url: String) -> void
|
||
func disconnect_from_server() -> void
|
||
func send_message(message: Dictionary) -> void
|
||
func is_connected() -> bool
|
||
```
|
||
|
||
**消息协议**:
|
||
所有消息使用 JSON 格式,包含以下字段:
|
||
```json
|
||
{
|
||
"type": "message_type",
|
||
"data": {},
|
||
"timestamp": 1234567890
|
||
}
|
||
```
|
||
|
||
消息类型包括:
|
||
- `auth_request`: 身份验证请求
|
||
- `auth_response`: 身份验证响应
|
||
- `character_create`: 创建角色
|
||
- `character_move`: 角色移动
|
||
- `character_state`: 角色状态更新
|
||
- `dialogue_send`: 发送对话
|
||
- `world_state`: 世界状态同步
|
||
|
||
### 2. 角色控制器 (CharacterController)
|
||
|
||
**职责**: 处理角色的移动、动画和状态
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name CharacterController extends CharacterBody2D
|
||
|
||
var character_id: String
|
||
var character_name: String
|
||
var is_online: bool
|
||
var move_speed: float = 200.0
|
||
|
||
func move_to(direction: Vector2) -> void
|
||
func set_position_smooth(target_pos: Vector2) -> void
|
||
func play_animation(anim_name: String) -> void
|
||
func set_online_status(online: bool) -> void
|
||
```
|
||
|
||
**状态**:
|
||
- `idle`: 静止状态
|
||
- `walking`: 行走状态
|
||
- `talking`: 对话状态
|
||
|
||
### 3. 对话系统 (DialogueSystem)
|
||
|
||
**职责**: 管理角色之间的对话交互
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name DialogueSystem extends Node
|
||
|
||
signal dialogue_started(character_id: String)
|
||
signal dialogue_ended()
|
||
signal message_received(sender: String, message: String)
|
||
|
||
func start_dialogue(target_character_id: String) -> void
|
||
func send_message(message: String) -> void
|
||
func end_dialogue() -> void
|
||
func show_bubble(character_id: String, message: String, duration: float) -> void
|
||
```
|
||
|
||
**对话模式**:
|
||
- **直接对话**: 玩家与另一个角色一对一对话
|
||
- **气泡对话**: 附近角色的对话以气泡形式显示
|
||
|
||
### 4. 输入处理器 (InputHandler)
|
||
|
||
**职责**: 处理多平台输入(键盘、触摸、虚拟摇杆)
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name InputHandler extends Node
|
||
|
||
signal move_input(direction: Vector2)
|
||
signal interact_input()
|
||
signal ui_input(action: String)
|
||
|
||
func get_move_direction() -> Vector2
|
||
func is_interact_pressed() -> bool
|
||
func setup_virtual_controls() -> void
|
||
```
|
||
|
||
**输入映射**:
|
||
- **桌面端**: WASD/方向键移动,E 键交互
|
||
- **移动端**: 虚拟摇杆移动,交互按钮
|
||
|
||
### 5. 游戏状态管理器 (GameStateManager)
|
||
|
||
**职责**: 管理游戏的全局状态和场景切换
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name GameStateManager extends Node
|
||
|
||
enum GameState {
|
||
LOGIN,
|
||
CHARACTER_CREATION,
|
||
IN_GAME,
|
||
DISCONNECTED
|
||
}
|
||
|
||
var current_state: GameState
|
||
var player_data: Dictionary
|
||
|
||
func change_state(new_state: GameState) -> void
|
||
func save_player_data() -> void
|
||
func load_player_data() -> Dictionary
|
||
```
|
||
|
||
### 6. 世界管理器 (WorldManager)
|
||
|
||
**职责**: 管理游戏世界中的所有角色和对象
|
||
|
||
**接口**:
|
||
```gdscript
|
||
class_name WorldManager extends Node
|
||
|
||
var characters: Dictionary = {} # character_id -> CharacterController
|
||
|
||
func spawn_character(character_data: Dictionary) -> void
|
||
func remove_character(character_id: String) -> void
|
||
func update_character_state(character_id: String, state: Dictionary) -> void
|
||
func get_nearby_characters(position: Vector2, radius: float) -> Array
|
||
```
|
||
|
||
## 数据模型
|
||
|
||
### 角色数据 (Character Data)
|
||
|
||
```gdscript
|
||
{
|
||
"id": "unique_character_id",
|
||
"name": "角色名称",
|
||
"owner_id": "player_account_id",
|
||
"position": {
|
||
"x": 100.0,
|
||
"y": 200.0
|
||
},
|
||
"is_online": true,
|
||
"appearance": {
|
||
"sprite": "character_01",
|
||
"color": "#FFFFFF"
|
||
},
|
||
"created_at": 1234567890,
|
||
"last_seen": 1234567890
|
||
}
|
||
```
|
||
|
||
### 世界状态 (World State)
|
||
|
||
```gdscript
|
||
{
|
||
"scene_id": "datawhale_office",
|
||
"characters": [
|
||
// 角色数据数组
|
||
],
|
||
"timestamp": 1234567890
|
||
}
|
||
```
|
||
|
||
### 对话消息 (Dialogue Message)
|
||
|
||
```gdscript
|
||
{
|
||
"sender_id": "character_id",
|
||
"receiver_id": "character_id", // 可选,为空表示广播
|
||
"message": "对话内容",
|
||
"timestamp": 1234567890
|
||
}
|
||
```
|
||
|
||
## 正确性属性
|
||
|
||
*属性是一个特征或行为,应该在系统的所有有效执行中保持为真——本质上是关于系统应该做什么的正式陈述。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。*
|
||
|
||
### 属性 1: 角色创建唯一性
|
||
*对于任意*两个成功创建的角色,它们的角色 ID 应该是唯一的,不会发生冲突
|
||
**验证需求: 1.5**
|
||
|
||
### 属性 2: 角色移动能力
|
||
*对于任意*创建或加载到场景的角色,该角色应该具有基础移动能力(可以响应移动指令)
|
||
**验证需求: 2.1**
|
||
|
||
### 属性 3: 位置更新同步
|
||
*对于任意*角色的移动操作,执行移动后角色的位置坐标应该被更新,并且该更新应该同步到所有连接的客户端
|
||
**验证需求: 2.2**
|
||
|
||
### 属性 4: 碰撞检测
|
||
*对于任意*角色和障碍物,当角色尝试移动到障碍物位置时,系统应该阻止该移动,角色位置保持不变
|
||
**验证需求: 2.4**
|
||
|
||
### 属性 5: 并发移动独立性
|
||
*对于任意*多个同时移动的角色,每个角色的移动应该独立处理,一个角色的移动不应影响其他角色的移动逻辑
|
||
**验证需求: 2.5**
|
||
|
||
### 属性 6: 对话触发
|
||
*对于任意*两个角色,当一个角色接近另一个角色并触发交互时,系统应该显示对话界面
|
||
**验证需求: 3.1**
|
||
|
||
### 属性 7: 消息传递完整性
|
||
*对于任意*对话消息,当玩家发送消息时,该消息应该被传递给接收方,并在发送方和接收方的界面上都正确显示
|
||
**验证需求: 3.3**
|
||
|
||
### 属性 8: 对话状态恢复
|
||
*对于任意*进行中的对话,当对话结束时,系统应该关闭对话界面并将游戏状态恢复到对话前的正常状态
|
||
**验证需求: 3.4**
|
||
|
||
### 属性 9: 对话可见性
|
||
*对于任意*两个角色之间的对话,附近的其他角色应该能够看到对话气泡显示在对话角色上方
|
||
**验证需求: 3.5**
|
||
|
||
### 属性 10: 场景碰撞检测
|
||
*对于任意*玩家角色和场景元素(如桌椅、墙壁),当玩家尝试移动到场景元素位置时,系统应该正确处理碰撞并阻止穿透
|
||
**验证需求: 4.5**
|
||
|
||
### 属性 11: 键盘输入响应
|
||
*对于任意*有效的键盘移动输入(方向键或 WASD),系统应该将玩家角色移动到相应方向,并将移动数据同步到服务器
|
||
**验证需求: 5.1**
|
||
|
||
### 属性 12: 触摸输入响应
|
||
*对于任意*有效的触摸移动输入(虚拟摇杆),系统应该将玩家角色移动到指定方向,并将移动数据同步到服务器
|
||
**验证需求: 5.2**
|
||
|
||
### 属性 13: 移动动画同步
|
||
*对于任意*角色的移动操作,系统应该播放相应的移动动画,并在所有客户端同步显示该动画
|
||
**验证需求: 5.5**
|
||
|
||
### 属性 14: 响应式布局适配
|
||
*对于任意*不同分辨率的浏览器窗口,游戏画面应该自动调整尺寸以适应窗口大小,保持可玩性
|
||
**验证需求: 6.3, 7.2**
|
||
|
||
### 属性 15: 窗口动态调整
|
||
*对于任意*浏览器窗口大小的改变,游戏系统应该动态调整游戏画面比例,保持界面元素的可访问性
|
||
**验证需求: 6.4**
|
||
|
||
### 属性 16: 数据序列化往返
|
||
*对于任意*游戏数据对象,序列化为 JSON 后再反序列化应该得到等价的对象(往返一致性)
|
||
**验证需求: 7.3, 9.5**
|
||
|
||
### 属性 17: 设备类型检测
|
||
*对于任意*设备类型(桌面或移动),系统应该正确检测设备类型并应用相应的控制方案(键盘或触摸)
|
||
**验证需求: 7.5**
|
||
|
||
### 属性 18: 角色数据持久化
|
||
*对于任意*创建的角色,角色数据应该被保存到服务器,后续登录时应该能够恢复相同的角色数据
|
||
**验证需求: 9.1, 9.2**
|
||
|
||
### 属性 19: 状态同步
|
||
*对于任意*角色位置或状态的改变,系统应该将更新同步到服务器,确保数据一致性
|
||
**验证需求: 9.4**
|
||
|
||
### 属性 20: 移动设备 UI 适配
|
||
*对于任意*在移动设备上运行的游戏,UI 元素大小应该调整以适应触摸操作(按钮足够大,间距合理)
|
||
**验证需求: 10.4**
|
||
|
||
### 属性 21: 错误提示显示
|
||
*对于任意*操作失败的情况,系统应该显示明确的错误提示信息,告知用户失败原因
|
||
**验证需求: 10.5**
|
||
|
||
### 属性 22: 在线角色显示
|
||
*对于任意*玩家进入游戏场景时,系统应该显示所有当前在线玩家的角色
|
||
**验证需求: 11.1**
|
||
|
||
### 属性 23: 离线角色显示
|
||
*对于任意*玩家进入游戏场景时,系统应该显示所有离线玩家的角色作为 NPC
|
||
**验证需求: 11.2**
|
||
|
||
### 属性 24: 上线状态切换
|
||
*对于任意*玩家上线事件,系统应该在场景中显示该玩家的角色,并将其标记为在线状态
|
||
**验证需求: 11.3**
|
||
|
||
### 属性 25: 下线状态切换
|
||
*对于任意*玩家下线事件,系统应该将该玩家的角色转换为离线 NPC 状态,但角色继续存在于场景中
|
||
**验证需求: 11.4**
|
||
|
||
### 属性 26: 角色状态视觉区分
|
||
*对于任意*显示的角色,系统应该通过视觉标识(如颜色、图标)区分在线玩家和离线角色
|
||
**验证需求: 11.5**
|
||
|
||
### 属性 27: 网络连接建立
|
||
*对于任意*玩家登录操作,系统应该尝试建立与服务器的网络连接
|
||
**验证需求: 12.1**
|
||
|
||
### 属性 28: 断线重连
|
||
*对于任意*网络连接中断事件,系统应该显示断线提示并自动尝试重新连接到服务器
|
||
**验证需求: 12.3**
|
||
|
||
### 属性 29: 操作确认
|
||
*对于任意*玩家执行的操作,系统应该将操作数据发送到服务器并等待接收确认响应
|
||
**验证需求: 12.4**
|
||
|
||
### 属性 30: 服务器更新同步
|
||
*对于任意*服务器推送的更新消息,客户端应该实时更新本地游戏状态以反映服务器的变化
|
||
**验证需求: 12.5**
|
||
|
||
## 错误处理
|
||
|
||
### 网络错误处理
|
||
|
||
**连接失败**:
|
||
- 显示友好的错误提示
|
||
- 提供重试按钮
|
||
- 记录错误日志用于调试
|
||
|
||
**连接中断**:
|
||
- 自动尝试重连(最多 3 次)
|
||
- 显示断线状态指示器
|
||
- 缓存未发送的操作,重连后重新发送
|
||
|
||
**消息发送失败**:
|
||
- 重试机制(指数退避)
|
||
- 超时后通知用户
|
||
- 保持本地状态一致性
|
||
|
||
### 数据验证错误
|
||
|
||
**角色创建验证**:
|
||
- 名称长度限制(2-20 字符)
|
||
- 禁止特殊字符和空白字符
|
||
- 检查名称唯一性
|
||
|
||
**输入验证**:
|
||
- 对话消息长度限制(1-500 字符)
|
||
- 过滤恶意输入
|
||
- 防止注入攻击
|
||
|
||
### 状态不一致处理
|
||
|
||
**客户端-服务器状态不一致**:
|
||
- 定期同步状态(每 5 秒)
|
||
- 服务器状态为权威状态
|
||
- 客户端预测 + 服务器校正
|
||
|
||
**角色位置冲突**:
|
||
- 服务器检测位置冲突
|
||
- 强制回退到有效位置
|
||
- 通知客户端更新
|
||
|
||
## 测试策略
|
||
|
||
### 单元测试
|
||
|
||
使用 Godot 的 GUT (Godot Unit Test) 框架进行单元测试。
|
||
|
||
**测试覆盖范围**:
|
||
- 数据模型的序列化/反序列化
|
||
- 输入处理逻辑
|
||
- 状态管理器的状态转换
|
||
- 消息协议的编码/解码
|
||
|
||
**示例测试**:
|
||
```gdscript
|
||
# test_character_data.gd
|
||
extends GutTest
|
||
|
||
func test_character_serialization():
|
||
var character = {
|
||
"id": "test_123",
|
||
"name": "测试角色",
|
||
"position": {"x": 100.0, "y": 200.0}
|
||
}
|
||
var json_str = JSON.stringify(character)
|
||
var parsed = JSON.parse_string(json_str)
|
||
assert_eq(parsed["id"], character["id"])
|
||
assert_eq(parsed["name"], character["name"])
|
||
```
|
||
|
||
### 属性基础测试
|
||
|
||
使用 GDScript 实现简单的属性测试框架,或使用社区提供的属性测试库。
|
||
|
||
**测试库**: 自定义实现或使用 Godot 社区的属性测试工具
|
||
|
||
**测试配置**: 每个属性测试至少运行 100 次迭代
|
||
|
||
**测试标注格式**: `# Feature: godot-ai-town-game, Property X: [属性描述]`
|
||
|
||
**属性测试覆盖**:
|
||
|
||
1. **属性 1: 角色创建唯一性**
|
||
- 生成多个随机角色
|
||
- 验证所有角色 ID 唯一
|
||
|
||
2. **属性 2: 角色移动能力**
|
||
- 生成随机角色
|
||
- 验证角色可以响应移动指令
|
||
|
||
3. **属性 3: 位置更新同步**
|
||
- 生成随机移动操作
|
||
- 验证位置正确更新
|
||
|
||
4. **属性 4: 碰撞检测**
|
||
- 生成随机障碍物和移动路径
|
||
- 验证碰撞正确阻止移动
|
||
|
||
5. **属性 16: 数据序列化往返**
|
||
- 生成随机游戏数据对象
|
||
- 验证序列化后反序列化得到等价对象
|
||
|
||
6. **属性 18: 角色数据持久化**
|
||
- 生成随机角色数据
|
||
- 验证保存后加载得到相同数据
|
||
|
||
**示例属性测试**:
|
||
```gdscript
|
||
# test_properties.gd
|
||
extends GutTest
|
||
|
||
# Feature: godot-ai-town-game, Property 16: 数据序列化往返
|
||
func test_property_serialization_roundtrip():
|
||
for i in range(100):
|
||
var random_data = generate_random_character_data()
|
||
var serialized = JSON.stringify(random_data)
|
||
var deserialized = JSON.parse_string(serialized)
|
||
assert_eq_deep(deserialized, random_data,
|
||
"序列化往返应该保持数据一致性")
|
||
|
||
func generate_random_character_data() -> Dictionary:
|
||
return {
|
||
"id": "char_" + str(randi()),
|
||
"name": "角色" + str(randi() % 1000),
|
||
"position": {
|
||
"x": randf_range(0, 1000),
|
||
"y": randf_range(0, 1000)
|
||
},
|
||
"is_online": randi() % 2 == 0
|
||
}
|
||
```
|
||
|
||
### 集成测试
|
||
|
||
**场景加载测试**:
|
||
- 测试 Datawhale 办公室场景正确加载
|
||
- 验证所有必需的节点存在
|
||
- 检查碰撞层设置正确
|
||
|
||
**网络集成测试**:
|
||
- 启动测试服务器
|
||
- 测试客户端连接流程
|
||
- 验证消息收发正确
|
||
|
||
**多客户端测试**:
|
||
- 模拟多个客户端连接
|
||
- 测试状态同步
|
||
- 验证角色互动
|
||
|
||
### 性能测试
|
||
|
||
**帧率测试**:
|
||
- 测试不同数量角色时的帧率
|
||
- 目标: 30+ FPS (10 个角色)
|
||
|
||
**网络延迟测试**:
|
||
- 测试不同网络条件下的响应时间
|
||
- 目标: 操作响应 < 200ms
|
||
|
||
**内存使用测试**:
|
||
- 监控长时间运行的内存使用
|
||
- 检测内存泄漏
|
||
|
||
### 跨平台测试
|
||
|
||
**浏览器兼容性**:
|
||
- Chrome (最新版本)
|
||
- Firefox (最新版本)
|
||
- Safari (最新版本)
|
||
- Edge (最新版本)
|
||
|
||
**设备测试**:
|
||
- 桌面 (1920x1080, 1366x768)
|
||
- 平板 (iPad, Android 平板)
|
||
- 手机 (iOS, Android)
|
||
|
||
**输入测试**:
|
||
- 键盘输入
|
||
- 鼠标输入
|
||
- 触摸输入
|
||
- 虚拟摇杆
|
||
|
||
## 场景设计
|
||
|
||
### Datawhale 办公室场景
|
||
|
||
**场景尺寸**: 2000x1500 像素
|
||
|
||
**主要区域**:
|
||
1. **入口区域**: 门、欢迎标识
|
||
2. **工作区**: 办公桌、电脑、椅子
|
||
3. **会议区**: 会议桌、白板
|
||
4. **休息区**: 沙发、茶水间
|
||
5. **展示区**: Datawhale logo、成就墙
|
||
|
||
**碰撞层设置**:
|
||
- Layer 1: 墙壁和固定障碍物
|
||
- Layer 2: 家具(可选择性碰撞)
|
||
- Layer 3: 角色
|
||
- Layer 4: 交互区域
|
||
|
||
**视觉风格**:
|
||
- 2D 俯视角(45度等距视角可选)
|
||
- 简洁的像素艺术或矢量风格
|
||
- Datawhale 品牌色: 蓝色系为主
|
||
|
||
### 资源需求
|
||
|
||
**图像资源**:
|
||
- 角色精灵图(4 方向行走动画)
|
||
- 场景瓦片集(地板、墙壁、家具)
|
||
- UI 元素(按钮、对话框、图标)
|
||
- Datawhale logo 和品牌元素
|
||
|
||
**音频资源** (可选):
|
||
- 背景音乐
|
||
- 脚步声
|
||
- UI 交互音效
|
||
- 对话提示音
|
||
|
||
## 部署和构建
|
||
|
||
### Web 导出配置
|
||
|
||
**Godot 导出设置**:
|
||
- 目标平台: HTML5
|
||
- 导出模板: Godot 4.x Web
|
||
- 线程支持: 启用(如果浏览器支持)
|
||
- VRAM 压缩: 启用
|
||
|
||
**Web 服务器要求**:
|
||
- 支持 WebSocket
|
||
- HTTPS (用于生产环境)
|
||
- CORS 配置正确
|
||
|
||
### 服务器部署
|
||
|
||
**推荐部署方案**:
|
||
- 静态文件: Nginx/Apache 或 CDN
|
||
- WebSocket 服务器: Node.js 或 Python
|
||
- 数据存储: JSON 文件或轻量级数据库
|
||
|
||
**环境变量**:
|
||
- `SERVER_URL`: WebSocket 服务器地址
|
||
- `PORT`: 服务器端口
|
||
- `DATA_DIR`: 数据存储目录
|
||
|
||
### 移动端预留
|
||
|
||
**响应式设计**:
|
||
- 使用 Godot 的 Viewport 缩放
|
||
- UI 元素使用相对定位
|
||
- 字体大小动态调整
|
||
|
||
**输入抽象**:
|
||
- 统一的输入接口
|
||
- 自动检测输入设备
|
||
- 虚拟控制器自动显示/隐藏
|
||
|
||
**跨端数据同步**:
|
||
- 统一的数据格式
|
||
- 服务器端状态管理
|
||
- 客户端无状态设计
|
||
|
||
## 扩展性考虑
|
||
|
||
### 未来功能预留
|
||
|
||
**AI 对话系统**:
|
||
- 预留 AI 接口(如 OpenAI API)
|
||
- 对话历史记录
|
||
- 角色个性设置
|
||
|
||
**更多场景**:
|
||
- 场景管理器支持多场景
|
||
- 场景切换机制
|
||
- 场景间传送
|
||
|
||
**社交功能**:
|
||
- 好友系统
|
||
- 私聊功能
|
||
- 角色关系网络
|
||
|
||
### 性能优化预留
|
||
|
||
**对象池**:
|
||
- 角色对象复用
|
||
- UI 元素复用
|
||
- 减少内存分配
|
||
|
||
**网络优化**:
|
||
- 消息批处理
|
||
- 状态差异同步
|
||
- 区域兴趣管理(AOI)
|
||
|
||
**渲染优化**:
|
||
- 视锥剔除
|
||
- LOD (细节层次)
|
||
- 纹理压缩
|