🏗️ Capti Game - 系统架构文档
System Architecture Overview
🏛️ 架构设计原则
- 内存优先:启动时一次性加载所有数据至内存,运行时避免SQL查询
- 模块化管理:单一职责原则,每个Manager专注特定领域
- 依赖注入:松耦合设计,便于测试和维护
- 事件驱动:信号系统实现模块间通信
- 单一数据源:避免数据不一致问题
🗂️ 核心架构图
┌──────────────────────────────────────────────────────────┐
│ GlobalData │
│ (协调器 - 550行) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Manager 依赖注入系统 │ │
│ └─────────────────────────────────────────────────────┘ │
└──┬───────────────────────────────────────────────────────┘
│
├── 📊 MemoryDataManager (486行)
│ ├── traders_data: Dictionary<String, MemoryTraderData>
│ ├── mercenaries_data: Dictionary<String, MemoryMercenaryData>
│ ├── commodities_data: Dictionary<int, MemoryCommodityData>
│ ├── holdings_data: Dictionary<String, MemoryHoldingData>
│ ├── equipment_instances: Dictionary<int, MemoryEquipmentInstanceData>
│ └── equipment_types: Dictionary<int, MemoryEquipmentTypeData>
│
├── 👥 TraderManager (626行)
│ ├── current_player_data: Dictionary
│ └── 信号: trader_data_updated, trader_level_up
│
├── ⚔️ MercenaryManager (748行)
│ └── 信号: mercenaries_updated
│
├── 🛡️ EquipmentManager (506行)
│ └── 信号: equipment_updated
│
├── 💾 SaveGameManager (383行)
│ └── 信号: save_completed, load_completed
│
├── 🔄 TradeManager (221行)
│ └── 信号: trade_completed, trade_failed
│
└── 🎬 SceneManager (230行)
└── AutoLoad 场景管理
┌──────────────────────────────────────────────────────────┐
│ SQLite Database │
│ (仅用于启动加载和存档保存) │
└──────────────────────────────────────────────────────────┘
管理器职责分工
| Manager | 主要职责 | 核心功能 |
|---|---|---|
| GlobalData | 系统协调器 | 初始化管理、Manager依赖注入、信号路由 |
| MemoryDataManager | 内存数据中心 | 统一数据加载、内存存储、数据验证 |
| TraderManager | 交易员管理 | 玩家数据、交易员属性、经验等级系统 |
| MercenaryManager | 佣兵系统 | 佣兵招募、状态管理、战斗属性 |
| EquipmentManager | 装备系统 | 装备实例、类型管理、属性计算 |
| SaveGameManager | 存档系统 | 游戏保存/加载、多存档支持 |
| TradeManager | 交易核心 | 物品转移、金币管理、交易验证 |
| SceneManager | 场景管理 | 场景切换、状态保持 |
🗂️ 数据结构设计
内存数据类型 (Memory*Data)
所有数据类型继承自Godot的Resource类,支持序列化和类型安全:
核心交易数据
# 交易员数据
class MemoryTraderData extends Resource:
@export var trader_code: String # 交易员编码 (如 TRADER_001)
@export var display_name: String # 显示名称
@export var trade_level: int # 交易等级
@export var trade_experience: int # 交易经验
@export var gold_balance: float # ⚠️ 已废弃 - 金币现为可转移物品
# 持有物品数据
class MemoryHoldingData extends Resource:
@export var holder_type: String # 持有者类型 (trader/mercenary)
@export var holder_id: int # 持有者ID
@export var commodity_id: int # 商品ID (1=金币)
@export var quantity: float # 数量
@export var location: String # 位置标识
# 商品数据
class MemoryCommodityData extends Resource:
@export var commodity_id: int # 商品ID
@export var commodity_name: String # 商品名称
@export var unit_price: float # 单价
@export var category: String # 分类
战斗相关数据
# 佣兵数据
class MemoryMercenaryData extends Resource:
@export var mercenary_id: int # 佣兵ID
@export var mercenary_name: String # 佣兵名称
@export var mercenary_level: int # 等级
@export var attack_power: int # 攻击力
@export var defense_power: int # 防御力
@export var hire_cost: float # 雇佣费用
@export var current_owner_id: int # 当前雇主ID
# 装备实例数据
class MemoryEquipmentInstanceData extends Resource:
@export var instance_id: int # 实例ID
@export var type_id: int # 装备类型ID
@export var current_owner_id: int # 当前拥有者ID
@export var durability: float # 耐久度 (0.0-1.0)
@export var enhancement_level: int # 强化等级
数据存储策略
# MemoryDataManager 中的数据组织
var traders_data: Dictionary = {} # String -> MemoryTraderData
var mercenaries_data: Dictionary = {} # int -> MemoryMercenaryData
var commodities_data: Dictionary = {} # int -> MemoryCommodityData
var holdings_data: Dictionary = {} # String -> MemoryHoldingData[]
var equipment_instances: Dictionary = {} # int -> MemoryEquipmentInstanceData
var equipment_types: Dictionary = {} # int -> MemoryEquipmentTypeData
# 索引键设计
# holdings_data key format: "{holder_type}_{holder_id}_{commodity_id}"
# 示例: "trader_1_1" = 交易员1的金币持有量
🔄 数据流转
启动数据加载流程
GlobalData.initialize_database()
↓
MemoryDataManager.initialize_memory_data_system()
↓
SQLite DB → 批量加载所有表数据 → 转换为Memory*Data对象
↓
TraderManager / MercenaryManager / EquipmentManager 初始化
↓
系统初始化完成,运行时无需SQL查询
交易数据流转
用户发起交易 → TradeManager.transfer_item
↓
验证交易合法性
├─ 失败 → 返回错误信息
└─ 成功 → 更新MemoryDataManager
↓
同步到SQLite
↓
发出trade_completed信号
├─ 更新UI显示
└─ 触发其他Manager刷新
实时查询模式
用户界面查询 → Manager API → MemoryDataManager → 内存Dictionary → O(1)查找性能
⚡ 性能优化策略
当前性能优势
- 内存优先架构:消除运行时SQL查询,实现O(1)数据访问
- 批量数据加载:启动时一次性加载,避免频繁I/O
- 智能索引设计:预构建查询索引,优化常用数据访问路径
- 事件驱动更新:仅在数据变更时触发必要的UI更新
🎯 高性能数据计算优化方向
1. 计算密集型优化
# 当前问题:频繁的装备属性计算
# 优化方案:属性计算结果缓存
class EquipmentManager:
var _attribute_cache: Dictionary = {} # instance_id -> 计算结果
func get_equipment_total_stats(instance_id: int) -> Dictionary:
if _attribute_cache.has(instance_id):
return _attribute_cache[instance_id] # 缓存命中
var stats = _calculate_equipment_stats(instance_id) # 重新计算
_attribute_cache[instance_id] = stats
return stats
2. 批量操作优化
# 当前问题:逐个处理大量佣兵数据
# 优化方案:向量化批量处理
func batch_update_mercenary_stats(mercenary_ids: Array) -> void:
var batch_updates: Array = []
for id in mercenary_ids:
var stats = calculate_mercenary_stats(id)
batch_updates.append({id: id, stats: stats})
# 批量提交更新,减少信号发送次数
_apply_batch_updates(batch_updates)
mercenaries_updated.emit() # 一次性通知UI更新
3. 内存池管理
# 目标:减少GC压力,提升大批量计算性能
class ObjectPool:
var _pool: Array = []
func get_temp_object() -> Dictionary:
if _pool.is_empty():
return {}
return _pool.pop_back()
func return_temp_object(obj: Dictionary) -> void:
obj.clear()
_pool.append(obj)
4. 异步计算管道
# 用于处理复杂的市场价格计算、AI决策等
func calculate_market_trends_async() -> void:
var worker = Thread.new()
worker.start(_background_market_calculation)
func _background_market_calculation() -> void:
# 在后台线程进行重计算
var results = heavy_market_analysis()
call_deferred("_apply_market_results", results)
📊 性能监控指标
| 指标 | 目标值 |
|---|---|
| 启动加载时间 | < 2秒 |
| 内存占用 | < 100MB |
| 查询响应时间 | < 1ms (内存查询) |
| 批量计算吞吐量 | > 10000 operations/sec |
📋 TODO 任务清单
✅ 已完成任务 (25项)
架构重构核心
- ✅ 分析项目当前结构和架构问题
- ✅ GlobalData 模块化分解 (1300行 → 550行)
- ✅ 创建6个专业Manager (3200+行代码分离)
- ✅ 建立依赖注入系统
- ✅ 修复所有初始化顺序问题
数据一致性
- ✅ 消除gold_balance双重存储问题
- ✅ 统一物品管理系统 (金币 = 可转移物品)
- ✅ 建立内存优先数据访问模式
代码质量
- ✅ 移除重复代码和遗留函数
- ✅ 修复所有编译错误和警告
- ✅ 创建完整的文档系统
⏳ 待完成任务 (8项)
🥇 高优先级 (性能关键)
- organize_data_structures - 数据结构标准化
- 统一Memory*Data类的命名规范
- 优化数据类型定义,减少内存占用
- 建立数据验证和类型检查机制
- 性能影响: 🔥 高 - 影响所有数据操作
- refactor_memory_manager - 内存管理器优化
- 实现智能缓存策略
- 添加内存池管理
- 优化批量数据加载算法
- 性能影响: 🔥 高 - 直接影响启动速度和运行效率
- validate_architecture - 架构验证与基准测试
- 建立性能基准测试套件
- 验证数据一致性和完整性
- 负载测试和压力测试
- 性能影响: 📊 监控 - 确保性能目标达成
🥈 中优先级 (质量提升)
- optimize_trade_manager - 交易系统优化
- improve_error_handling - 错误处理统一化
- add_documentation - 文档完善
🥉 低优先级 (维护性)
- extract_constants - 配置外部化
- create_utility_classes - 工具类创建
🚀 性能优化专项任务
- ⏳ 内存池实现 - 减少GC压力,提升批量计算性能
- ⏳ 异步计算管道 - 后台处理复杂计算任务
- ⏳ 缓存策略优化 - 智能缓存热点数据
- ⏳ 批量操作接口 - 减少单次操作开销
- ⏳ 性能监控仪表板 - 实时性能指标展示
🛠️ 开发指南
性能最佳实践
- 避免在循环中进行数据库操作
- 使用批量API而非单个操作
- 合理使用缓存,避免重复计算
- 异步处理耗时操作
- 监控内存使用,及时释放无用对象
代码规范
- Manager类使用依赖注入模式
- 所有数据访问通过MemoryDataManager
- 使用信号进行模块间通信
- 保持单一职责原则
测试策略
- 单元测试覆盖所有Manager核心功能
- 集成测试验证Manager间交互
- 性能测试确保响应时间目标
- 压力测试验证系统稳定性
📈 项目统计
代码规模
- GlobalData:550行 (原1300行,精简57.7%)
- 总Manager代码:3200+行
- 架构文件:6个核心Manager + 1个协调器
性能指标
- 查询性能:O(n) → O(1) (Hash表查找)
- 启动优化:批量加载策略
- 内存效率:单一数据源设计
- 响应速度:内存优先架构
开发效率
- 模块化:单一职责,易于维护
- 可测试:依赖注入,便于单元测试
- 可扩展:信号驱动,松耦合设计
- 可调试:完整的日志和监控系统
📝 文档版本: v1.1 | 最后更新: 2026-02-04