Capti - 2D 经济模拟交易游戏
内部技术手册 v0.6 | 基于 Godot 4.5 引擎
系统架构概览
核心设计原则
| 原则 | 描述 |
|---|---|
| 内存优先 | 启动时一次性加载所有数据至内存,运行时避免SQL查询 |
| 模块化管理 | 单一职责原则,每个Manager专注特定领域 |
| 依赖注入 | 松耦合设计,Manager之间通过GlobalData协调 |
| 事件驱动 | 使用Godot信号系统实现模块间通信 |
| 单一数据源 | MemoryDataManager作为唯一内存数据中心 |
架构层次
┌─────────────────────────────────────────────────────────────────────┐
│ UI Layer (scenes/ui/) │
│ StartMenu │ MainMenu │ EconomyMenu │ TradingChart │ DevConsole │
└───────────────────────────────┬─────────────────────────────────────┘
│ (信号/API调用)
┌───────────────────────────────▼─────────────────────────────────────┐
│ GlobalData (协调器/AutoLoad) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Manager 依赖注入系统 │ │
│ │ setup_dependencies() → 初始化顺序控制 → 信号连接 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└───────┬─────────┬─────────┬─────────┬─────────┬─────────┬──────────┘
│ │ │ │ │ │
┌────▼────┐┌───▼───┐┌────▼────┐┌───▼───┐┌───▼───┐┌────▼────┐
│Memory ││Market ││GameTime ││Trader ││Trade ││World │
│DataMgr ││Manager││Manager ││Manager││Manager││EventMgr│
└────┬────┘└───────┘└─────────┘└───────┘└───┬───┘└────────┘
│ │
└──────────────────┬───────────────────┘
│
┌──────────────────────────▼──────────────────────────────────────────┐
│ SQLite Database Layer │
│ (仅用于启动加载和存档保存) │
│ sqlite_database/game_trade.db │
└─────────────────────────────────────────────────────────────────────┘
Manager 架构详解
1. MemoryDataManager - 内存数据中心
路径: scripts/core/managers/memory_data_manager.gd
职责: 统一管理所有游戏数据的内存存储,提供O(1)数据访问接口
核心数据容器
# 玩家/交易员数据 (对应 traders 表)
var traders_data: Dictionary = {} # trader_code -> MemoryTraderData
# 佣兵数据 (对应 mercenaries + mercenary_mood 表)
var mercenaries_data: Dictionary = {} # mercenary_id -> MemoryMercenaryData
var mercenary_moods: Dictionary = {} # mercenary_id -> MemoryMercenaryMoodData
# 物品数据 (对应 bulk_commodities + bulk_commodity_holdings 表)
var commodities_data: Dictionary = {} # commodity_id -> MemoryCommodityData
var holdings_data: Dictionary = {} # "holder_type:holder_id:commodity_id" -> MemoryHoldingData
# 装备数据 (对应 equipment_types + equipment_instances 表)
var equipment_types: Dictionary = {} # type_id -> MemoryEquipmentTypeData
var equipment_instances: Dictionary = {} # instance_id -> MemoryEquipmentInstanceData
# 冒险数据 (对应 adventure_* 表)
var adventure_teams: Dictionary = {} # team_id -> MemoryAdventureTeamData
var adventure_projects: Dictionary = {} # project_id -> MemoryAdventureProjectData
var team_members: Dictionary = {} # team_member_id -> MemoryTeamMemberData
关键API
| 方法 | 功能 | 返回值 |
|---|---|---|
initialize_with_database(db) |
初始化并从SQLite加载数据 | bool |
get_trader_data(code) |
获取交易员数据 | MemoryTraderData |
get_holding_data(type, id, commodity_id) |
获取持有物数据 | MemoryHoldingData |
update_holding(...) |
更新持有物(增/删/改) | bool |
get_trader_portfolio_summary(id, market_mgr) |
获取投资组合P&L | Dictionary |
信号
signal data_initialized # 数据初始化完成
signal holdings_updated(holder_id, holder_type) # 持有物更新
signal trader_balance_updated(trader_code) # 交易员余额更新
2. GameTimeManager - 游戏时间管理器
路径: scripts/core/managers/game_time_manager.gd
职责: 统一的时间系统,管理游戏时间、市场时段和多层次Tick调度
时间刻度
enum TimeScale {
PAUSED = 0, # 暂停
REAL_TIME = 1, # 实时(1倍速)
FAST = 5, # 快速(5倍速)
VERY_FAST = 10, # 很快(10倍速)
TURBO = 30, # 极速(30倍速)
DEBUG = 100 # 调试(100倍速)
}
游戏时间结构
var game_time: Dictionary = {
"year": 1, # 游戏年份(持续累加)
"month": 1, # 月份/季节 (1-4: 春夏秋冬)
"day": 1, # 日期 (1-28)
"hour": 8, # 小时 (0-23)
"minute": 0, # 分钟 (0-59)
"second": 0, # 秒数 (0-59)
"season": "春", # 当前季节名称
"cycle_year": 1, # 甲子年份 (1-60)
"stem": "甲", # 天干
"branch": "子" # 地支
}
Tick定时系统
| Tick类型 | 周期 | 用途 |
|---|---|---|
ultra_fast_tick |
100ms | 市场数据更新 |
fast_tick |
1秒 | 交易执行检查、AI交易员 |
normal_tick |
5秒 | 一般游戏逻辑 |
slow_tick |
30秒 | 长期事件处理 |
very_slow_tick |
5分钟 | 日常重置 |
3. MarketManager - 市场管理器
路径: scripts/core/managers/market_manager.gd
职责: 商品数据管理、价格波动模拟、市场需求追踪
核心状态
# 价格序列数据
var _commodity_series: Dictionary = {} # commodity_id -> Array[{timestamp, price, volume}]
var _commodity_current_price: Dictionary = {} # commodity_id -> float
var _commodity_base_price: Dictionary = {} # commodity_id -> float
var _commodity_open_price: Dictionary = {} # commodity_id -> float (每日开盘价)
var _commodity_trend: Dictionary = {} # commodity_id -> float (-1.0 ~ 1.0)
# 市场需求追踪
var _market_demand: Dictionary = {} # commodity_id -> {buy_volume, sell_volume, net_demand}
var _trade_volume_24h: Dictionary = {} # commodity_id -> Array[{quantity, timestamp}]
价格生成算法
func _generate_next_point(commodity_id):
# 1. 基于稀有度和类别计算波动率
var volatility = _get_volatility(commodity) # common=1.5, rare=3.0, epic=4.5
# 2. 随机波动 + 趋势影响
var random_change = randf_range(-volatility, volatility)
var trend_change = _commodity_trend[id] * trend_strength
# 3. 应用市场需求影响
var demand_impact = _calculate_demand_price_impact(id, current_price)
# 4. 价格限制(每日最大80%偏离开盘价)
current_price = clamp(current_price, open_price * 0.2, open_price * 1.8)
市场需求API
| 方法 | 功能 |
|---|---|
add_buy_demand(commodity_id, quantity) |
添加买入需求(事件系统调用) |
add_sell_demand(commodity_id, quantity) |
添加卖出需求 |
record_market_trade(commodity_id, quantity, is_buy) |
记录实际交易(由TradeManager调用) |
get_market_demand(commodity_id) |
获取需求信息 |
get_24h_volume(commodity_id) |
获取24小时交易量 |
市场参数配置
var _demand_decay_rate: float = 0.95 # 需求衰减率(每tick衰减5%)
var _price_sensitivity: float = 0.0015 # 价格对需求的敏感度
var _max_price_change_per_tick: float = 0.05 # 单次最大价格变化(5%)
var _demand_smoothing: float = 0.3 # 需求平滑系数
4. TradeManager - 交易管理器
路径: scripts/trade/trade_manager.gd
职责: 执行物品所有权转移、交易验证、市场数据联动
交易结果状态码
enum TradeResult {
SUCCESS = 0,
INSUFFICIENT_QUANTITY, # 数量不足
ITEM_NOT_FOUND, # 物品不存在
ITEM_LOCKED, # 物品被锁定
ITEM_NOT_TRADEABLE, # 物品不可交易
INVALID_HOLDER, # 无效持有者
INVALID_QUANTITY, # 无效数量
DATABASE_ERROR,
TRANSACTION_FAILED
}
核心API: execute_transfer
func execute_transfer(
commodity_id: int, # 物品ID
from_holder_id: int, # 源持有者ID
from_holder_type: String, # "trader" 或 "mercenary"
to_holder_id: int, # 目标持有者ID
to_holder_type: String,
quantity: float,
to_location_info: String = "personal_bag"
) -> Dictionary:
# 返回: {success: bool, error?: String, from, to, commodity, quantity}
市场实体交易
const MARKET_ENTITY_ID = 22
# 检测市场交易并通知MarketManager
if from_holder_id == MARKET_ENTITY_ID or to_holder_id == MARKET_ENTITY_ID:
var is_buy = (from_holder_id == MARKET_ENTITY_ID)
market_manager.record_market_trade(commodity_id, quantity, is_buy)
5. TraderManager - 交易员管理器
路径: scripts/core/managers/trader_manager.gd
职责: 管理所有交易员数据(包括玩家TRADER_001),处理等级、经验、统计等
玩家不是特殊存在:统一使用trader概念,TRADER_001是当前玩家的代码
当前玩家缓存结构
var current_player_data = {
# 游戏内属性(不保存到数据库)
"position": Vector2.ZERO,
"equipment": {},
"inventory": [],
# 数据库字段
"trader_code": "TRADER_001",
"display_name": "玩家",
"trade_level": 0,
"trade_experience": 0,
"trade_reputation": 50,
"total_trades": 0,
"successful_trades": 0,
"total_asset_value": 5000.0,
"total_profit": 0.0,
"best_trade_profit": 0.0,
"biggest_loss": 0.0,
# AI专用字段(玩家为null)
"is_ai": 0,
"risk_tolerance": null,
"specialization": null,
"investment_strategy": null,
...
}
6. AITraderManager - AI交易员管理器
路径: scripts/core/managers/ai_trader_manager.gd
职责: 管理AI交易员的自动交易决策和执行
交易策略
func evaluate_best_action_for_trader(trader: MemoryTraderData) -> Dictionary:
# 1. 遍历可交易商品
for commodity in tradeable_commodities:
# 2. 检查专业化匹配
if trader.specialization and commodity.category != trader.specialization:
continue
# 3. 技术分析:SMA交叉策略
var short_sma = _calculate_sma(price_series, 5)
var long_sma = _calculate_sma(price_series, 20)
var score = (short_sma - long_sma) / long_sma
# 4. 生成交易信号
if score > 0.02: # 买入信号
action = "buy"
elif score < -0.02: # 卖出信号
action = "sell"
风险管理
# 买入时:根据风险容忍度决定投资比例
var investment_amount = trader.gold_balance * (trader.risk_tolerance / 10.0) * 0.2
# 卖出时:根据风险容忍度决定卖出比例
var quantity_to_sell = holding.quantity * (1.0 - (trader.risk_tolerance / 10.0)) * 0.5
7. WorldEventManager - 世界事件管理器
路径: scripts/core/managers/world_event_manager.gd
职责: 宏观调控与动态事件引擎,连接各Manager实现全局事件
事件类型(WorldEventsLibrary)
| 事件类型 | 触发条件 | 效果 |
|---|---|---|
| 需求热潮 | 价格高位 + 单日涨幅>20% | 调用 market_manager.add_buy_demand() |
| 恐慌抛售 | 价格低位 + 单日跌幅>20% | 调用 market_manager.add_sell_demand() |
| 市场垄断 | 玩家持有占比>70% | 发布反垄断警告新闻 |
| 破产保护 | 金币<50G< /td> | 一次性发放1000G援助金 |
平衡机制
# 全局每日事件限制
const MAX_DAILY_EVENTS = 3
var _daily_trigger_count: int = 0
# 事件冷却系统
var _event_state: Dictionary = {} # event_id -> {last_triggered, cooldown_days}
数据流与生命周期
启动流程
1. GlobalData._ready()
│
├─ 2. initialize_database() → SQLite连接
│
├─ 3. initialize_memory_data_system()
│ └─ MemoryDataManager.initialize_with_database()
│ ├─ load_traders_data()
│ ├─ load_commodities_data()
│ ├─ load_holdings_data()
│ └─ ... (按依赖顺序加载)
│
├─ 4. initialize_*_manager() (依次初始化各Manager)
│ └─ setup_dependencies() → 注入依赖
│
└─ 5. 连接信号 → 系统就绪
交易数据流转
用户/AI发起交易
│
▼
TradeManager.execute_transfer()
│
├─ validate_transfer_conditions()
│
├─ MemoryDataManager.update_holding() (扣减源)
│
├─ MemoryDataManager.update_holding() (增加目标)
│
├─ 检测市场实体交易?
│ │
│ └─ MarketManager.record_market_trade()
│ │
│ └─ 影响 _market_demand → 价格变动
│
├─ trade_completed.emit()
│
└─ WorldEventManager监听 → 可能触发事件
数据结构定义
Memory*Data 类型
| 类型 | 文件 | 对应表 |
|---|---|---|
MemoryTraderData |
memory_traders.gd | traders |
MemoryCommodityData |
memory_commodities.gd | bulk_commodities |
MemoryHoldingData |
memory_holdings.gd | bulk_commodity_holdings |
MemoryMercenaryData |
memory_mercenaries.gd | mercenaries |
MemoryEquipmentInstanceData |
memory_equipment_instances.gd | equipment_instances |
Holdings键格式
"{holder_type}:{holder_id}:{commodity_id}"
示例:
- "trader:1:1" → 交易员1的金币
- "mercenary:3:5" → 佣兵3的治愈草
开发指南
添加新Manager
- 创建
scripts/core/managers/xxx_manager.gd - 定义
class_name XxxManager - 实现
setup_dependencies()方法 - 在
GlobalData._ready()中初始化 - 添加到架构图和文档
调试命令(DevConsole)
# 金币操作
trader_gold add 20000
trader_gold set 50000
# 物品操作
holding add <commodity_id> <quantity> id TRADER_001
# 市场操作
market_price set <commodity_id> <price>
next_day
# 事件触发
force_trigger <event_id>
性能目标
| 指标 | 目标值 |
|---|---|
| 启动加载时间 | < 2秒 |
| 内存查询响应 | < 1ms |
| 内存占用 | < 100MB |
项目结构
gdt/
├── scripts/
│ ├── core/
│ │ ├── global_data.gd # 全局协调器 (AutoLoad)
│ │ ├── managers/
│ │ │ ├── memory_data_manager.gd # 内存数据中心
│ │ │ ├── market_manager.gd # 市场管理
│ │ │ ├── game_time_manager.gd # 时间管理
│ │ │ ├── trader_manager.gd # 交易员管理
│ │ │ ├── ai_trader_manager.gd # AI交易员
│ │ │ ├── world_event_manager.gd # 世界事件
│ │ │ ├── mercenary_manager.gd # 佣兵系统
│ │ │ ├── equipment_manager.gd # 装备系统
│ │ │ ├── adventure_manager.gd # 冒险系统
│ │ │ ├── news_manager.gd # 新闻系统
│ │ │ └── save_game_manager.gd # 存档系统
│ │ ├── data_structures/ # Memory*Data类定义
│ │ ├── events/
│ │ │ └── world_events_library.gd # 世界事件库
│ │ └── sync/
│ │ └── dirty_tracker.gd # 脏数据追踪
│ ├── trade/
│ │ └── trade_manager.gd # 交易执行
│ └── ui/ # UI脚本
├── scenes/ # 场景文件
├── sqlite_database/ # 数据库文件和SQL脚本
├── docs/ # 开发文档
├── ARCHITECTURE.md # 架构详解
└── PROJECT_INDEX_AND_ROADMAP.md # 项目路线图
文档版本: v0.6 | 最后更新: 2025年12月