增加MD文件

This commit is contained in:
wuwenbo 2026-04-13 15:15:08 +08:00
parent cf81156d94
commit 821086f612
25 changed files with 4795 additions and 40 deletions

View File

@ -0,0 +1,240 @@
# 🎮 TH1 游戏架构总览
> **项目类型**: 回合制4X策略游戏Explore, Expand, Exploit, Exterminate
> **技术栈**: Unity (C#) + 阿里云函数计算 (Node.js) + Steam 多人联网
> **主题**: 东方Project 文明模拟
> **支持模式**: 单人 / Steam多人 / AI对战 / 观战 / 教程 / 故事模式
---
## 📐 系统架构图
```
┌─────────────────────────────────────────────────────────────────┐
│ TH1 游戏系统 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Input │ │ AI │ │ Net │ │ Steam │ │
│ │ 输入系统 │ │ AI系统 │ │ 网络层 │ │ 平台层 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Core 核心层 (Main + GameLogic) │ │
│ │ GameState状态机 · 回合管理 · 初始化 · 存档/读档 │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Action │ │ Logic │ │ Skill │ │
│ │ 行为系统 │ │ 逻辑模块 │ │ 技能系统 │ │
│ │ 6种行为 │ │City/Unit │ │ 296+技能 │ │
│ │ │ │Player │ │ 300+实现 │ │
│ └────┬────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Data 数据层 (MapData) │ │
│ │ GridData · CityData · UnitData · PlayerData · NetData │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────┬────────┼────────┬────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌───────┐┌───────┐┌───────┐┌───────┐┌────────┐ │
│ │ Event ││ UI ││Present││Render ││ Anim │ │
│ │事件总线││UI框架 ││演出队列││渲染器 ││动画系统 │ │
│ └───────┘└───────┘└───────┘└───────┘└────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 基础设施层 │ │
│ │ Audio · Config · Resource · Multilingual · OSS · Pool │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Server 服务端 (阿里云函数计算) │ │
│ │ Steam验证 → STS令牌签发 → OSS上传 → Tablestore缓存 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
---
## 📁 模块索引
| # | 模块 | 说明 | 详细文档 |
|---|------|------|---------|
| 1 | **核心层 (Core)** | Main入口 · GameLogic状态机 · 回合流程 | [01-核心层](./01-核心层-Core与GameLogic.md) |
| 2 | **数据层 (Data)** | MapData · 所有运行时数据结构 | [02-数据层](./02-数据层-Data数据结构.md) |
| 3 | **行为系统 (Action)** | 建造 · 训练 · 移动 · 攻击 · 外交 | [03-行为系统](./03-行为系统-Action.md) |
| 4 | **逻辑模块 (Logic)** | City/Unit/Player三大逻辑 | [04-逻辑模块](./04-逻辑模块-CityUnitPlayer.md) |
| 5 | **技能系统 (Skill)** | 296种技能类型 · 300+实现 | [05-技能系统](./05-技能系统-Skill.md) |
| 6 | **AI系统** | 行为树 · 评分 · 决策 · ML推理 | [06-AI系统](./06-AI系统.md) |
| 7 | **事件系统 (Event)** | EventManager · UIEvents | [07-事件系统](./07-事件系统-Event.md) |
| 8 | **UI框架** | ViewController · 5大UI管理器 | [08-UI框架](./08-UI框架.md) |
| 9 | **演出与动画** | PresentationManager · Fragment | [09-演出与动画](./09-演出与动画系统.md) |
| 10 | **渲染系统 (Renderer)** | Map/Grid/Unit/City渲染器 | [10-渲染系统](./10-渲染系统-Renderer.md) |
| 11 | **网络与Steam** | Lobby · P2P · 消息协议 | [11-网络与Steam](./11-网络与Steam.md) |
| 12 | **音频系统** | BGM轮播 · SFX · 环境音 | [12-音频系统](./12-音频系统.md) |
| 13 | **配置与数据资产** | Config · DataAssets · Excel | [13-配置与数据资产](./13-配置与数据资产.md) |
| 14 | **辅助系统** | 多语言 · 成就 · 漫画 · Wiki等 | [14-辅助系统](./14-辅助系统.md) |
| 15 | **服务端** | 阿里云函数 · STS · OSS上传 | [15-服务端](./15-服务端-GameUploadFunction.md) |
| 16 | **AI训练管线** | ONNX推理 · 训练数据录制 | [16-AI训练管线](./16-AI训练管线.md) |
---
## 🔑 核心设计模式
| 模式 | 应用位置 | 说明 |
|------|---------|------|
| **状态机** | GameLogic, AILogic, LobbyState | 游戏阶段/AI阶段/大厅状态管理 |
| **事件总线** | EventManager | 100+ struct事件类型的发布/订阅 |
| **工厂模式** | SkillFactory, FragmentFactory, ActionLogicFactory | 反射注册 + 字典缓存 |
| **单例** | Main, AudioManager, ConfigManager 等 | 全局管理器 |
| **MVC** | ViewController ↔ Data ↔ Renderer | UI控制器/数据/视图分离 |
| **队列序列器** | PresentationManager | 顺序执行UI/动画任务 |
| **行为树** | BTNodeCanvas (150+ 节点) | AI决策 |
| **对象池** | PrefabPoolManager | 特效/Prefab复用 |
| **策略模式** | AI评分计算器 | 不同评分策略组合 |
---
## 🕹️ 游戏核心循环
```
┌─────────────────────────────────────────┐
│ 主菜单 (Menu) │
│ 选择文明/设置/多人/读档/教程/故事 │
└──────────────┬──────────────────────────┘
│ StartMatch / NetStartGame
┌─────────────────────────────────────────┐
│ 地图生成 (MapGenerator) │
│ 生成地形 · 放置资源 · 创建玩家/城市/部队 │
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ 玩家回合 (PlayerRound) │
│ │
│ 输入 → 行为选择 → 执行Action │
│ 移动(Move) / 攻击(Attack) │
│ 建造(Build) / 训练(Train) │
│ 科技(Tech) / 外交(Diplomacy) │
│ 技能触发 → 动画演出 → UI更新 │
│ │
│ 结束回合 → TurnEnd │
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ AI回合 (OtherPlayerRound) │
│ │
│ 行为树决策 → 生成合法Action │
│ 评分计算 → 选择最优Action │
│ 执行 → 动画 → 下一个AI │
└──────────────┬──────────────────────────┘
▼ (循环直到胜利条件)
┌─────────────────────────────────────────┐
│ 结算 (Finished) │
│ 保存成就 · 录制数据 · 上传OSS · 显示结果 │
└─────────────────────────────────────────┘
```
---
## 🗂️ 目录结构
```
Scripts/
├── TH1_Core/ # 核心事件系统
│ ├── Events/ # UIEvents事件定义 + EventManagerBinder
│ └── Managers/ # EventManager · PresentationManager · UIManager
├── TH1_Logic/ # 游戏逻辑(最大模块)
│ ├── Core/ # Main.cs · GameLogic.cs 入口
│ ├── Action/ # 6种行为逻辑
│ ├── AI/ # AI逻辑 · 评分 · 生成器
│ ├── AITrain/ # ML推理 · 训练数据
│ ├── City/ # 城市逻辑
│ ├── Unit/ # 部队逻辑
│ ├── Player/ # 玩家逻辑
│ ├── Skill/ # 技能系统 (300+文件)
│ ├── Net/ # Lobby网络抽象
│ ├── Steam/ # Steam P2P/Lobby
│ ├── Config/ # 配置管理
│ ├── Map/ # 地图生成与交互
│ ├── Multilingual/ # 10种语言支持
│ ├── Achievement/ # 成就系统
│ ├── Comic/ # 漫画/剧情
│ ├── Oss/ # 阿里云OSS上传
│ └── ... # 更多子系统
├── TH1_Data/ # 运行时数据结构
│ ├── MapData.cs # 地图总数据 (88KB)
│ ├── GridData.cs # 格子数据
│ ├── CityData.cs # 城市数据
│ ├── UnitData.cs # 部队数据
│ ├── PlayerData.cs # 玩家数据
│ └── NetData.cs # 网络数据
├── TH1_UI/ # UI框架与控制器
├── TH1_Presentation/ # 演出队列任务
├── TH1_Renderer/ # 视觉渲染器
├── TH1_Anim/ # 动画/Fragment系统
├── TH1_Audio/ # 音频管理
├── TH1_Config/ # Excel配置生成
├── TH1_Resource/ # 资源缓存
├── TH1_DataAssetsScript/ # ScriptableObject数据资产
├── TH1_Instance/ # 全局单例
├── BTNodeCanvas/ # AI行为树节点 (150+文件)
├── Effect/ # 特效控制
├── Steamworks.NET/ # Steam SDK封装
└── ThirdParty/ # 第三方库
Tools/OSS/game-upload-function/ # 服务端(Node.js)
└── index.js # STS令牌服务
```
---
## 🎭 文明与势力
| 文明 (CivEnum) | 势力 (ForceEnum) | 说明 |
|----------------|-----------------|------|
| Egyptian | Remilia | 埃及文明 |
| French | Kaguya | 法国文明 |
| Germany | Kanako | 德国文明 |
| Indian | Satori | 印度文明 |
| Norway | Reimu | 挪威文明 |
| Britain | Byakuren | 英国文明 |
| Persian | Miko | 波斯文明 |
| Byzantine | Zanmu | 拜占庭文明 |
---
## 🔗 序列化方案
- **MemoryPack**: 用于网络同步、存档、训练数据序列化(高性能二进制)
- **JSON**: 用于配置文件GameConfig、成就数据、训练JSONL
- **ScriptableObject**: 用于编辑器可视化数据资产
- **Excel → C# 代码生成**: 用于配置表AI配置、地理描述、历史时刻
---
## 📊 代码规模统计
| 模块 | 文件数 | 估算代码行 |
|------|--------|-----------|
| TH1_Logic | 400+ | 50,000+ |
| TH1_UI | 80+ | 8,000+ |
| TH1_Data | 8 | 5,000+ |
| TH1_Anim | 33+ | 4,000+ |
| TH1_Renderer | 15+ | 6,000+ |
| BTNodeCanvas | 150+ | 5,000+ |
| TH1_DataAssetsScript | 24 | 3,000+ |
| 服务端 | 3 | 400+ |
| **总计** | **700+** | **80,000+** |

View File

@ -0,0 +1,238 @@
# 01 - 核心层Core 与 GameLogic
> **目录**: `TH1_Logic/Core/`
> **核心文件**: `Main.cs`(入口) · `GameLogic.cs`(状态机) · `MainEditor.cs`(调试)
---
## 1. Main.cs — 游戏入口与总调度器
`Main : MonoBehaviour` 是整个游戏的入口 MonoBehaviour挂载于场景中采用单例模式。
### 1.1 职责
| 职责 | 说明 |
|------|------|
| 系统初始化 | 按顺序初始化 13+ 单例管理器 |
| 游戏模式入口 | 单人/多人/观战/续局 的统一入口 |
| Update 主循环 | 每帧更新各子系统 |
| 存档管理 | 单人/多人存档检查与加载 |
### 1.2 初始化流程
```
Start()
├── StartInstanceGroup() // 初始化所有单例
│ ├── Table.Instance // 数据资产表
│ ├── Timer.Instance // 延时调度
│ ├── ResourceCache.Instance // 资源缓存
│ ├── ConfigManager.Instance // 配置管理
│ ├── MultilingualManager // 多语言
│ ├── AudioManager // 音频
│ ├── GameRecordManager // 录像管理
│ ├── AchievementDataManager // 成就
│ ├── LobbyManager // 网络大厅
│ ├── InputConfigManager // 输入配置
│ ├── CrashSightManager // 崩溃上报
│ └── ...更多管理器
├── 初始化逻辑模块
│ ├── InputLogic // 输入逻辑
│ ├── MapGeneratorLogic // 地图生成
│ ├── GameLogic // 游戏状态机
│ └── MapInteractionLogic // 地图交互
├── ModelInference.LoadModel() // 加载AI模型(可选)
└── OnGameStart() // 触发UI初始化 + 播放主菜单音乐
```
### 1.3 游戏模式入口
| 方法 | 模式 | 说明 |
|------|------|------|
| `StartMatch()` | 单人新局 | 创建MapData → 生成地图 → 初始化渲染 → 显示开局动画 |
| `ResumeMatch()` | 单人续局 | 从存档恢复MapData → 初始化渲染 |
| `MainMemberStartMatch()` | 多人主机新局 | Host创建地图 → 广播给所有玩家 |
| `MainMemberResumeMatch()` | 多人主机续局 | Host加载存档 → 广播给所有玩家 |
| `NetStartGame(MapData)` | 多人客户端新局 | 接收Host的MapData → 初始化 |
| `NetResumeMatch(MapData)` | 多人客户端续局 | 接收Host的MapData → 恢复 |
| `StartSpectate(MapData, MapData)` | 观战 | 加载已结束游戏 → 回放Action序列 |
### 1.4 三级逻辑架构
```
Level 1: InputLogic / AILogic ← 决策层(输入/AI
Level 2: MapInteractionLogic ← 交互层(地图交互)
Level 3: CityLogic / UnitLogic / PlayerLogic ← 执行层(具体逻辑)
```
### 1.5 关键字段
```csharp
public static Main Instance; // 单例
public static MapData MapData; // 当前游戏世界数据(静态)
public MapData SpectateMapData; // 观战回放数据
public MapConfig MapConfig; // 当前对局配置
public PlayerConfirmMap ConfirmMap; // 网络玩家确认状态
public bool IsNetActionExecuting; // 网络Action执行锁
```
### 1.6 调试参数
```csharp
public bool NoAI; // 禁用AI
public bool FullSight; // 全视野
public float AIActionTime; // AI行动间隔
public bool AIAllTech; // AI全科技
public bool AIMoreMoney; // AI额外资金
public float AnimationSpeed; // 动画速度
public bool DebugMode; // 调试模式
```
---
## 2. GameLogic.cs — 游戏状态机
`GameLogic` 是核心的游戏状态机,管理游戏的所有阶段和转换。
### 2.1 游戏状态 (GameState)
```
Menu → 主菜单/大厅
PlayerRound → 本地玩家回合
OtherPlayerRound → 其他玩家回合AI或远程玩家
DieWaiting → 玩家已阵亡,等待游戏结束
Finished → 游戏结束
ForceUpdating → 断线重连后强制同步
Spectate → 观战模式回放Action序列
```
### 2.2 状态转换图
```
┌─────────┐
│ Menu │
└────┬────┘
│ StartMatch
┌──────────────────────┐
│ PlayerRound │ ◄─────────────────┐
│ (玩家操作回合) │ │
└──────────┬───────────┘ │
│ TurnEnd │
▼ │
┌──────────────────────┐ │
│ OtherPlayerRound │ ── AI行动完成 ──────┘
│ (AI/其他玩家回合) │
└──────────┬───────────┘
┌────────┴────────┐
▼ ▼
┌──────────┐ ┌──────────────┐
│ Finished │ │ DieWaiting │
│ (结算) │ │ (阵亡等待) │
└──────────┘ └──────────────┘
```
### 2.3 Update 主循环
```
Update()
├── UpdateReconnect() // 每2秒检查重连(非Host)
├── SendHeartbeat() // 每2秒发送心跳(多人)
├── UpdateConnectState() // 检测玩家连接状态(10秒超时)
├── _gameStateDict[_curState].Update() // 执行当前状态逻辑
├── UpdateAI() // 处理AI回合(如需要)
└── UpdateConfirm() // 每5秒广播地图确认(Host)
```
### 2.4 AI回合管理
```csharp
// NeedAI() 判断规则:
// 1. 单人模式 → 非自己的玩家回合需要AI
// 2. 多人模式 → 断线超时的玩家由Host接管AI
// 3. 观战模式 → 不需要AI回放Action
UpdateAI()
├── 找到当前轮到的玩家
├── NeedAI() → 是否需要AI接管
├── AILogic.StartAILogic(mapData, player) // 启动AI
├── AILogic.Update() // AI决策循环
└── 完成后 → 切换到下一个玩家
```
### 2.5 网络同步机制
| 机制 | 间隔 | 说明 |
|------|------|------|
| 心跳 | 2秒 | 保持连接,检测延迟 |
| 重连 | 2秒 | 非Host定期检查连接 |
| 确认 | 5秒 | Host广播MapData校验和 |
| 超时 | 10秒 | 玩家超时后AI接管 |
### 2.6 各状态行为
| 状态 | Enter | Update | End |
|------|-------|--------|-----|
| **PlayerRound** | 播放音频 · 显示UI · 解锁输入 | — | 锁定输入 |
| **OtherPlayerRound** | 显示"AI思考中"提示 | — | — |
| **DieWaiting** | 显示"AI思考中"提示 | — | — |
| **Menu** | 清除游戏数据 | 更新大厅成员 · 检查配置变化 | — |
| **ForceUpdating** | 设10秒超时 | 超时返回Menu | — |
| **Spectate** | — | 回放Action序列 | — |
| **Finished** | 保存成就 · 录像 · 上传OSS · 退出 | — | — |
---
## 3. MainEditor.cs — AI调试编辑器
`MainEditor` 是AI策略可视化和Action录制的调试工具。
### 3.1 调试功能
| 快捷键 | 功能 |
|--------|------|
| F4 | 治满所有部队 |
| F10 | 启用编辑器模式 |
| F11 | 关闭编辑器模式 |
| Space | 执行一次AI行动 |
### 3.2 策略追踪
```csharp
// 追踪AI决策数据
_playerStrategy // 玩家级策略
_cityStrategy // 城市级策略
_unitStrategy // 部队级策略
_legionStrategy // 军团级策略
_unitTarget // 部队→目标城市映射
_actionRecord // 按城市分组的Action记录
```
---
## 4. 模块关系图
```
Main (MonoBehaviour, 场景入口)
├── GameLogic (状态机)
│ ├── PlayerRoundState
│ ├── OtherPlayerRoundState
│ ├── MenuState
│ ├── FinishedState
│ └── ...
├── InputLogic (玩家输入)
├── MapGeneratorLogic (地图生成)
├── MapInteractionLogic (地图交互)
├── CityLogic (static, 城市逻辑)
├── UnitLogic (static, 部队逻辑)
├── PlayerLogic (static, 玩家逻辑)
├── MapData (static, 游戏世界数据)
└── MainEditor (调试工具)
```

View File

@ -0,0 +1,393 @@
# 02 - 数据层Data 数据结构
> **目录**: `TH1_Data/`
> **核心**: 所有运行时游戏状态的数据结构,支持 MemoryPack 序列化
> **序列化**: 用于存档、网络同步、训练数据
---
## 1. MapData — 游戏世界总数据
**文件**: `MapData.cs` (88.4 KB最大的数据文件)
MapData 是整个游戏世界的数据容器,所有游戏状态都在此汇聚。
### 1.1 核心成员
```csharp
[MemoryPackable]
public partial class MapData
{
public uint MapID; // 地图唯一ID
public MapConfig MapConfig; // 对局配置(玩家数/难度/地图大小)
public GridMapData GridMap; // 所有格子数据
public PlayerMapData PlayerMap; // 所有玩家数据
public CityMapData CityMap; // 所有城市数据
public UnitMapData UnitMap; // 所有部队数据
public NetData Net; // 网络/多人状态
}
```
### 1.2 关系映射表 (ID → ID 字典)
```
CityToPlayerDict 城市ID → 玩家ID // 城市归属
UnitToCityDict 部队ID → 城市ID // 部队驻扎
UnitToGridDict 部队ID → 格子ID // 部队位置
CityToGridDict 城市ID → 格子ID // 城市位置
GridToCityDict 格子ID → 城市ID // 格子所属城市
```
### 1.3 查询方法
| 方法 | 功能 |
|------|------|
| `GetCityIdByGridId(gid)` | 通过格子找城市 |
| `GetCityDataByUnitId(uid)` | 通过部队找所属城市 |
| `GetCityDataListByPlayerId(pid)` | 获取玩家的所有城市 |
| `GetCapitalCityDataByPlayerId(pid)` | 获取玩家首都 |
| `GetUnitDataListByPlayerId(pid)` | 获取玩家的所有部队 |
| `GetGridDataSetByPlayerId(pid)` | 获取玩家的所有领土格子 |
### 1.4 修改方法
| 方法 | 功能 | 复杂度 |
|------|------|--------|
| `SetCityIdToPlayerId(cid, pid)` | 城市易主(征服) | 高:处理部队转移、玩家死亡 |
| `SetUnitIdToGridId(uid, gid)` | 移动部队 | 中:更新位置映射 |
| `SetUnitIdToCityId(uid, cid)` | 驻扎部队 | 低 |
| `SetUnitDataDie(uid)` | 部队阵亡 | 中:清理映射、更新视觉 |
---
## 2. GridData — 格子/地块数据
**文件**: `GridData.cs` (37.2 KB)
### 2.1 单个格子
```csharp
[MemoryPackable]
public partial class GridData : IdentifierBase
{
public Vector2Int Pos; // 位置坐标 (x, y)
public uint Id; // 唯一ID
// 地形/资源/建筑等信息
// 附加技能列表
}
```
### 2.2 GridMapData 容器
| 方法 | 功能 |
|------|------|
| `GetGridDataByGid(id)` | 按ID查找格子 |
| `GetGridDataByPos(pos)` | 按坐标查找格子 |
| `GetAroundGridData(center, radius)` | 获取周围格子(含中心) |
| `GetAroundGridDataSet_NOCENTER(center, radius)` | 获取周围格子(不含中心) |
| `GetAroundGridDataSetByOrder(center)` | BFS序获取邻居(上下左右优先) |
| `CalcDistance(a, b)` | 计算两格子距离 |
| `OnTurnStart()` / `OnTurnEnd()` | 回合生命周期 |
---
## 3. CityData — 城市数据
**文件**: `CityData.cs`
### 3.1 核心字段
```csharp
[MemoryPackable]
public partial class CityData : IdentifierBase
{
public uint Id; // 城市ID
public CityLibrary Name; // 城市名称枚举
public int Level; // 城市等级
public int LevelExp; // 升级经验
public bool IsCapital; // 是否首都
public int CityWall; // 城墙等级
public int Workshop; // 工坊等级
public int ParkCount; // 公园数量
public int ConnectExp; // 首都连接经验
public TerritoryData Territory; // 领土数据
}
```
### 3.2 TerritoryData 领土
```csharp
public class TerritoryData
{
public HashSet<uint> TerritoryArea; // 领土内的格子ID集合
}
```
### 3.3 关键方法
| 方法 | 功能 |
|------|------|
| `TryUpgradeCity()` | 尝试升级城市 |
| `CheckIsInTerritory(gid)` | 检查格子是否在领土内 |
| `SetCapital()` | 设为首都 |
| `Player()` | 获取拥有者 |
| `Grid()` | 获取城市所在格子 |
| `Civ()` | 获取所属文明 |
---
## 4. UnitData — 部队数据
**文件**: `UnitData.cs`
### 4.1 核心字段
```csharp
[MemoryPackable]
public partial class UnitData : IdentifierBase
{
public UnitFullType UnitFullType; // 完整类型(兵种+英雄+等级)
public UnitType UnitType; // 兵种类型
public GiantType GiantType; // 英雄类型
public int UnitLevel; // 等级
public ChessType ChessType; // 棋子分类
public int Health; // 当前HP
public int GiantExp; // 英雄经验
public UnitFullType CarryUnitFullType; // 携带的部队类型
public int DefenseReduction; // 防御削减
public uint LegionId; // 军团ID
// ActionPoint 行动点
// Common / Move / Attack / Capture 四类行动点
}
```
### 4.2 行动点系统
```
ActionPoint.Common → 通用行动点(每回合重置)
ActionPoint.Move → 移动行动点
ActionPoint.Attack → 攻击行动点
ActionPoint.Capture → 占领行动点
```
### 4.3 关键方法
| 方法 | 功能 |
|------|------|
| `IsAlive()` | 判断是否存活 |
| `OnTurnStart()` | 回合开始重置行动点 |
| `OnAfterTurnStart()` | 回合开始后触发技能 |
| `OnTurnEnd()` | 回合结束处理 |
---
## 5. PlayerData — 玩家数据
**文件**: `PlayerData.cs`
### 5.1 核心字段
```csharp
[MemoryPackable]
public partial class PlayerData : IdentifierBase
{
public uint Id; // 玩家ID
public CivEnum PlayerCivId; // 文明
public ForceEnum PlayerForceId; // 势力
public bool Alive; // 存活状态
public DiplomacyData DiplomacyData; // 外交关系
// 技能列表 (文明特性)
}
```
### 5.2 外交枚举
```csharp
// 外交状态
enum DiplomacyState {
NoDiplomacy, // 无外交
Neutral, // 中立
League, // 同盟
War, // 战争
LeagueRupture // 同盟破裂
}
// 好感度
enum FeelingState {
Trust, // 信任
Appreciate, // 欣赏
Indifferent, // 冷漠
Suspicion, // 猜疑
Terrible // 厌恶
}
// 性格策略
enum FeelingStrategy {
Wise, Charming, Peaceful, ...
}
```
### 5.3 奇迹类型
```csharp
enum WonderTypeEnum {
Peace, // 和平奇迹
Knowledge, // 知识奇迹
Trade, // 贸易奇迹
Wealth, // 财富奇迹
Power, // 力量奇迹
Park, // 公园奇迹
Eye // 天眼奇迹
}
```
---
## 6. NetData — 网络数据
**文件**: `NetData.cs`
### 6.1 网络模式
```csharp
enum NetMode {
None, // 无
Single, // 单人
Multi, // 多人
Spectator // 观战
}
```
### 6.2 核心字段
```csharp
[MemoryPackable]
public partial class NetData
{
public NetMode Mode; // 网络模式
public uint CurPlayerId; // 当前回合玩家
public Dictionary<ulong, uint> Players; // SteamId → PlayerId映射
public List<Action> Actions; // 所有已执行Action
public int RandomSeed; // 确定性随机种子
}
```
### 6.3 关键方法
| 方法 | 功能 |
|------|------|
| `GetRandom()` | 获取确定性随机数生成器 |
| `RefreshPlayerNet()` | 同步网络玩家数据 |
| `GetActionVersion()` | 获取下一个Action序列号 |
| `CompareEqual(other)` | 与其他客户端校验同步 |
### 6.4 PlayerConfirmData
```csharp
// 每个网络玩家的连接状态
public class PlayerConfirmData
{
public MemberNetState State; // OK / Leaved / Disconnected / Timeout / Error
// Ping/延迟测量
public void OnSendHeartbeat();
public void OnReceiveHeartbeat();
public void OnReceiveHeartbeatReply();
}
```
---
## 7. RuntimeData — 基类
**文件**: `RuntimeData.cs`
### 7.1 IdentifierBase
所有游戏实体的抽象基类:
```csharp
[MemoryPackable]
[MemoryPackUnion(0, typeof(PlayerData))]
[MemoryPackUnion(1, typeof(UnitData))]
[MemoryPackUnion(2, typeof(CityData))]
[MemoryPackUnion(3, typeof(GridData))]
public abstract partial class IdentifierBase
{
public uint Id; // 唯一标识
public List<SkillBase> Skills; // 技能列表
public SkillBase GetSkill(SkillType type); // 获取技能
public void AddOrOverrideSkill(SkillBase skill); // 添加/覆盖技能
public void SpecialAddOrOverrideSkill(skill, info); // 特殊添加(含覆盖信息)
}
```
---
## 8. MatchData — 对局配置
**文件**: `MatchData.cs`
### 8.1 对局限制
```csharp
enum MatchLimitType {
PlayerCannotLearnTech, // 玩家不能学习科技
PlayerCannotSelectHero, // 玩家不能选择英雄
AICannotLearnTech, // AI不能学习科技
AICannotBuildOrUpgradeCity, // AI不能建造/升级城市
AIMove3RoundsPerAction // AI每3回合行动一次
}
```
---
## 9. 数据关系总图
```
MapData (游戏世界根节点)
├── MapConfig (对局配置)
│ ├── 玩家数量
│ ├── 难度
│ └── 地图大小
├── GridMapData
│ └── GridData[] (每个地块)
│ ├── 位置 (x,y)
│ ├── 地形/资源
│ └── 技能列表
├── PlayerMapData
│ └── PlayerData[] (每个玩家)
│ ├── 文明/势力
│ ├── 外交关系
│ └── 技能列表(文明特性)
├── CityMapData
│ └── CityData[] (每座城市)
│ ├── 等级/经验
│ ├── 建筑(城墙/工坊/公园)
│ ├── TerritoryData (领土格子集合)
│ └── 技能列表
├── UnitMapData
│ └── UnitData[] (每个部队)
│ ├── 兵种/英雄类型/等级
│ ├── HP/行动点
│ ├── 军团归属
│ └── 技能列表
├── 关系映射表
│ ├── City ↔ Player
│ ├── Unit ↔ City
│ ├── Unit ↔ Grid
│ └── City ↔ Grid
└── NetData (网络状态)
├── 模式/当前玩家
├── Steam玩家映射
├── Action历史
└── 随机种子
```

View File

@ -0,0 +1,266 @@
# 03 - 行为系统Action
> **目录**: `TH1_Logic/Action/`
> **核心文件**: `ActionLogic.cs` (122KB) · 5个具体行为文件
> **设计模式**: 工厂模式 + 策略模式
---
## 1. 行为系统总览
游戏中所有玩家操作和AI操作都通过统一的 Action 系统执行。每个 Action 都经过:**生成 → 校验 → 执行 → 同步**。
### 1.1 行为类型 (CommonActionType)
```csharp
enum CommonActionType {
Gain, // 获取资源
Build, // 建造建筑
StartWonder, // 开始建造奇迹
TrainUnit, // 训练部队
GridMisc, // 格子杂项操作
UnitAction, // 部队行为
UnitSkill, // 部队技能
LearnTech, // 学习科技
UnitMove, // 部队移动
UnitAttack, // 部队攻击
// ... 共20种
}
```
### 1.2 行为显示状态 (ActionShowState)
```
None → 不显示
Available → 可用(绿色)
Unavailable → 不可用(灰色)
Expensive → 资源不足(红色)
Finished → 已完成
```
---
## 2. CommonActionParams — 通用行为参数
所有行为共用的参数容器,支持 MemoryPack 网络序列化。
```csharp
[MemoryPackable]
public partial class CommonActionParams
{
// 序列化字段(用于网络传输和存档)
public uint PlayerId;
public uint UnitId;
public uint CityId;
public uint GridId;
public uint TargetUnitId;
public uint TargetGridId;
// ... 更多数值ID
// 非序列化字段运行时对象引用从ID恢复
[MemoryPackIgnore] public PlayerData Player;
[MemoryPackIgnore] public UnitData Unit;
[MemoryPackIgnore] public CityData City;
[MemoryPackIgnore] public GridData Grid;
// ...
}
```
### 关键方法
| 方法 | 功能 |
|------|------|
| `RefreshParams()` | 从序列化ID恢复对象引用 |
| `OnParamChanged()` | 从对象引用同步到序列化ID |
| `GetCopyParam()` | 深拷贝 |
| `GetStringLog()` | 调试输出 |
---
## 3. 六大具体行为
### 3.1 BuildAction — 建造行为
**文件**: `BuildActionLogic.cs`
支持建造的建筑类型:
| 建筑 | 功能 |
|------|------|
| Farm (农场) | 增加粮食产出 |
| Mine (矿场) | 增加矿石产出 |
| Lumberhut (伐木场) | 增加木材产出 |
| Windmill (风车) | 加工粮食 |
| Sawmill (锯木厂) | 加工木材 |
| Forge (锻造厂) | 加工矿石 |
| Market (市场) | 增加金币 |
| Port (港口) | 水域建筑 |
执行流程:
```
Execute()
├── 更新格子资源
├── 放置建筑
├── 更新城市经验
├── 更新相邻格子道路
└── 触发技能检查
```
### 3.2 TrainUnitAction — 训练部队
**文件**: `TrainUnitActionLogic.cs`
```
校验流程:
├── TrainUnitActionCheckBaseData() // 验证玩家数据
├── TrainUnitActionCheckHasTechCulture() // 科技/文化卡检查
│ ├── 文明专属部队限制(埃及/法国/诸矢/印度)
│ ├── 科技前置条件
│ └── 文化卡前置条件
└── 资源消耗检查
```
### 3.3 UnitActionAction — 部队行为
**文件**: `UnitActionLogic.cs`
```csharp
enum UnitActionType {
Upgrade, // 升级
Recover, // 恢复
Heal, // 治疗
Examine, // 探索宝箱
Gather, // 采集资源
Capture, // 占领城市
Disband, // 解散
HeroUpgrade, // 英雄升级
// ...
}
```
**占领城市流程**:
```
Capture
├── 逻辑层处理(CityLogic)
├── 视图层更新(渲染器)
├── 城市经验分配
└── 英雄任务触发
```
### 3.4 PlayerActionAction — 玩家行为
**文件**: `PlayerActionLogic.cs`
```csharp
enum PlayerActionType {
OfferAlly, // 提议结盟
AcceptAlly, // 接受结盟
RefuseAlly, // 拒绝结盟
BreakAlly, // 破坏同盟
Embassy, // 建立大使馆
SelectHero, // 选择英雄
FinishHeroTask, // 完成英雄任务
}
```
继承结构:
```
PlayerActionAction : ActionLogicBase
└── PlayerActionDiplomacy : PlayerActionAction // 外交专用
```
### 3.5 GridMiscAction — 格子杂项
**文件**: `GridMiscActionLogic.cs`
```csharp
enum GridMiscActionType {
GrowForest, // 种植森林
ClearForest, // 砍伐森林
BurnForest, // 焚烧森林
Destroy, // 摧毁建筑
UpgradeTemple, // 升级神庙
GrowForestOutside, // 领土外种植
CreateMountain, // 创造山脉
SellMetal, // 出售金属
}
```
特殊逻辑:
- 森林操作影响部队防御状态
- 神庙升级影响信仰产出
- 竹子移动科技联动更新
### 3.6 LearnTech — 学习科技
通过 ActionLogic 主文件处理,消耗科技点学习科技树节点。
---
## 4. AI行为控制 (AIParamControlType)
```csharp
enum AIParamControlType {
AllClear, // 清除所有行动点
APClear, // 清除攻击点
MPClear, // 清除移动点
CPClear, // 清除占领点
AIMoney // AI金币消耗
}
```
---
## 5. 行为执行数据流
```
玩家点击UI / AI决策
┌───────────────────┐
│ CommonActionParams │ ← 填入操作参数
│ (PlayerId, UnitId, │
│ GridId, 行为类型) │
└───────┬───────────┘
┌───────────────────┐
│ ActionLogic.Check()│ ← 合法性校验
│ CanExecute? │ 资源足够?技能允许?
└───────┬───────────┘
│ ✓
┌───────────────────┐
│ ActionLogic │ ← 执行
│ .Execute() │ 修改MapData
└───────┬───────────┘
├──→ MemoryPack序列化 → 网络同步(多人)
├──→ 触发技能回调 (OnActionExecuted)
├──→ 更新渲染器 (UnitRenderer/CityRenderer)
└──→ 发布事件 (EventManager)
└─→ UI更新
```
---
## 6. 行为系统类图
```
ActionLogicBase (抽象基类)
├── BuildAction // 建造
├── TrainUnitAction // 训练
├── UnitActionAction // 部队行为
│ └── (Upgrade/Recover/Heal/Capture/...)
├── PlayerActionAction // 玩家行为
│ └── PlayerActionDiplomacy // 外交
├── GridMiscAction // 格子杂项
└── LearnTechAction // 学习科技
CommonActionParams // 通用参数(MemoryPackable)
CommonActionType // 行为类型枚举
ActionShowState // 显示状态枚举
```

View File

@ -0,0 +1,284 @@
# 04 - 逻辑模块City / Unit / Player
> **目录**: `TH1_Logic/City/` · `TH1_Logic/Unit/` · `TH1_Logic/Player/`
> **设计**: 接口 + 实现分离ICityLogic / CityLogic 等)
---
## 1. CityLogic — 城市逻辑
**文件**: `CityLogic.cs` (24.6 KB) + `ICityLogic.cs`
### 1.1 核心功能
| 方法 | 功能 | 说明 |
|------|------|------|
| `GenerateTribe()` | 生成部落 | 初始城市单位 |
| `TribeToCity()` | 部落→城市 | 定居建城 |
| `CityNewUnit()` | 城市出兵 | 在城市格子生成新部队 |
| `CityRemoveUnitFromList()` | 移除驻军 | 从城市部队列表移除 |
| `CityExploit()` | 城市开采 | 从格子提取资源 |
| `Update()` | 城市更新 | 每帧/每回合更新 |
### 1.2 城市经验与升级
```
CityUpdateExp_LogicOnly(city, exp)
├── 累加经验到 LevelExp
├── 检查是否达到升级阈值
└── 触发 CityUpdateLevel()
CityUpdateLevel(city)
├── 等级+1
├── 扩展领土(新增格子)
├── 发布 ShowUINotifyMoment 事件
├── 更新 MomentData
└── 触发英雄任务回调
GridGiveCityExp_LogicView(grid, city, exp)
├── 逻辑:累加经验
└── 视图:播放经验动画(投射物飞向城市)
```
### 1.3 城市探索系统
```csharp
int explorerStepMax; // 探索最大步数
int explorerStep; // 当前探索步数
Vector2Int explorerNowPos; // 探索者当前位置
CityData explorerCityData; // 正在探索的城市
```
---
## 2. UnitLogic — 部队逻辑
**文件**: `UnitLogic.cs` (86.2 KB最大逻辑文件) + `IUnitLogic.cs`
### 2.1 接口方法
```csharp
interface IUnitLogic {
void MoveToLogic(unit, path); // 移动(含路径)
void Attack(attacker, target); // 攻击
void Upgrade(unit); // 升级
void Recover(unit); // 恢复
void LandToBoat(unit); // 陆地→船
void BoatToLand(unit); // 船→陆地
void StartNextTurn(player); // 下一回合重置
}
```
### 2.2 伤害类型
```csharp
enum DamageType {
ActiveAttack, // 主动攻击
CounterAttack, // 反击
FollowAttack, // 追击
Splash, // 溅射
True, // 真实伤害
KillSelf, // 自杀
DelayAttack, // 延迟攻击
PushAttack // 推击
}
```
### 2.3 治疗类型
```csharp
enum HealType {
AttackAllyHeal, // 攻击友军治疗
SelfHeal // 自我治疗
}
```
### 2.4 AttackInfo — 战斗元数据
```csharp
struct AttackInfo {
UnitData DamageOrigin; // 攻击者
PlayerData OriginPlayer; // 攻击方玩家
UnitData DamageTarget; // 防御者
PlayerData TargetPlayer; // 防御方玩家
GridData DamageOriginGrid; // 攻击者格子
GridData DamageTargetGrid; // 防御者格子
bool IsKill; // 是否击杀
}
```
### 2.5 SettlementInfo — 伤害结算
```csharp
struct SettlementInfo {
DamageType DamageType; // 伤害类型
int DamageValue; // 伤害值
int HealthReduceValue; // 实际HP减少值
bool IsFinished; // 结算完成
bool IsKill; // 是否致死
// + 攻守双方所有引用
}
```
### 2.6 战斗流程
```
Attack(attacker, target)
├── 创建 AttackInfo
├── 技能回调: BeforeActiveAttackOther()
├── 计算伤害
│ ├── 基础伤害 = 攻击力 - 防御力
│ ├── 地形加成
│ ├── 技能加成 (GetAttackAdditionParam / GetDefenseAdditionParam)
│ ├── 暴击检查 (GetCriticalHitRate)
│ └── 最终伤害 = max(基础伤害, 最小伤害)
├── 应用伤害 (SettlementInfo)
│ ├── 技能回调: BeforeDamagedSupportStage()
│ ├── 技能回调: BeforeDamagedTransformStage()
│ ├── 技能回调: OnDamaged()
│ ├── 技能回调: OnDamageOther()
│ └── 技能回调: AfterDamageOther()
├── 反击判定(如目标存活且在攻击范围内)
│ └── 重复上述伤害计算流程
├── 击杀判定
│ ├── 技能回调: OnAnyUnitDie()
│ ├── MapData.SetUnitDataDie()
│ └── 发布事件
└── 生成动画 Fragment
├── FragmentAttack (单向攻击)
└── FragmentAttackAndCounter (攻击+反击)
```
### 2.7 移动流程
```
MoveToLogic(unit, path)
├── 技能回调: BeforeMove()
├── 消耗移动行动点
├── 更新 UnitToGrid 映射
├── 技能回调: OnMove()
├── 更新视野 (UpdateSight)
└── 生成 FragmentMove 动画
```
---
## 3. PlayerLogic — 玩家逻辑
**文件**: `PlayerLogic.cs` (76.0 KB) + `IPlayerLogic.cs`
### 3.1 接口方法
```csharp
interface IPlayerLogic {
void UpdateCityConnect(); // 更新城市连通性
void ExamineTreasure(unit, grid); // 探索宝箱
void Disband(unit); // 解散部队
void UpdateSight_LogicView(player); // 更新视野
void ResearchTech(player, tech); // 研究科技
void UpdatePlayerStarsPerTurn(player);// 计算每回合资源
}
```
### 3.2 奇迹系统 (Wonder)
```
奇迹类型及完成条件:
PEACE 和平奇迹 → 全部城市连通
KNOWLEDGE 知识奇迹 → 研究全部科技
TRADE 贸易奇迹 → 贸易路线条件
WEALTH 财富奇迹 → 金币达到阈值
EYE 天眼奇迹 → 所有瞭望塔可见
POWER 力量奇迹 → 军事力量条件
PARK 公园奇迹 → 公园数量达标
奇迹状态: NO_HINT → HAVE_HINT → FINISH_NOT_BUILD → (建造中) → 完成
```
### 3.3 城市连通性
```
UpdateCityConnect()
├── 从首都出发
├── BFS遍历道路相连的领土
├── 标记可达城市为"已连通"
└── 连通城市获得额外经验
```
### 3.4 视野系统
```
UpdateSight_LogicView(player)
├── 遍历玩家所有部队
│ └── 每个部队的视野范围 = 基础视野 + GetExtraSight()
├── 遍历玩家所有城市领土
├── 合并所有可见格子 → Sight.SightGidSet
└── 更新雾气渲染
```
### 3.5 征服与占领
```
OccupyCity_LogicView(player, city)
├── 城市易主 (MapData.SetCityIdToPlayerId)
│ ├── 原属部队处理
│ ├── 检查原玩家是否全灭
│ └── 更新所有关系映射
├── 更新领土
└── 更新视野
OccupyVillage_LogicOnly(player, grid)
├── 村庄转化为城市
└── 分配初始领土
```
### 3.6 每回合资源计算
```
UpdatePlayerStarsPerTurn(player)
├── 遍历所有领土格子
│ ├── 计算每个格子的资源产出
│ ├── 建筑加成
│ └── 文明特性加成
├── 汇总金币/科技/文化产出
└── 更新 UI TopBar
```
---
## 4. 三大逻辑关系图
```
┌─────────────────────────────────────────┐
│ PlayerLogic │
│ 视野 · 科技 · 奇迹 · 资源 · 征服 │
│ UpdateSight · ResearchTech · Wonder │
├─────────────┬───────────────────────────┤
│ │ 调用 │
│ ▼ │
│ ┌──────────────────┐ ┌────────────┐ │
│ │ CityLogic │ │ UnitLogic │ │
│ │ 经验·升级·建城 │ │移动·攻击 │ │
│ │ 领土·驻军·开采 │ │升级·恢复 │ │
│ └────────┬─────────┘ └─────┬──────┘ │
│ │ │ │
│ └───────┬───────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ MapData │ │
│ │ (共享状态) │ │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ SkillOwner │ │
│ │ (技能回调) │ │
│ └──────────────┘ │
└─────────────────────────────────────────┘
```

View File

@ -0,0 +1,287 @@
# 05 - 技能系统Skill
> **目录**: `TH1_Logic/Skill/`
> **规模**: 296种 SkillType · 300+实现文件 · 50+接口方法
> **设计**: 反射工厂 + MemoryPack 多态序列化
---
## 1. 技能类型 (SkillType)
共 296 种技能,从 `NONE=0``Max=999`,分为以下几大类:
### 1.1 通用战斗技能
| 技能 | 说明 |
|------|------|
| DASH | 冲锋(额外移动) |
| ESCAPE | 逃脱 |
| PERSIST | 坚韧 |
| SPLASH | 溅射攻击 |
| SNEAK | 潜行 |
| STIFF | 僵硬 |
| FORTIFY | 防御强化 |
| HEAL | 治疗 |
| CONVERT | 转化 |
| SCOUT | 侦察 |
| FLY | 飞行(无视地形) |
| CRITICAL | 暴击 |
### 1.2 角色专属技能
```
Remilia系列: RemiliaBuffSkill, RemiliaAttackSkill, ...
Kaguya系列: KaguyaFrench*, ...
Kanako系列: KanakoGermany*, ...
Satori系列: SatoriIndian*, ...
Reimu系列: ReimuNorway*, ...
Byakuren系列: ByakurenBritish*, ...
Miko系列: MikoPersian*, ...
Zanmu系列: ZanmuByzantine*, ...
```
### 1.3 早苗神授技能 (SanaeDivine)
```
SanaeDivine/ 目录下13个独立文件:
├── SanaeDivine_E2_ATK_Skill (攻击强化)
├── SanaeDivine_E2_MOVE_Skill (移动强化)
├── SanaeDivine_E3_COUNTER_Skill(反击强化)
├── SanaeDivine_E3_HP_Skill (HP强化)
├── SanaeDivine_E4_DEFENSE_Skill(防御强化)
├── SanaeDivine_E4_KILL_Skill (击杀触发)
├── SanaeDivine_F2_DEFENSE_Skill(防御护盾)
├── SanaeDivine_F2_RESIST_Skill (抗性)
├── SanaeDivine_F3_MOVE_Skill (移动增益)
├── SanaeDivine_F3_RESIST_Skill (范围抗性)
├── SanaeDivine_F4_ATK_Skill (范围攻击)
└── SanaeDivine_F4_KILL_Skill (范围击杀)
```
---
## 2. ISkill 接口 — 50+ 生命周期方法
### 2.1 移动相关
```csharp
void BeforeMove(); // 移动前
void OnMove(); // 移动时
```
### 2.2 伤害/战斗相关
```csharp
// 被攻击流程
void BeforeDamagedSupportStage(); // 被打前-支援阶段
void BeforeDamagedTransformStage(); // 被打前-变身阶段
void OnDamaged(); // 被打时
void OnHealOther(); // 治疗他人时
// 攻击流程
void BeforeDamageOther(); // 伤害他人前
void OnDamageOther(); // 伤害他人时
void AfterDamageOther(); // 伤害他人后
void BeforeActiveAttackOther(); // 主动攻击前
void AfterActiveAttackOther(); // 主动攻击后
```
### 2.3 回合相关
```csharp
void OnTurnStart(); // 回合开始
void OnAfterTurnStart(); // 回合开始后
void OnTurnEnd(); // 回合结束
void OnRefresh(); // 刷新
void OnFinished(); // 完成
void BeforeDisappear(); // 消失前
```
### 2.4 全局事件(任何部队触发)
```csharp
void BeforeUnitDamaged(); // 任何部队被攻击前
void OnUnitDamaged(); // 任何部队被攻击时
void OnAnyUnitMove(); // 任何部队移动
void OnAnyUnitDie(); // 任何部队死亡
void OnAnyUnitCreate(); // 任何部队创建
void OnActionExecuted(); // 任何Action执行后
```
### 2.5 状态查询20+
```csharp
bool IsHideState(); // 隐身状态
bool IsOfficer(); // 军官状态
bool CanAttackAll(); // 可攻击所有
bool IsLimitSelfMove(); // 限制自身移动
bool IsLimitSelfAttack(); // 限制自身攻击
bool IsIgnoreZOC(); // 无视控制区
bool HasZOC(); // 拥有控制区
bool IsCanMoveOnTerrain(); // 可移动到地形
bool IsCanMoveOnFeature(); // 可移动到地物
bool IsCanBeKill(); // 可被击杀
bool IsCanBeOfficer(); // 可成为军官
int GetExtraSight(); // 额外视野
float GetCriticalHitRate(); // 暴击率
float GetAttackAdditionParam(); // 攻击加成
float GetDefenseAdditionParam(); // 防御加成
int GetExtraMoveRange(); // 额外移动范围
int GetExtraAttackRange(); // 额外攻击范围
```
### 2.6 变身/进化
```csharp
bool ReservedOnTransform(); // 变身时保留
bool ReservedOnTransformBoat(); // 上船时保留
bool ReservedOnTransformUpgrade(); // 升级时保留
SkillBase NewSkillOnTransform(); // 变身后新技能
```
---
## 3. SkillBase — 抽象基类
```csharp
[MemoryPackable]
[MemoryPackUnion(0, typeof(DashSkill))]
[MemoryPackUnion(1, typeof(FlySkill))]
// ... 300+ Union子类型
public abstract partial class SkillBase
{
public bool IsPermanent; // 永久 vs 临时
public bool IsLevelSkill; // 可叠加等级
public uint OriginId; // 来源部队ID
public uint Turns; // 已持续回合数
public uint TurnsLimit; // 最大持续回合
public float Score; // AI评分
public int _level; // 技能等级
public int _levelLimit; // 等级上限
public bool _autoDisappear; // 等级归零时自动消失
}
```
### 3.1 特殊添加类型
```csharp
enum SpecialAddSkillType {
Normal, // 普通添加
Force, // 强制添加
AddTurnLimit, // 增加回合限制
AddLevel // 增加等级
}
```
### 3.2 技能覆盖信息
```csharp
class SkillOverrideInfo {
SpecialAddSkillType AddType;
uint TurnsLimit;
int Level;
bool AutoDisappear;
}
```
---
## 4. SkillFactory — 反射工厂
```csharp
class SkillFactory
{
static Dictionary<SkillType, Type> _skillDict;
static SkillBase GetSkillBySkillType(SkillType type)
{
// 首次调用时:
// 1. 扫描程序集中所有 SkillBase 子类
// 2. 实例化每个子类获取其 SkillType
// 3. 建立 SkillType → Type 映射字典
// 后续调用:直接从字典创建实例
if (_skillDict == null) {
_skillDict = new Dictionary<SkillType, Type>();
foreach (var type in Assembly.GetTypes())
if (type.IsSubclassOf(typeof(SkillBase)))
RegisterSkill(type);
}
return Activator.CreateInstance(_skillDict[type]) as SkillBase;
}
}
```
---
## 5. SkillOwner — 技能容器
```csharp
class SkillOwner {
public List<SkillBase> Skills; // 拥有的技能列表
}
```
SkillOwner 附着在每个实体Unit/City/Grid/Player`IdentifierBase.Skills` 上。
---
## 6. 技能触发时序图
```
┌──────────────────── 攻击流程 ────────────────────┐
│ │
│ 攻击者技能: │
│ ① BeforeActiveAttackOther() │
│ ② BeforeDamageOther() │
│ │
│ 防御者技能: │
│ ③ BeforeDamagedSupportStage() ← 可触发支援 │
│ ④ BeforeDamagedTransformStage() ← 可触发变身 │
│ │
│ ── 伤害结算 ── │
│ │
│ 防御者技能: │
│ ⑤ OnDamaged() │
│ │
│ 攻击者技能: │
│ ⑥ OnDamageOther() │
│ ⑦ AfterDamageOther() │
│ ⑧ AfterActiveAttackOther() │
│ │
│ 全局技能(所有部队): │
│ ⑨ OnUnitDamaged() │
│ ⑩ OnAnyUnitDie() (如击杀) │
│ │
└───────────────────────────────────────────────────┘
```
---
## 7. 目录结构
```
TH1_Logic/Skill/
├── SkillBase.cs # 核心SkillType枚举 + ISkill接口 + SkillBase基类
├── SkillFactory.cs # 反射工厂
├── SkillOwner.cs # 技能容器
├── AllSkill/ # 300+ 技能实现
│ ├── AttackUpSkill.cs
│ ├── DefenseUpSkill.cs
│ ├── HealSkill.cs
│ ├── DashSkill.cs
│ ├── FlySkill.cs
│ ├── CriticalSkill.cs
│ ├── RemiliaAttackSkill.cs
│ ├── KaguyaFrench*.cs
│ └── ... (300+ 文件)
├── SanaeDivine/ # 早苗神授系列 (13文件)
│ ├── SanaeDivineSkill.cs
│ └── SanaeDivine_*.cs
└── Generate/ # MemoryPack自动生成
├── *.MemoryPackable.g.cs
└── SkillBase.MemoryPackUnion.g.cs
```

View File

@ -0,0 +1,315 @@
# 06 - AI系统
> **目录**: `TH1_Logic/AI/` + `BTNodeCanvas/`
> **核心**: 行为树决策 + 评分系统 + Action生成器
> **规模**: 150+ 行为树节点
---
## 1. AILogic — AI核心状态机
**文件**: `AILogic.cs`
### 1.1 AI状态
```csharp
enum AILogicState {
Prepare, // 初始化
Playing, // 决策中
PrePlay, // 预行动
Pausing, // 等待动画
Finished // 完成
}
```
### 1.2 行动分类
```csharp
enum AIActionType {
Grid, // 地形操作
City, // 城市操作
Unit, // 部队操作
Tech, // 科技研究
Max // 总数
}
```
### 1.3 核心流程
```
StartAILogic(MapData, PlayerData)
├── 初始化评分器
├── 初始化生成器
└── 设置行为树
Update() (每帧调用最多200次循环保护)
├── Prepare → 初始化BT → Playing
├── Playing → 运行行为树 → 选择最佳Action
├── PrePlay → 准备执行
├── Pausing → 等待动画完成
└── 回到Playing 或 Finished
FinishAILogic()
├── 记录AI行动日志
└── 清理状态
```
### 1.4 ML模型支持
```csharp
#if ENABLE_AIMODEL
void AIModelExecute()
├── TrainingState.GetMapState() → 802维状态向量
├── TrainingState.GetAllActionBitCodec() → 合法Action列表
├── ModelInference.Predict() → 选择最佳Action索引
└── 执行选中的Action
#endif
```
---
## 2. AIActionGenerator — Action生成器
**文件**: `AIActionGenerator.cs`
### 2.1 职责
为AI生成所有合法的 Action 选项。
```csharp
class AIActionGenerator
{
void Init(MapData, PlayerData);
// 分类生成
void GeneratorUnitActions(); // 部队行为
void GeneratorGridActions(); // 格子行为
void GeneratorCityActions(); // 城市行为
void GeneratorTechActions(); // 科技行为
// 轮转生成(每次调用生成一类)
void GeneratorOneStepActions();
// 待处理队列
List<UnitData> _waitUnits;
List<GridData> _waitGrids;
List<CityData> _waitCity;
}
```
---
## 3. AIActionScoreCalculator — 评分计算器
**文件**: `AIActionScoreCalculator.cs`
### 3.1 评分维度 (14种)
```csharp
enum AICalculatorType {
Sight, // 视野评分
UnitCanMove, // 移动力评分
MoneyScore, // 经济评分
UnitScore, // 部队价值
CityScore, // 城市价值
CityDefendScore, // 城防评分
UnitAttack, // 攻击评分
UnitDefend, // 防御评分
UnitExplore, // 探索评分
UnitExploreCityCenter, // 城市中心探索
UnitExploreTreasure, // 宝箱探索
UnitExploreStarfish, // 海星探索
TechScore // 科技评分
}
```
### 3.2 评分数据
```csharp
class CalculateResult {
Dictionary<AICalculatorType, float> Scores;
}
class UnitTargetMap {
Dictionary<UnitData, List<UnitData>> AttackTargets;
}
```
### 3.3 配置权重 (AIConfigAsset)
```csharp
class AIConfigAsset : ScriptableObject
{
float MoneyScore; // 经济权重
float UnitScore; // 部队权重
float CityScore; // 城市权重
float CityDefendScore; // 城防权重
float UnitAttackScore; // 攻击权重
float UnitDefendScore; // 防御权重
float UnitExploreScore; // 探索权重
float FutureScoreTransformValue; // 远期评估折扣
float MilitaryConstructionRatioValue; // 军事/建设平衡
List<AICalculatorTechInfo> TechInfoList; // 科技评分表
List<AIDiffInfo> AidiffInfos; // 难度修正
}
```
---
## 4. BTNodeCanvas — 行为树节点 (150+)
**目录**: `BTNodeCanvas/`
### 4.1 基类
| 类 | 继承 | 功能 |
|---|------|------|
| `BaseCondition` | ConditionTask | 条件节点基类带NodeId |
| `BaseActionTask` | ActionTask | 行为节点基类,带日志记录 |
### 4.2 条件节点分类
#### 策略判断
| 节点 | 检查内容 |
|------|---------|
| `CountryStrategyCondition` | 国家策略匹配 |
| `AIParamPlayerTurn` | 当前玩家回合 |
| `AIParamPlayerWealth` | 玩家财富比较 |
| `AIParamRandom` | 随机概率 (0-100%) |
#### 部队状态
| 节点 | 检查内容 |
|------|---------|
| `AIParamHealth` | 血量比例 |
| `AIParamLevel` | 部队等级 |
| `AIParamUnitCiv` | 部队文明 |
| `AIParamUnitFullType` | 部队完整类型 |
| `AIParamSelfSkill` | 自身技能 |
| `AIParamSelfSkillLevel` | 技能等级 |
#### 目标分析
| 节点 | 检查内容 |
|------|---------|
| `AIParamTargetHealth` | 目标血量 |
| `AIParamTargetHealthRatio` | 目标血量比 |
| `AIParamIsTargetAttacker` | 目标是否攻击型 |
| `AIParamIsTargetHeroAttacker` | 目标英雄攻击能力 |
| `AIParamTargetUnitFullType` | 目标类型 |
| `AIParamTargetUnitLeague` | 目标阵营 |
#### 空间分析
| 节点 | 检查内容 |
|------|---------|
| `AIParamAroundUnitCount` | 周围部队数量 |
| `AIParamAroundOtherUnitCount` | 周围敌方数量 |
| `AIParamAroundSelfLeagueUnitCount` | 周围友军数量 |
| `AIParamTargetGridDistance` | 到目标距离 |
| `AIParamTargetCityInAttackRange` | 目标城市可攻击 |
| `AIParamAroundNoUnitCity` | 附近无守军城市 |
#### 领土与城市
| 节点 | 检查内容 |
|------|---------|
| `AIParamSelfTerritory` | 自身领土 |
| `AIParamSelfTerritoryResource` | 领土资源 |
| `AIParamSelfCityCount` | 城市数量 |
| `AIParamTargetGridIsMyCity` | 目标是我的城市 |
| `AIParamTargetGridIsOtherCity` | 目标是他人城市 |
| `AIParamCityLevelMoreThanX` | 城市等级阈值 |
#### 外交
| 节点 | 检查内容 |
|------|---------|
| `AIParamFeelingValue` | 好感度 |
| `AIParamAnyPlayerFeelValue` | 任意玩家好感 |
| `AIParamHandleLeagueRequest` | 处理结盟请求 |
| `AIParamBuildEmbassy` | 建造大使馆 |
### 4.3 行为节点
| 节点 | 功能 |
|------|------|
| `AIGeneratorAction` | 生成合法Action列表 |
| `AICalculateAction` | 计算最优Action |
| `AIExcuteAction` | 执行选中Action |
| `AIFinishAction` | 标记完成 |
| `MarkAction` | 添加/检查标记 |
### 4.4 流程控制
| 节点 | 功能 |
|------|------|
| `AIForeachStart` | 遍历Action列表开始 |
| `AIForeachEnd` | 遍历结束 |
| `AIGeneratorActionReturnTrue` | 有Action则成功 |
### 4.5 最优选择
```
AIParamChooseMaxAttacker 选择最强攻击目标
AIParamChooseMaxKillScore 选择最高击杀分目标
AIParamChooseMaxDefendScore 选择最高防御分目标
```
---
## 5. AI决策流程
```
AI回合开始
┌────────────────────────────────┐
│ 1. 评分计算 (ScoreCalculator) │
│ 视野/移动/经济/战斗评分 │
└──────────────┬─────────────────┘
┌────────────────────────────────┐
│ 2. 行为树执行 (BehaviourTree) │
│ 条件判断 → 策略选择 │
│ 150+ 节点组合决策 │
└──────────────┬─────────────────┘
┌────────────────────────────────┐
│ 3. Action生成 (Generator) │
│ 为每个部队/城市生成合法操作 │
└──────────────┬─────────────────┘
┌────────────────────────────────┐
│ 4. Action评分 & 排序 │
│ 对每个Action计算分数 │
│ 选择最优Action │
└──────────────┬─────────────────┘
┌────────────────────────────────┐
│ 5. 执行Action │
│ 修改MapData → 触发动画 │
│ (最多200次循环保护) │
└──────────────┬─────────────────┘
AI回合结束
```
---
## 6. AI配置 (Excel驱动)
**文件**: `TH1_Config/GenerateCS/AIConfig.cs`
```csharp
class AIConfig {
int Id; // 配置ID
int AIConfigId; // AI组ID
int Order; // 序列号
string Name; // 节点名 (如 "SelectTarget", "AttackCity")
string[] NodeParams; // 节点参数数组
}
```
AI行为树的节点参数由 Excel 表驱动,运行时反序列化为配置数据。

View File

@ -0,0 +1,247 @@
# 07 - 事件系统Event
> **目录**: `TH1_Core/Events/` + `TH1_Core/Managers/`
> **核心**: EventManager (泛型发布/订阅) + 100+ struct事件
---
## 1. EventManager — 事件总线
**文件**: `TH1_Core/Managers/EventManager.cs`
### 1.1 架构
基于静态字典的泛型发布/订阅系统,所有事件类型为 `struct` 以提高性能。
```csharp
public static class EventManager
{
// 类型 → 委托链
static Dictionary<Type, Delegate> _eventDict;
// 订阅
public static void Subscribe<T>(Action<T> listener) where T : struct;
// 取消订阅
public static void Unsubscribe<T>(Action<T> listener) where T : struct;
// 发布
public static void Publish<T>(T eventData) where T : struct;
}
```
### 1.2 特性
- **线程安全**: 委托链操作
- **多订阅者**: 同一事件可有多个监听者
- **类型安全**: 泛型约束 `struct`
- **零GC**: struct事件不产生堆分配
---
## 2. UIEvents — 事件定义
**文件**: `TH1_Core/Events/UIEvents.cs`
### 2.1 提示事件
```csharp
struct ShowHintEvent { ... } // 显示提示
struct HideHintEvent { ... } // 隐藏提示
struct HintTriggerDisabledEvent { ... } // 提示触发禁用
struct ShowHeroHintPanelEvent { ... } // 英雄提示面板
```
### 2.2 重大公告事件
```csharp
struct ShowUIAnnounceMajorEvent {
UIAnnounceMajorEventType Type;
}
enum UIAnnounceMajorEventType {
StartGame, // 游戏开始
FirstMeet, // 首次遭遇
CivLose, // 文明灭亡
WonderStart, // 奇迹开工
WonderEnd // 奇迹完成
}
```
### 2.3 交互事件
```csharp
struct ShowUIInteractionCityUpgrade { ... } // 城市升级交互
struct ChoiceUIInteractionCityUpgrade { ... } // 城市升级选择
```
### 2.4 信息面板事件
```csharp
struct ShowUIInfoDiplomacy { ... } // 外交面板
struct ShowUIInfoHero { ... } // 英雄面板
struct ShowUIInfoTechTree { ... } // 科技树面板
struct ShowUIInfoGridInfo { // 格子信息面板
UIGridInfoType Type;
}
enum UIGridInfoType {
// 格子/部队/城市信息类型
}
```
### 2.5 通知事件
```csharp
struct ShowUINotifyCommon {
UINotifyCommonType Type;
}
struct ShowUINotifyMoment { ... } // 历史时刻通知
enum UINotifyCommonType {
// 通用通知类型
}
```
### 2.6 外部界面事件
```csharp
struct ShowUIOutsideMultiplay { ... } // 多人界面
struct ShowUIOutsideMenu { ... } // 主菜单
struct ShowUIOutsideHistory { ... } // 历史记录
struct ShowUIOutsideLibrary { ... } // 百科图书馆
struct ShowUIOutsideTutor { ... } // 教程
struct ShowUIOutsideStory { ... } // 故事模式
```
### 2.7 HUD事件
```csharp
// 底部栏
struct ShowUIBottomBottomBar { ... }
// 顶部栏
struct ShowUITopTopBar { ... }
struct UpdateUITopTopBar {
UpdateTopBarType Type;
}
enum UpdateTopBarType {
Faith, // 信仰
Coin, // 金币
Tech, // 科技
Culture, // 文化
// ...
}
```
---
## 3. UIEventManagerBinder — 事件路由中心
**文件**: `TH1_Core/Events/UIEventManagerBinder.cs` (30.8 KB)
### 3.1 职责
订阅所有UI事件并路由到对应的 Controller。
```
Initialize()
├── Subscribe<ShowUIAnnounceMajorEvent>(HandleAnnounce)
├── Subscribe<ShowUIInteractionCityUpgrade>(HandleCityUpgrade)
├── Subscribe<ShowUIInfoDiplomacy>(HandleDiplomacy)
├── Subscribe<ShowUIInfoTechTree>(HandleTechTree)
├── Subscribe<ShowUINotifyCommon>(HandleNotify)
├── Subscribe<ShowUIOutsideMenu>(HandleMenu)
├── Subscribe<ShowUIBottomBottomBar>(HandleBottomBar)
├── Subscribe<ShowUITopTopBar>(HandleTopBar)
└── ... 100+ 订阅
```
### 3.2 路由目标
```
事件 → UIEventManagerBinder → Controller
ShowUIAnnounceMajorEvent → UIAnnounceMajorEventController
ShowUIInteractionCityUpgrade → UIInteractionCityLevelupController
ShowUIInfoDiplomacy → UIInfoDiplomacyController
ShowUIInfoTechTree → UIInfoTechTreeController
ShowUIInfoGridInfo → UIInfoGridInfoController
ShowUIInfoHero → UIInfoHeroController
ShowUINotifyCommon → UINotifyCommonController
ShowUINotifyMoment → UINotifyMomentController
ShowUIOutsideMenu → UIOutsideMenuController
ShowUIOutsideMultiplay → UIOutsideMultiplayController
ShowUIBottomBottomBar → UIBottomBottomBarController
ShowUITopTopBar → UITopTopBarController
```
---
## 4. 事件驱动数据流
```
┌──────────────┐
│ 游戏逻辑 │ CityLogic / UnitLogic / PlayerLogic
│ 执行Action │
└──────┬───────┘
│ EventManager.Publish(new ShowUINotifyMoment{...})
┌──────────────┐
│ EventManager │ 静态字典查找订阅者
│ (发布/订阅) │
└──────┬───────┘
│ 委托链调用
┌──────────────┐
│EventManager │
│ Binder │ UIEventManagerBinder 路由
└──────┬───────┘
│ 调用对应Controller
┌──────────────┐
│ Controller │ UINotifyMomentController
│ 打开UI窗口 │
└──────┬───────┘
┌──────────────┐
│ PresentationManager │ 加入演出队列(顺序执行)
│ (如果是演出类) │
└──────────────┘
```
---
## 5. 使用示例
### 发布事件(逻辑层)
```csharp
// 城市升级时通知UI
EventManager.Publish(new ShowUINotifyMoment {
MomentType = MomentType.CityLevelUp,
CityData = city
});
// 游戏开始公告
EventManager.Publish(new ShowUIAnnounceMajorEvent {
Type = UIAnnounceMajorEventType.StartGame
});
// 更新顶部资源栏
EventManager.Publish(new UpdateUITopTopBar {
Type = UpdateTopBarType.Coin
});
```
### 订阅事件UI层
```csharp
// 在 UIEventManagerBinder.Initialize() 中
EventManager.Subscribe<ShowUIAnnounceMajorEvent>(e => {
UIAnnounceMajorEventController.Show(e.Type);
});
```

View File

@ -0,0 +1,278 @@
# 08 - UI框架
> **目录**: `TH1_UI/` + `TH1_Core/Managers/UIManager.cs`
> **核心**: ViewController模式 · 5大UI管理器 · 20+ Controller
---
## 1. UIManager — UI总管理器
**文件**: `TH1_Core/Managers/UIManager.cs`
### 1.1 UI层级
```csharp
enum UIRootType {
PresentationUI, // 演出层(公告、交互弹窗)
InfoUI, // 信息层(外交、科技树、格子信息)
NotifyUI, // 通知层(浮动消息)
OutsideUI, // 外部层(菜单、大厅、加载)
BottomUI, // 底部层(操作栏)
TopUI // 顶部层(资源栏)
}
```
### 1.2 五大子管理器
| 管理器 | 职责 |
|--------|------|
| `UIInfoManager` | 信息面板(顺序队列) |
| `UINotifyManager` | 通知消息 |
| `UIOutsideManager` | 菜单/大厅/加载 |
| `UIBottomManager` | 底部操作栏 |
| `UITopManager` | 顶部资源栏 |
### 1.3 初始化
```
Init(Main main)
├── 查找Canvas Root
├── 创建5个子管理器
└── 关联UIEventManagerBinder
OnGameStart() → 显示主菜单
OnMatchStart() → 初始化游戏内UI
ShowLoading() → 显示加载画面
```
---
## 2. ViewController — UI控制器基类
**文件**: `TH1_UI/Controller/Base/ViewController.cs`
### 2.1 生命周期
```
Start() → Open() → _TryOpen() → LoadProperty.Start()
┌────────────────┘
_OnWindowLoadNotify()
OnLoaded()
_TrueOpen()
OnOpen() → RegisterEventCallback()
OpenProperty.Execute()
[UI 激活中]
▼ (关闭)
Close() → _TrueClose()
UnregisterEventCallback()
OnClose()
隐藏动画 → postHideAction()
OnClosedCallback?.Invoke()
```
### 2.2 属性系统
| 属性类 | 功能 |
|--------|------|
| `ViewLoadProperty` | Prefab加载从Resources |
| `ViewDepthProperty` | Z序管理WinDepthType |
| `ViewHierarchyProperty` | 互斥层级(同层只显示一个) |
| `ViewOpenProperty` | 打开事件回调 |
| `ViewCloseProperty` | 关闭事件回调 |
| `ViewCameraProperty` | 相机后处理开关 |
| `ViewMaskProperty` | 点击遮罩 |
### 2.3 深度类型
```csharp
enum WinDepthType {
// 不同UI层级有不同的深度排序
}
```
---
## 3. 控制器分类
### 3.1 公告控制器 (Announce)
| 控制器 | 功能 |
|--------|------|
| `UIAnnounceMajorEventController` | 重大事件公告(开局/遭遇/灭亡/奇迹) |
| `UIAnnounceDiplomacyController` | 外交公告 |
### 3.2 交互控制器 (Interaction)
| 控制器 | 功能 |
|--------|------|
| `UIInteractionCityLevelupController` | 城市升级选项 |
| `UIInterationDiplomacyOfferAllyController` | 结盟提议 |
### 3.3 信息控制器 (Info)
| 控制器 | 功能 |
|--------|------|
| `UIInfoDiplomacyController` | 外交关系面板 |
| `UIInfoGridInfoController` | 格子/部队/城市信息 |
| `UIInfoHeroController` | 英雄详情 |
| `UIInfoTechTreeController` | 科技树 |
### 3.4 通知控制器 (Notify)
| 控制器 | 功能 |
|--------|------|
| `UINotifyCommonController` | 通用浮动通知 |
| `UINotifyMomentController` | 历史时刻通知 |
### 3.5 外部控制器 (Outside)
| 控制器 | 功能 |
|--------|------|
| `UIOutsideMenuController` | 主菜单 |
| `UIOutsideMultiplayController` | 多人大厅 |
| `UIOutsideSelectController` | 文明/场景选择 |
| `UIOutsideLoadingController` | 加载画面 |
| `UIOutsideHistoryController` | 游戏历史 |
| `UIOutsideLibraryController` | 百科图书馆 |
| `UIOutsideStoryController` | 故事模式 |
| `UIOutsideTutorController` | 教程 |
| `UIOutsideInvitedController` | 邀请 |
### 3.6 底部控制器 (Bottom)
| 控制器 | 功能 |
|--------|------|
| `UIBottomBottomBarController` | 底部操作栏(行动按钮) |
| `UIBottomNetController` | 网络连接状态 |
| `UIBottomRankingController` | 排行榜 |
| `UIBottomTutorController` | 教程提示 |
### 3.7 顶部控制器 (Top)
| 控制器 | 功能 |
|--------|------|
| `UITopTopBarController` | 资源/信仰/金币/科技/文化 |
| `UITopSettingController` | 设置面板 |
| `UITopWinController` | 胜利条件面板 |
| `UITopInvitedController` | 邀请面板 |
### 3.8 提示控制器 (HintUI)
| 控制器 | 功能 |
|--------|------|
| `HintWindowController` | 提示窗口管理 |
| `HeroHintPanel` | 英雄提示 |
| `HintUI` | 通用提示 |
| `HintTrigger` | 提示触发器 |
| `HintDataProvider` | 提示数据源 |
---
## 4. 公共UI组件
### 4.1 基础组件
| 组件 | 功能 |
|------|------|
| `CommonUI` | 抽象UI基类带动画 |
| `BaseUIView<TData>` | 泛型View模板 |
| `BoardingUI` | 版本选择UI |
| `CameraController` | 摄像机控制(缩放/平移/平滑移动) |
| `DebugUI` | 调试面板 |
| `UIBlockCameraDrag` | UI区域阻止摄像机拖拽 |
### 4.2 通用效果
| 组件 | 功能 |
|------|------|
| `ButtonHoverEffect` | 悬停缩放+音效 |
| `ChooseUIButtonHoverColor` | 悬停变色 |
| `ChooseUISnapScrollRect` | 对齐滚动 |
| `SetButtonTextColor` | 文字变色 |
| `ToggleButtonController` | 开关动画 |
| `BottomBarButtonUIAnimator` | 底栏按钮动画 |
| `TechTreeButtonAnimator` | 科技树按钮动画 |
### 4.3 工具组件
| 组件 | 功能 |
|------|------|
| `ChatBubble` | 聊天气泡 |
| `DropdownRebuildTrigger` | 修复TMP下拉框布局 |
| `IconSizingUtility` | 图标缩放工具 |
| `VolumeSliderController` | 音量滑块 |
| `RoundedRectImage` | 圆角矩形 |
| `TooltipTrigger` | 提示框触发 |
---
## 5. ViewControllerManager — 全局注册表
**文件**: `TH1_UI/Core/ViewControllerManager.cs`
静态工厂,注册并管理所有 ViewController 实例。
```csharp
static class ViewControllerManager
{
static Dictionary<Type, IViewControllerInterface> _controllers;
static T Get<T>() where T : IViewControllerInterface;
static void Register<T>(T controller);
}
```
---
## 6. UIResourceController — UI资源管理
**文件**: `TH1_UI/Core/UIResourceController.cs`
```csharp
class UIResourceController
{
Dictionary<string, GameObject> _windows; // 已加载的窗口
void AddWindow(string name, GameObject go);
GameObject GetWindow(string name);
}
```
**UIResourceName**: 所有UI Prefab路径常量。
---
## 7. ESC关闭系统
**接口**: `IEscClosable`
```csharp
interface IEscClosable
{
bool CanCloseByEsc(); // 是否可ESC关闭
bool CancelMapHighlightsOrDoNothing(); // 取消高亮或不操作
}
```
通过 `PresentationManager.TryCloseCurrentByEsc()` 统一处理。

View File

@ -0,0 +1,326 @@
# 09 - 演出与动画系统
> **目录**: `TH1_Presentation/` + `TH1_Anim/` + `TH1_Core/Managers/PresentationManager.cs`
> **核心**: 队列序列器 + Fragment动画 + UnitAtomAnim
---
## 1. PresentationManager — 演出队列管理器
**文件**: `TH1_Core/Managers/PresentationManager.cs`
### 1.1 三级队列
```
_taskQueue 主队列 → 顺序执行演出任务
_taskNextFrameQueue 下帧队列 → 延迟一帧执行的任务
_taskNotCurPlayList 非当前队列 → 等到玩家回合才执行
```
### 1.2 核心流程
```
EnqueueTask(task, viewNextFrame)
├── viewNextFrame=true → 加入 _taskNextFrameQueue
└── viewNextFrame=false → 加入 _taskQueue
TryProcessNext()
├── 检查 _isBusy → 正在执行则跳过
├── 从队列取出下一个任务
├── _isBusy = true
└── task.Execute(OnTaskCompleted)
OnTaskCompleted()
├── _isBusy = false
└── TryProcessNext() → 继续下一个
CheckNextFrameQueue() → 下帧队列转移到主队列
CheckNotCurQueue() → 回合开始时转移非当前队列
TryCloseCurrentByEsc() → ESC关闭当前演出
```
### 1.3 特殊任务
```
EnqueueTaskGroupCityExp() → 城市经验动画组(特殊序列)
```
---
## 2. ISequencerTask — 任务接口
**文件**: `TH1_Presentation/Sequencer/Task/ISequencerTask.cs`
```csharp
interface ISequencerTask
{
void Execute(Action onComplete); // 执行任务,完成后回调
}
```
### 2.1 FragmentSequencerTask — 动画任务
**文件**: `TH1_Presentation/Sequencer/Task/FragmentSequencerTask.cs`
```csharp
class FragmentSequencerTask : ISequencerTask
{
// 播放动画Fragment完成后回调
void Execute(Action onComplete) {
// 添加Fragment到FragmentManager
// Fragment完成时调用onComplete
}
}
class InputSequencerTask : ISequencerTask
{
// 等待玩家输入
}
```
### 2.2 UISequencerTask — UI展示任务
**文件**: `TH1_Presentation/Sequencer/Task/UISequencerTask.cs`
```csharp
class UISequencerTask : ISequencerTask
{
// 打开ViewController等待关闭后回调
void Execute(Action onComplete) {
controller.Open();
controller.OnClosedCallback = onComplete;
}
}
```
---
## 3. FragmentManager — 动画Fragment管理器
**文件**: `TH1_Anim/FragmentManager.cs`
### 3.1 Fragment类型 (FragmentType)
```csharp
enum FragmentType {
Move, // 移动
Attack, // 单向攻击
AttackAndCounter, // 攻击+反击
AttackAndCounterDie, // 攻击+反击+阵亡
MoveKill, // 移动击杀
NotMoveKill, // 原地击杀
GridUpdate, // 格子更新(建造等)
CityExp, // 城市经验飞行
CityExpUp, // 城市经验上升
CityExpDown, // 城市经验下降
CityLevelUp, // 城市升级
Die, // 部队阵亡
CityConnectExpUp, // 城市连通经验上升
CityConnectExpDown, // 城市连通经验下降
MoveExplorer, // 探索者移动
MoveTeleport, // 传送移动
AttackAlly, // 友军技能攻击
AttackGround, // 地面技能攻击
}
```
### 3.2 FragmentFactory
```
FragmentFactory.Create(FragmentType) → FragmentBase
```
### 3.3 执行流程
```
Update()
├── 遍历 _fragments 列表
├── UpdateFragment(fragment)
│ ├── Prepare → OnStart() → Playing
│ ├── Playing → OnUpdate(progressTime)
│ ├── CheckDone() → OnFinished() → 移除
│ └── TimeOut() → 强制完成安全保护2x时长
└── OnFinishedCallback?.Invoke()
```
---
## 4. FragmentBase — 动画基类
**文件**: `TH1_Anim/Fragments/FragmentBase.cs`
```csharp
abstract class FragmentBase
{
FragmentState State; // Prepare / Playing / Finished / Wrong
float StartTime; // 开始时间
float Duration; // 持续时间
Action OnFinishedCallback;// 完成回调
abstract void OnStart(float time);
abstract void OnUpdate(float progressTime);
abstract void OnFinished();
abstract bool CheckDone(float progressTime);
bool TimeOut(float progressTime) {
return progressTime > Duration * 2; // 安全超时
}
}
```
---
## 5. 各Fragment详解
### 5.1 FragmentMove — 移动动画
```
步骤1: 播放移动动画(沿路径插值)
步骤2: 即时更新位置 + 刷新格子状态
音效: "SFX/UNIT_move"
```
### 5.2 FragmentAttackAndCounter — 攻击+反击
```
6步动画:
① 攻击者攻击(近战冲锋或投射物)
② 攻击者返回位置
③ 攻击和反击之间等待
④ 防御者反击
⑤ 防御者返回位置
⑥ 最终状态更新
```
### 5.3 FragmentAttack — 单向攻击
```
2步动画:
① 攻击者攻击动画(近战或投射物)
② 目标受伤动画(弹跳效果 + 特效)
```
### 5.4 FragmentDie — 阵亡
```
1步: UnitRenderer.Die() → 城市渲染更新 → 高亮重置
安全检查: 多重空值检查
```
### 5.5 FragmentMoveTeleport — 传送
```
步骤1: 播放雾效 → 部队消失
步骤2: 延迟 → 部队在目标位置出现(雾效+宝箱特效)
```
### 5.6 FragmentCityExp — 城市经验
```
经验投射物从源格子飞向城市
距离影响动画时长
```
---
## 6. UnitAtomAnim — 部队原子动画
**目录**: `TH1_Anim/UnitAtomAnim/`
### 6.1 原子动画类型
```csharp
enum UnitAtomAnimType {
Move, // 沿路径移动
Bounce, // 弹跳效果(先上后下)
AttackMove, // 近战冲锋(向前)
AttackMoveBack, // 近战返回(向后)
KillMove, // 击杀移动
Projectile // 投射物发射
}
```
### 6.2 UnitAnimManager — 原子动画队列
```csharp
class UnitAnimManager
{
Queue<IUnitAtomAnim> _animQueue; // 动画队列
IUnitAtomAnim _currentAnim; // 当前动画
bool _isBusy; // 忙碌标志
void EnqueueAnim(type, data); // 入队
void Update(unitMono); // 更新
void TryProcessNext(); // 处理下一个
void OnAnimCompleted(); // 完成回调
}
```
### 6.3 具体原子动画
| 动画 | 说明 |
|------|------|
| `UnitAtomAnimMove` | 沿路径点列表插值移动 |
| `UnitAtomAnimBounce` | 弹跳(上升+下降两阶段) |
| `UnitAtomAnimAttackMove` | 近战向目标冲锋 |
| `UnitAtomAnimAttackMoveBack` | 近战返回原位 |
| `UnitAtomAnimProjectile` | 投射物发射动画 |
### 6.4 动画时间配置 (AnimDataAssets)
```csharp
class AnimDataAssets : ScriptableObject
{
float BounceDownTime; // 弹跳下降时间
float BounceUpTime; // 弹跳上升时间
float AttackAnimTime; // 攻击动画时间
float AttackArrowTime; // 箭矢飞行时间
float AttackBombTime; // 炸弹飞行时间
float AttackReturnAnimTime; // 攻击返回时间
float CounterReturnAnimTime; // 反击返回时间
float BetweenAttackCounterAnimTime;// 攻击-反击间隔
float MoveAnimTime; // 移动动画时间
float ExplorerMoveDelay; // 探索者移动延迟
float AIBeforeAnimWaitTime; // AI动画前等待
float ProjectileMoveTime; // 投射物飞行时间
float ProjectileBombMoveTime; // 炸弹飞行时间
float ProjectileCityExpMoveTime; // 城市经验飞行
float ProjectileCoinMoveTime; // 金币飞行时间
float GridUpdateAnimTime; // 格子更新动画
}
```
---
## 7. 演出系统关系图
```
PresentationManager (演出队列)
├── UISequencerTask → ViewController → UI打开/关闭
└── FragmentSequencerTask
FragmentManager (Fragment队列)
├── FragmentMove
├── FragmentAttack
├── FragmentAttackAndCounter
├── FragmentDie
├── FragmentCityExp
└── ...
UnitAnimManager (原子动画队列)
├── UnitAtomAnimMove
├── UnitAtomAnimBounce
├── UnitAtomAnimAttackMove
└── UnitAtomAnimProjectile
UnitMono (Unity组件)
Sprite/Position/Animation
```

View File

@ -0,0 +1,273 @@
# 10 - 渲染系统Renderer
> **目录**: `TH1_Renderer/`
> **核心**: Map/Grid/Unit/City渲染器 + 投射物 + 特效 + 气泡
---
## 1. 渲染器一览
| 渲染器 | 文件 | 职责 |
|--------|------|------|
| `MapRenderer` | MapRenderer.cs | 地图总渲染(最大文件) |
| `GridRenderer` | GridRenderer.cs | 格子渲染(高亮/选中/移动指示) |
| `GridVFXRenderer` | GridVFXRenderer.cs | 格子视觉特效 |
| `UnitRenderer` | UnitRenderer.cs | 部队渲染(动画/状态/高亮) |
| `CityInfoRenderer` | CityInfoRenderer.cs | 城市信息渲染 |
| `BubbleRenderer` | BubbleRenderer.cs | 行动提示气泡 |
| `EffectManager` | EffectManager.cs | 特效管理器(雾/火/攻击) |
| `ProjectileManager` | ProjectileManager.cs | 投射物管理 |
| `ProjectileRenderer` | ProjectileRenderer.cs | 投射物渲染 |
| `InGameBubbleManager` | InGameBubbleManager.cs | 气泡管理器 |
---
## 2. MapRenderer — 地图总渲染
主要职责:
- 管理所有格子的渲染状态
- 协调Unit/City/Grid渲染器
- 处理地图级别的视觉更新
---
## 3. GridRenderer — 格子渲染
### 3.1 功能
- 格子高亮(选中/可移动/可攻击)
- 移动路径指示
- 领土边界渲染
- 地形可视化
---
## 4. UnitRenderer — 部队渲染
### 4.1 功能
- Sprite显示与方向控制
- 动画状态管理
- 血条/防御值显示
- 高亮效果(选中/悬停)
- 阵亡动画
### 4.2 关键子组件
**UnitMono** (`TH1_Renderer/Prefab/UnitMono.cs`):
```csharp
class UnitMono : MonoBehaviour
{
SpriteRenderer Sprite; // 主Sprite
// 血量/防御/状态 UI组件
}
```
**UnitStatusArea** (`TH1_Renderer/UnitStatusArea.cs`):
```csharp
class UnitStatusArea
{
// 显示负面状态图标
// KomeijiFear恐惧
// SkillBan技能封印
}
```
---
## 5. CityInfoRenderer — 城市信息渲染
### 5.1 CityInfoMono
```csharp
class CityInfoMono : MonoBehaviour
{
// 房屋图标
// 资源产出数值
// 城市名称
}
```
### 5.2 CityInfoHouseMono
```csharp
class CityInfoHouseMono : MonoBehaviour
{
// 单个房屋指示器
// 房屋等级/人口显示
}
```
---
## 6. BubbleRenderer — 行动提示气泡
### 6.1 气泡类型
```csharp
enum BubbleType {
Gather, // 采集
Capture, // 占领
HeroUpgrade, // 英雄升级
Upgrade, // 普通升级
Examine // 探索
}
```
### 6.2 InGameBubbleManager
管理地图上所有行动提示气泡的显示/隐藏。
```csharp
class InGameBubbleManager
{
void ShowBubble(BubbleType type, GridData grid);
void HideBubble(GridData grid);
void HideAllBubbles();
}
```
### 6.3 BubbleMono
```csharp
class BubbleMono : MonoBehaviour
{
// 点击处理器
// 气泡UI组件
}
```
---
## 7. EffectManager — 特效管理器
### 7.1 特效类型
```csharp
enum EffectTypeEnum {
Fog, // 迷雾
Fire, // 火焰
Attack // 攻击特效
}
```
### 7.2 功能
- 管理格子上的视觉特效(迷雾/火焰)
- 攻击特效播放
- 特效对象池复用
---
## 8. ProjectileManager — 投射物管理
### 8.1 投射物类型
```csharp
enum ProjectileType {
Arrow, // 箭矢
Bomb, // 炸弹
Coin, // 金币(收入动画)
Faith, // 信仰(信仰动画)
// ... 更多类型
}
```
### 8.2 运动方式
```csharp
enum ProjectileMoveType {
Straight, // 直线
Parabola, // 抛物线
HighParabola, // 高抛物线
Curved, // 曲线
Spin, // 旋转
// ...
}
```
### 8.3 ProjectileRenderer
```csharp
class ProjectileRenderer
{
// 从起点到终点的投射物动画
// 支持多种运动轨迹
// 到达目标后触发回调
}
```
---
## 9. SpriteEffectController — 特效控制器
**文件**: `Effect/SpriteEffectController.cs`
```csharp
class SpriteEffectController : MonoBehaviour
{
Material outlineMaterial; // 描边材质
Material grayScaleMaterial; // 灰度材质
Color outlineColor; // 描边颜色
float outlineWidth; // 描边宽度 (0-0.5)
float grayIntensity; // 灰度强度 (0-1)
void ApplyOutlineEffect(); // 应用描边
void ApplyGrayEffect(); // 应用灰度
void ResetToOriginal(); // 重置
}
```
**优化**: 使用 `MaterialPropertyBlock` 避免创建新材质实例。
---
## 10. RenderUpdateManager — 渲染更新管理
**文件**: `TH1_Logic/Render/RenderUpdateManager.cs`
追踪需要更新的渲染对象:
```csharp
class RenderUpdateManager // Singleton
{
void AddUnitRUList(unit); // 标记部队需刷新
void AddCityRUList(city); // 标记城市需刷新
void SetBattleRU(info); // 设置战斗渲染
void SetCenterMessageRU(msg); // 设置中心消息
// 追踪: 部队/城市/格子/科技树/UI/战斗特效
}
```
---
## 11. 渲染系统关系图
```
MapRenderer (地图总渲染)
├── GridRenderer (格子)
│ ├── 高亮/选中/移动路径
│ └── GridVFXRenderer (格子特效)
├── UnitRenderer (部队)
│ ├── UnitMono (Sprite/血条)
│ ├── UnitStatusArea (状态图标)
│ └── UnitAnimManager (动画)
├── CityInfoRenderer (城市)
│ ├── CityInfoMono (信息面板)
│ └── CityInfoHouseMono (房屋)
├── InGameBubbleManager (气泡)
│ ├── BubbleRenderer
│ └── BubbleMono
├── EffectManager (特效)
│ ├── Fog/Fire/Attack
│ └── PrefabPoolManager (对象池)
└── ProjectileManager (投射物)
└── ProjectileRenderer
├── Arrow/Bomb → 抛物线
└── Coin/Faith → 曲线飞行
```

View File

@ -0,0 +1,298 @@
# 11 - 网络与Steam
> **目录**: `TH1_Logic/Net/` + `TH1_Logic/Steam/` + `Steamworks.NET/`
> **核心**: Lobby大厅 · P2P通信 · 消息协议 · 确定性同步
---
## 1. 网络架构总览
```
┌────────────────────────────────────────┐
│ LobbyManager (门面) │
│ Init() → 根据平台选择实现 │
├────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌───────────────┐ │
│ │ ILobby接口 │ │ LobbyBase │ │
│ │ (抽象) │ │ (空实现,备用) │ │
│ └──────┬───────┘ └───────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ SteamLobbyManager │ │
│ │ (Steam平台实现) │ │
│ └──────────┬───────────────┘ │
│ │ │
│ ┌──────────▼───────────────┐ │
│ │ SimpleP2P │ │
│ │ (Steam P2P网络层) │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────┐ ┌───────────────┐ │
│ │GameNetSender │ │GameNetReceiver│ │
│ │ (消息发送) │ │ (消息接收) │ │
│ └──────────────┘ └───────────────┘ │
└────────────────────────────────────────┘
```
---
## 2. ILobby — 大厅接口
**文件**: `TH1_Logic/Net/ILobby.cs`
### 2.1 生命周期
```csharp
void Init(); // 初始化
void Update(); // 每帧更新
void Cleanup(); // 清理
void SetGameState(int); // 广播游戏状态
```
### 2.2 大厅管理
```csharp
void CreateLobby(int maxMembers, bool isPublic); // 创建房间
void JoinLobbyById(ulong lobbyId); // 加入房间
void LeaveLobby(); // 离开房间
void KickMember(ulong memberId); // 踢出玩家
```
### 2.3 大厅状态
```csharp
enum LobbyState {
None, // 无
Creating, // 创建中
Joining, // 加入中
InLobby, // 在大厅
Leaving // 离开中
}
```
### 2.4 好友系统
```csharp
Dictionary<ulong, MemberInfo> GetOnlineFriendsDict(); // 在线好友
void InviteFriend(ulong friendId); // 邀请好友
MemberInfo GetMemberInfo(ulong id); // 获取成员信息
```
### 2.5 P2P消息
```csharp
bool SendMessageToPeer(ulong target, byte[] data, bool reliable);
void BroadcastMessage(byte[] data, bool reliable);
```
---
## 3. SteamLobbyManager — Steam实现
**文件**: `TH1_Logic/Steam/SteamLobbyManager.cs`
- 实现 ILobby 接口
- 使用 Steamworks.NET SDK
- 好友列表获取
- 成员状态追踪
- Lobby元数据管理
---
## 4. SimpleP2P — P2P网络层
**文件**: `TH1_Logic/Steam/SimpleP2P.cs`
```csharp
class SimpleP2P // Singleton
{
void Initialize();
// 连接/断开回调
// Steam网络Socket管理
// 中继服务器支持
// 重试逻辑
}
```
---
## 5. 消息协议
**文件**: `TH1_Logic/Steam/SteamObjectSerializer.cs`
### 5.1 消息类型 (BaseMessage Union)
```csharp
[MemoryPackable]
[MemoryPackUnion(0, typeof(StringMessage))]
[MemoryPackUnion(1, typeof(GameStartMessage))]
[MemoryPackUnion(2, typeof(ActionConfirmMessage))]
[MemoryPackUnion(3, typeof(ActionExecuteMessage))]
// ... 共16种消息类型
public abstract partial class BaseMessage { }
```
### 5.2 核心消息类型
| 消息 | 方向 | 功能 |
|------|------|------|
| `StringMessage` | 双向 | 通用文本消息 |
| `GameStartMessage` | Host→All | 游戏开始含完整MapData |
| `ActionConfirmMessage` | 双向 | Action确认同步校验 |
| `ActionExecuteMessage` | 双向 | Action执行含Action数据 |
| `TurnEndMessage` | 双向 | 回合结束 |
| `MapConfirmMessage` | Host→All | 地图确认(校验和) |
| `ForceUpdateMessage` | Host→Client | 强制同步完整MapData |
| `ChatMessage` | 双向 | 聊天消息 |
| `HeartbeatMessage` | 双向 | 心跳 |
| `ReconnectMessage` | Client→Host | 重连请求 |
---
## 6. GameNetSender — 消息发送器
**文件**: `TH1_Logic/Steam/GameNetSender.cs`
```csharp
class GameNetSender // Singleton
{
void SendMessage(ulong target, BaseMessage msg);
void BroadcastMessage(BaseMessage msg);
// 业务方法
void ActionConfirm(params); // 发送Action确认
void ActionExecute(params); // 发送Action执行
void GameStart(MapData); // 发送游戏开始
void TurnEnd(); // 发送回合结束
// ... 20+ 消息发送方法
}
```
---
## 7. GameNetReceiver — 消息接收器
**文件**: `TH1_Logic/Steam/GameNetReceiver.cs`
```csharp
class GameNetReceiver // Singleton
{
void OnMessageReceived(ulong sender, byte[] data);
// 20+ 消息处理器
void HandleGameStart(msg);
void HandleActionConfirm(msg);
void HandleActionExecute(msg);
void HandleTurnEnd(msg);
void HandleMapConfirm(msg);
void HandleForceUpdate(msg);
void HandleChatMessage(msg);
void HandleHeartbeat(msg);
void HandleReconnect(msg);
// ...
}
```
---
## 8. SteamManager — Steam SDK封装
**文件**: `Steamworks.NET/SteamManager.cs`
```csharp
class SteamManager : MonoBehaviour // Singleton
{
static bool Initialized;
void Awake() // 初始化Steam API
void OnDestroy() // 关闭Steam API
void Update() // 每帧运行Steam回调
}
```
### 初始化检查
1. DLL版本检查
2. Packsize验证
3. Steam客户端运行检查
4. steam_appid.txt存在检查
5. 平台兼容性Windows/Linux/macOS
---
## 9. 确定性同步机制
### 9.1 Action同步
```
玩家操作 → 创建Action
ActionConfirm → 发送给所有玩家确认
所有玩家确认 → ActionExecute → 执行
MapConfirm → 定期校验MapData一致性
```
### 9.2 随机数同步
```csharp
NetData.RandomSeed → 确定性随机种子
NetData.GetRandom() → 所有客户端使用相同种子
```
### 9.3 断线重连
```
1. 客户端检测断线
2. 每2秒发送Reconnect消息
3. Host收到 → 发送ForceUpdate完整MapData
4. 客户端收到 → 恢复到最新状态
5. 10秒超时 → AI接管断线玩家
```
---
## 10. MemberInfo — 成员数据
```csharp
class MemberInfo
{
ulong Id; // Steam ID
string Name; // 显示名称
Texture2D Texture; // 头像
}
```
---
## 11. 网络时序图
```
Host Client
│ │
│ ← JoinLobby ─────────────── │
│ │
│ ── GameStartMessage ───────→ │ (含MapData)
│ │
│ ◄── HeartbeatMessage ──────► │ (每2秒)
│ │
│ ← ActionConfirm ──────────── │ (玩家操作)
│ │
│ ── ActionExecute ──────────→ │ (广播执行)
│ │
│ ── MapConfirmMessage ──────→ │ (每5秒校验)
│ │
│ ── TurnEndMessage ─────────→ │
│ │
│ [断线] │
│ │
│ ← ReconnectMessage ─────── │ (重连请求)
│ │
│ ── ForceUpdateMessage ─────→ │ (完整MapData)
```

View File

@ -0,0 +1,157 @@
# 12 - 音频系统
> **目录**: `TH1_Audio/`
> **核心**: AudioManager(单例) · BGM轮播 · SFX · 环境音
---
## 1. AudioManager — 音频管理器
**文件**: `AudioManager.cs` (670行)
### 1.1 架构
```csharp
class AudioManager // Singleton
{
AudioPlayer _musicPlayer; // 当前BGM播放器
List<AudioPlayer> _allPlayer; // SFX播放器池
Dictionary<string, AudioClip> _clips; // 缓存的音频
bool _isPlayingRotation; // BGM轮播标志
List<string> _activePlayerMusics; // 可用BGM列表
string _pendingMusicName; // 待播放音乐
}
```
### 1.2 AudioPlayer 内部类
```csharp
class AudioPlayer
{
PlayerState State; // Prepare / FadeIn / FadeOut / Playing / Finished
AudioSource Source;
float FadeInDuration;
float FadeOutDuration;
}
```
---
## 2. BGM资源列表
| BGM名称 | 关联 |
|---------|------|
| Main | 主菜单 |
| RemiliaEgyptian | 雷米莉亚/埃及 |
| SatoriIndian | 觉/印度 |
| KanakoGermany | 神奈子/德国 |
| KaguyaFrench | 辉夜/法国 |
| ReimuNorway | 灵梦/挪威 |
| ByakurenBritish | 白莲/英国 |
| MikoPersian | 神子/波斯 |
| ZanmuByzantine | 残梦/拜占庭 |
| Story | 故事模式 |
---
## 3. SFX音效列表
| 类别 | 音效 |
|------|------|
| **UI** | UI_buttonHover, UI_buttonClick |
| **部队** | UNIT_click, UNIT_bomb, UNIT_archer, UNIT_hurt, UNIT_move |
| | UNIT_attack, UNIT_attack_arrow, UNIT_attack_bomb |
| | UNIT_levelup, UNIT_capture, UNIT_heal, UNIT_die |
| | UNIT_treasure, UNIT_born |
| **环境** | ENV_sea, ENV_forest |
| **城市** | CITY_exp, CITY_levelup |
| **玩家** | PLAYER_coin |
| **建造** | GRID_build |
| **结果** | MATCH_win, MATCH_lose |
---
## 4. 核心方法
| 方法 | 功能 |
|------|------|
| `Init()` | 初始化音频资源 |
| `PlayMusic(name)` | 播放BGM带淡入淡出 |
| `PlayAudio(name)` | 播放SFX |
| `PlayMusicDelayed(name)` | 当前BGM结束后播放 |
| `StartBgmRotation()` | 开启BGM轮播 |
| `StopBgmRotation()` | 停止BGM轮播 |
| `UpdateActivePlayerMusics()` | 更新可用BGM基于已遭遇文明 |
| `CalculateAndPlayAmbient()` | 根据地形播放环境音 |
---
## 5. BGM轮播机制
```
StartBgmRotation()
├── 收集已遭遇文明的BGM → _activePlayerMusics
├── 随机选择一首
├── PlayMusic(selected)
└── 播放完成 → 选择下一首 → 循环
UpdateActivePlayerMusics()
├── 检查已遭遇的文明
├── 添加对应文明BGM到列表
└── 去重
```
---
## 6. 辅助组件
### 6.1 SFXComponent — 抽象基类
```csharp
abstract class SFXComponent : MonoBehaviour
{
// 音效播放模板
}
```
### 6.2 ButtonSFX — 按钮音效
```csharp
class ButtonSFX : SFXComponent, IPointerEnterHandler, IPointerClickHandler
{
void OnPointerEnter() → Play("SFX/UI_buttonHover");
void OnPointerClick() → Play("SFX/UI_buttonClick");
}
```
### 6.3 AudioClipConfig
```csharp
class AudioClipConfig : MonoBehaviour
{
List<AudioClip> Clips; // 自定义音频列表
}
```
---
## 7. 音频播放流程
```
播放请求
AudioManager.PlayMusic("RemiliaEgyptian")
├── 从 _clips 缓存查找
│ └── 未命中 → Resources.Load → 缓存
├── 当前BGM淡出 (FadeOut)
├── 新BGM淡入 (FadeIn)
│ └── AudioPlayer.State = FadeIn → Playing
└── 播放完成
├── _isPlayingRotation → 选择下一首
└── _pendingMusicName → 播放排队音乐
```

View File

@ -0,0 +1,289 @@
# 13 - 配置与数据资产
> **目录**: `TH1_Config/` + `TH1_DataAssetsScript/` + `TH1_Instance/`
> **核心**: Excel→C#生成 · ScriptableObject · 全局资产表
---
## 1. ConfigManager — 配置管理器
**文件**: `TH1_Logic/Config/ConfigManager.cs`
```csharp
class ConfigManager // Singleton
{
GameConfig Config; // 运行时游戏设置
VersionConfig VersionCfg; // 版本信息
ColorConfig ColorConfig; // 颜色配置
void Init() {
// 加载 game_cfg.json带备份恢复
// 路径: Application.persistentDataPath + "/../Config/game_cfg.json"
}
void InitExcelConfig() {
// 反射扫描所有 ExcelConfigBase 子类
// 从 Resources/ExcelConfig/GenerateBytes/ 加载
// 调用 Init() + AfterInit()
}
void Update() {
// 每秒自动保存(脏标记检查)
}
}
```
### 1.1 GameConfig — 游戏设置
```csharp
class GameConfig // Serializable
{
MultilingualType MultilingualType; // 语言 (默认:None=自动)
float MusicVolume; // 音乐音量 (默认:0.5)
float AudioVolume; // 音效音量 (默认:0.5)
bool ShowReminder; // 提醒 (默认:true)
bool KeyMomentEnabled; // 关键时刻 (默认:true)
bool BgmContinuousPlay; // BGM连续播放 (默认:false)
bool IsChanged; // 脏标记
void MarkSaved(); // 保存后清除脏标记
}
```
### 1.2 VersionConfig — 版本管理
```csharp
class VersionConfig : ScriptableObject
{
uint CurVersionId;
List<VersionInfo> Versions;
}
class VersionInfo // Serializable
{
uint MajorVersion, MinorVersion, PatchVersion, FourthVersion;
string Description;
// VersionId = Major*1000000 + Minor*10000 + Patch*100 + Fourth
// FullVersion = "1.2.3" 或 "1.2.3a"
}
```
---
## 2. Excel配置生成 (TH1_Config)
### 2.1 ExcelConfigBase — 基类
```csharp
abstract class ExcelConfigBase
{
abstract void Init(byte[] data); // MemoryPack反序列化
virtual void AfterInit() { } // 后处理
}
```
### 2.2 已生成的配置
| 配置类 | 文件 | 内容 |
|--------|------|------|
| `AIConfig` | AIConfig.cs | AI行为树节点参数 |
| `GeoDesc` | GeoDesc.cs | 地理特征描述 |
| `Moment` | Moment.cs | 历史时刻事件 |
#### AIConfig
```csharp
class AIConfig {
int Id; // 配置ID
int AIConfigId; // AI组ID
int Order; // 序列号
string Name; // 节点名 ("SelectTarget", "AttackCity")
string[] NodeParams; // 参数数组
}
```
#### GeoDesc
```csharp
class GeoDesc {
int Id;
string BigClass; // 资源大类 ("Mineral", "Forest")
string SmallClass; // 子类
string GeoName; // 地貌名
CivEnum CivEnum; // 关联文明
string[] NearbyCity; // 附近城市
string GeoDescStr; // 描述文本
}
```
#### Moment
```csharp
class Moment {
int Id;
string MomentSubType; // 事件子类型
int BigId, MediumId, SmallId; // 层级ID
string MomentMainType; // 主类型
string Title, tmpDesc; // 标题和描述
}
```
---
## 3. DataAssets — ScriptableObject数据资产
**目录**: `TH1_DataAssetsScript/` (24个文件)
### 3.1 核心资产
| 资产类 | 功能 | 关键数据 |
|--------|------|---------|
| **UnitTypeDataAssets** | 部队类型定义 | 40+ UnitType, GiantType |
| **PlayerDataAssets** | 文明/势力 | 9 CivEnum, 9 ForceEnum |
| **SkillDataAssets** | 技能定义 | 技能描述/颜色/视图类型 |
| **TechDataAssets** | 科技树 | 科技节点/前置/效果 |
| **ActionDataAssets** | 行为定义 | 行为名/费用/图标 |
| **AnimDataAssets** | 动画时间 | 所有动画时长参数 |
### 3.2 辅助资产
| 资产类 | 功能 |
|--------|------|
| **CivDataAssets** | 文明属性和奖励 |
| **ColorDataAssets** | 配色方案 |
| **CultureCardDataAssets** | 文化卡定义 |
| **DiplomacyDataAssets** | 外交关系规则 |
| **GeoDataAssets** | 地理特征 |
| **GridObjectDataAssets** | 格子对象(资源/奇迹) |
| **HeroDataAssets** | 英雄属性 |
| **HintDataAssets** | 提示消息 |
| **LibraryDataAssets** | 百科条目 |
| **MobilityDataAssets** | 移动力定义 |
| **MomentDataAssets** | 历史时刻 |
| **ProjectileTypeDataAssets** | 投射物类型 |
| **ScenarioDataAssets** | 场景/战役 |
| **StoryDataAssets** | 故事内容 |
| **TextDataAssets** | 本地化文本 |
| **UICenterMessageDataAssets** | 中心消息 |
| **PlayerTaskDataAssets** | 玩家任务 |
### 3.3 通用模式
每个DataAssets都遵循相同模式
```csharp
class XxxDataAssets : ScriptableObject
{
List<XxxInfo> InfoList; // 数据列表
Dictionary<KeyType, XxxInfo> _infoDict; // 字典缓存
bool GetInfo(KeyType key, out XxxInfo info); // 查找方法
void RefreshDict(); // 初始化字典
}
```
---
## 4. Table — 全局资产注册表
**文件**: `TH1_Instance/Table.cs`
```csharp
class Table // Singleton
{
TechDataAssets TechDataAssets;
ActionDataAssets ActionDataAssets;
UnitTypeDataAssets UnitTypeDataAssets;
SkillDataAssets SkillDataAssets;
PlayerDataAssets PlayerDataAssets;
CivDataAssets CivDataAssets;
DiplomacyDataAssets DiplomacyDataAssets;
ProjectileTypeDataAssets ProjectileTypeDataAssets;
AnimDataAssets AnimDataAssets;
// ... 100+ 引用
}
```
所有系统通过 `Table.Instance.XxxDataAssets` 访问数据资产。
---
## 5. 其他全局实例
### 5.1 DebugCenter
```csharp
class DebugCenter
{
bool DebugMode; // 调试模式
bool DebugNoAI; // 禁用AI
bool DebugSelfPlayerAllSight; // 全视野
}
```
### 5.2 Timer — 延时调度
```csharp
class Timer // Singleton
{
void TimerRegister(target, method, delay, message);
// 延迟执行回调
}
```
---
## 6. ResourceCache — 资源缓存
**目录**: `TH1_Resource/`
### 6.1 SpriteCache
缓存 50+ Sprite资源
- 地形Ground, Forest, Mountain, Water, Ocean
- 道路9种道路变体 + 水上道路
- 部队指示器Self/Enemy
- 科技树Complete/Locked/Available
- 格子特效Die, Heal, Damage, Treasure等
- 特殊角色Meiling sleep, Kanako sit, Utsuho boom
### 6.2 AnimCache
缓存动画GridVFX, Hint, UI面板 的各种动画Clip
### 6.3 MatCache
缓存材质:
- WhiteOverlay白色覆盖
- Glow发光
- Default默认
- GradientBG_Green/Blue/Red渐变背景
---
## 7. 配置数据流
```
Excel表格 (设计时)
│ ExcelExport工具
MemoryPack二进制 (Resources/ExcelConfig/GenerateBytes/)
│ ConfigManager.InitExcelConfig()
C#配置类 (AIConfig, GeoDesc, Moment)
▼ 运行时访问
ScriptableObject (设计时, Unity编辑器)
│ Table.Instance
DataAssets (UnitType, Skill, Tech, Action...)
▼ 运行时访问
JSON文件 (持久化)
│ ConfigManager.Init()
GameConfig (音量/语言/设置)
```

View File

@ -0,0 +1,410 @@
# 14 - 辅助系统
> 多语言 · 成就 · 漫画 · 数据采集 · 文化卡 · 英雄任务 · Wiki · 对局配置 · 输入 · 对象池 · 历史时刻
---
## 1. 多语言系统 (Multilingual)
**目录**: `TH1_Logic/Multilingual/`
### 1.1 支持语言 (10种)
```
ZH 简体中文
TDZH 繁体中文
EN 英文
JP 日文
KR 韩文
RU 俄文
ES 西班牙文
PT 葡萄牙文
FR 法文
```
### 1.2 MultilingualManager
```csharp
class MultilingualManager // Singleton
{
void GetMultilingualText(key) → string; // 获取翻译文本
void ChangedMultilingual(type); // 切换语言
MultilingualType GetSystemLanguage(); // 检测系统语言
MultilingualType GetLanguageByString(str); // 字符串转语言枚举
}
```
### 1.3 嵌套字符串引用
```
支持 {KEY} 格式嵌入其他翻译:
"WELCOME_MSG" = "欢迎来到{GAME_NAME}!"
→ 正则解析并递归替换
```
### 1.4 MultilingualTextMono
```csharp
class MultilingualTextMono : MonoBehaviour
{
// 自动更新TextMeshPro文本
// 支持参数替换
// 语言变更时自动刷新
// 字体组绑定
}
```
---
## 2. 成就系统 (Achievement)
**目录**: `TH1_Logic/Achievement/`
### 2.1 架构
```
AchievementDataManager (Singleton)
├── LoadAchievement() // 加载JSON
├── SaveAchievementData() // 保存JSON
├── OnTurnStart() // 回合检查
├── OnKillUnit() // 击杀检查
└── OnGameEnd() // 结局检查
AchievementAsset (ScriptableObject)
├── AchievementData
└── AchievementItem[]
├── CheckConditions() // 检查条件
└── GetConditionProgress() // 获取进度
AchievementFactory
└── GetAchievementCondition(type) // 工厂创建条件
```
### 2.2 层级ID系统
```
BigID → 大类 (如"战斗成就")
SmallID → 小类 (如"击杀敌人")
InternalID → 具体条件 (如"击杀100个敌人")
```
### 2.3 持久化
- JSON序列化
- 向后兼容旧版本数据
- 事件驱动的检查触发
---
## 3. 漫画/剧情系统 (Comic)
**目录**: `TH1_Logic/Comic/`
### 3.1 数据结构
```
ComicAsset (ScriptableObject)
└── ComicSheet[]
└── ComicData[]
├── ComicSubItem[] // 子元素(角色/道具)
├── ComicBackground // 背景
├── ComicDialogLayoutParam // 对话框布局
└── ComicAction[] // 动画行为
```
### 3.2 ComicControl — 状态机
```csharp
enum ComicState {
Prepared, // 准备
Playing, // 播放中
Pausing, // 暂停
Ended // 结束
}
```
### 3.3 13种漫画行为 (ComicAction)
```
Fade 淡入/淡出
Slide 滑动
Text 文字显示
Wait 等待
Move 移动
Scale 缩放
Rotate 旋转
Color 变色
Sound 音效
Effect 特效
Dialog 对话
Choice 选择
Custom 自定义
```
---
## 4. 数据采集系统 (Collect)
**目录**: `TH1_Logic/Collect/`
### 4.1 采集事件类型
```csharp
class DamageCollectData { ... } // 伤害数据
class AddUnitCollectData { ... } // 创建部队
class TransformUnitCollectData { ... } // 转化部队
class LearnTechCollectData { ... } // 学习科技
class OnTurnStartCollectData { ... } // 回合开始
class MatchGameEndCollectData { ... } // 游戏结束
class PlayerGameEndCollectData { ... } // 玩家结局
```
### 4.2 CollectManager
```csharp
class CollectManager // Singleton
{
void OnDamageCollect(data);
void OnAddUnitCollect(data);
void LearnTechsCollect(data);
void OnTurnStartCollect(data);
void MatchGameEndCollect(data);
}
```
---
## 5. 文化卡系统 (CultureCard)
**目录**: `TH1_Logic/CultureCard/`
### 5.1 工厂模式
```csharp
class CultureCardFactory
{
static CultureCardBase GetCultureCardBase(type);
// 反射查找 + 字典缓存
}
```
### 5.2 14种文化卡
每种卡继承 `CultureCardBase`,实现不同的游戏效果:
- 英雄消费折扣
- 购买大型部队
- 解锁资源
---
## 6. 英雄任务系统 (HeroTask)
**目录**: `TH1_Logic/HeroTask/`
```
HeroTaskManager (Singleton)
├── Init() // 从配置加载
├── GetHeroTaskContent() // 获取任务内容
└── Map: GiantType → Task
HeroTaskItem
├── 关联英雄 (GiantType)
├── 任务内容 (HeroTaskContent)
└── GetCopyHeroTaskContentBase()
HeroTaskFactory
└── GetHeroTaskContentBase() // 反射工厂
```
---
## 7. Wiki系统
**目录**: `TH1_Logic/WiKi/`
```csharp
class WikiData : ScriptableObject
{
List<WikiItem> Items;
void AddWikiItem(item);
void Refresh();
}
class WikiItem
{
int Type; // 3种Wiki类型
List<DescItem> Descs; // 4种描述类型
// 提示系统集成
}
```
---
## 8. 对局配置 (MatchConfig)
**目录**: `TH1_Logic/MatchConfig/`
### 8.1 胜利条件
```csharp
// 5种结算类型
class MatchSettlementLogicFactory {
IMatchSettlement Create(type);
}
enum SettlementType {
Domination, // 统治胜利
Perfect, // 完美胜利
Tutor, // 教程
Story, // 故事
Creative // 创造模式
}
```
### 8.2 玩家任务
```csharp
// 9种任务逻辑
enum TaskType {
Survive, // 存活
OtherDie, // 敌人阵亡
ScoreWin, // 分数胜利
ScoreValue, // 达到分数
HasCityCount, // 城市数量
HasUnitCount, // 部队数量
HasLevelCityCount, // 等级城市数量
HasCoinCount, // 金币数量
HasExploreCount // 探索数量
}
```
---
## 9. 输入系统 (Input)
**目录**: `TH1_Logic/Input/`
### 9.1 InputConfig
```csharp
class InputConfig // MemoryPackable
{
List<InputKeyConfig> KeyConfigs;
void SetInputKeyConfig(action, key);
InputKeyConfig GetInputKeyConfig(action);
bool CheckConfigConflict(); // 冲突检查
}
```
### 9.2 InputLogic
```csharp
class InputLogic
{
void Update(); // 每帧输入检测
void OnTileClicked(pos); // 格子点击
void OnGridInfoAction(grid); // 格子信息
void OnTechTreeAction(); // 科技树
void OnHeroAction(); // 英雄操作
// WASD摄像机控制
// 调试快捷键
}
```
---
## 10. 对象池 (PrefabPool)
**目录**: `TH1_Logic/PrefabPool/`
```csharp
class PrefabPoolManager // Singleton
{
GameObject GetGameObject(PrefabType type); // 获取(创建或复用)
void ReturnGameObject(PrefabType type, go); // 归还
// 每种类型最多30个缓存对象
}
// 10种Prefab类型
enum PrefabType {
Fog, Treasure, Hurt, Fire, Die, ...
}
```
---
## 11. 聊天系统 (Chat)
```csharp
class ChatManager // Singleton
{
void SendChatItem(text); // 发送消息
void ReceiveChatItem(item); // 接收消息
// MemoryPackable → 网络传输
// 时间戳消息
}
```
---
## 12. 游戏录像 (GameRecord)
```csharp
class GameRecordManager // Singleton
{
List<GameRecord> GetSortGameRecordList(filters);
void AddRecord(record);
void RefreshGameRecord();
// 按GameMode/Force/PlayerCount筛选
// 按score/turn/time排序
// 文件持久化
}
```
---
## 13. 地图记录 (MapRecord)
```csharp
class MapRecordManager // Singleton
{
void SaveMapRecord(MapData); // 保存快照
MapData LoadMapRecord(); // 加载快照
// MemoryPack序列化
}
```
---
## 14. OSS上传 (Oss)
**目录**: `TH1_Logic/Oss/`
```
OssManager (Singleton)
├── UploadMapData() // 上传游戏数据
├── UploadGameDataAsync() // 异步上传
└── UploadCollectData() // 上传采集数据
StsTokenService
└── RequestStsTokenAsync() // 获取STS临时令牌
OssUploadService
└── UploadFileAsync() // Multipart上传(≤2MB)
```
---
## 15. 崩溃上报 (CrashSight)
```csharp
class CrashSightManager
{
void Initialize() {
CrashSightAgent.ConfigCrashReporter(1);
CrashSightAgent.ConfigCrashServerUrl("pc.crashsight.qq.com");
}
}
```

View File

@ -0,0 +1,224 @@
# 15 - 服务端Game Upload Function
> **目录**: `Tools/OSS/game-upload-function/`
> **技术栈**: Node.js · 阿里云函数计算 · Steam Web API · 阿里云 STS · OSS · Tablestore
> **端口**: 9000
---
## 1. 服务概述
运行在阿里云函数计算上的 HTTP 服务,为游戏客户端提供安全的 OSS 文件上传凭证。
**核心流程**: Steam身份验证 → STS临时令牌签发 → Post Policy生成 → 缓存管理
---
## 2. 接口规范
### 2.1 请求
```
POST /
Content-Type: application/json
最大请求体: 1024字节
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `steamId` | string | ✅ | 玩家 Steam ID |
| `authTicket` | string | ✅ | Steam Auth Ticket (十六进制) |
| `version` | string | ❌ | 客户端版本号 |
| `type` | string | ❌ | 上传类型: `ossdata`(默认) / `collectdata` |
### 2.2 成功响应 (200)
```json
{
"accessKeyId": "STS.xxx",
"accessKeySecret": "xxx",
"securityToken": "xxx",
"endpoint": "oss-cn-shanghai.aliyuncs.com",
"bucket": "xxx",
"objectKey": "1.2.3/76561198xxx/1234567890.dat",
"policy": "base64...",
"signature": "hmac-sha1...",
"expiresIn": 900
}
```
### 2.3 错误响应
| 状态码 | 原因 |
|--------|------|
| 400 | 缺少 steamId 或 authTicket |
| 403 | Steam 身份验证失败 |
| 405 | 非 POST 请求 |
| 413 | 请求体超过 1024 字节 |
| 500 | 服务器内部错误 |
---
## 3. 核心流程
```
客户端POST请求
[1] 查询 Tablestore 缓存
├─ 命中(版本匹配 + 未过期 + STS有效期>2分钟
│ └── 直接返回缓存令牌
└─ 未命中
[2] Steam Web API 验证 AuthTicket
│ https://api.steampowered.com/ISteamUserAuth/
│ AuthenticateUserTicket/v1/
│ 最多重试3次每次间隔1秒
├─ 验证失败 → 返回 403
└─ 验证通过
[3] 申请 STS 临时令牌
│ 阿里云 AssumeRole API
│ 有效期: 15分钟 (900秒)
│ 权限: 仅 oss:PutObject 指定路径
[4] 生成 Post Policy + HMAC-SHA1 签名
│ 限制: objectKey精确匹配
│ 限制: 文件大小 1B - 3MB
[5] 存入 Tablestore 缓存
│ 键: {steamId}#{type}
│ 含版本号、签发时间、过期时间
返回令牌给客户端
```
---
## 4. OSS上传路径规则
### 4.1 ossdata 类型
```
有版本号: {version}/{steamId}/{timestamp}.dat
无版本号: common/{steamId}/{timestamp}.dat
```
### 4.2 collectdata 类型
```
有版本号: collect/{version}/{steamId}/{timestamp}.dat
无版本号: collect/common/{steamId}/{timestamp}.dat
```
---
## 5. 缓存机制
### 5.1 存储
使用阿里云 Tablestore表: `Players`,主键: `PlayerId`)。
### 5.2 缓存命中条件(全部满足)
| 条件 | 说明 |
|------|------|
| 版本号匹配 | `null` 视为老版本,需严格匹配 |
| 签发时间 < 5分钟 | `Date.now() - issuedAt < 5min` |
| STS有效期 > 2分钟 | `stsExpireAt - Date.now() > 2min` |
### 5.3 Tablestore字段
| 字段 | 说明 |
|------|------|
| PlayerId (主键) | `{steamId}#{type}` |
| accessKeyId/Secret/Token | STS临时凭证 |
| endpoint/bucket/objectKey | OSS信息 |
| policy/signature | Post Policy |
| issuedAt | 签发时间戳(ms) |
| stsExpireAt | STS过期时间戳(ms) |
| version | 客户端版本号 |
---
## 6. 安全设计
| 措施 | 说明 |
|------|------|
| **Steam验证** | 缓存未命中时强制验证Ticket + SteamID比对 |
| **最小权限STS** | 每个令牌仅限写入带时间戳的精确路径 |
| **Post Policy签名** | 限制文件大小(≤3MB)和目标路径 |
| **版本隔离** | 不同版本使用不同路径,令牌不可跨版本复用 |
| **请求限制** | 请求体≤1024字节防止大请求攻击 |
| **CORS** | 允许所有源 (`*`)仅允许POST |
---
## 7. 环境变量
| 变量 | 说明 |
|------|------|
| `ACCESS_KEY_ID` | 阿里云 AccessKeyId |
| `ACCESS_KEY_SECRET` | 阿里云 AccessKeySecret |
| `ROLE_ARN` | STS RAM角色ARN |
| `BUCKET_NAME` | OSS Bucket名称 |
| `STEAM_API_KEY` | Steam Web API Key |
| `STEAM_APP_ID` | Steam App ID |
| `OTS_ENDPOINT` | Tablestore Endpoint |
| `OTS_INSTANCE` | Tablestore 实例名 |
---
## 8. 关键参数
| 参数 | 值 |
|------|----|
| 服务端口 | 9000 |
| 最大请求体 | 1024字节 |
| 最大上传文件 | 3MB |
| STS有效期 | 900秒 (15分钟) |
| 缓存有效期 | 5分钟 |
| Steam API超时 | 15秒 |
| Steam API重试 | 3次 |
---
## 9. 依赖
```json
{
"@alicloud/pop-core": "^1.8.0", // 阿里云SDK
"tablestore": "^5.6.3" // Tablestore SDK
}
```
---
## 10. 客户端上传流程 (Unity侧)
```
Unity客户端
├── OssManager.UploadMapData()
├── StsTokenService.RequestStsTokenAsync()
│ └── POST → game-upload-function → 获取STS令牌
└── OssUploadService.UploadFileAsync()
└── Multipart Form-Data POST → OSS
├── key = objectKey
├── policy = base64Policy
├── OSSAccessKeyId = accessKeyId
├── signature = signature
├── x-oss-security-token = securityToken
└── file = 游戏数据(≤2MB)
```

View File

@ -0,0 +1,270 @@
# 16 - AI训练管线
> **目录**: `TH1_Logic/AITrain/`
> **核心**: ONNX推理 · 训练数据录制 · 状态/行为编码
> **预处理**: `#if ENABLE_TRAIN` / `#if ENABLE_AIMODEL`
---
## 1. 系统概述
TH1 包含完整的 AI 强化学习训练管线,支持:
- 游戏过程中录制训练数据(状态/合法行为/选择/奖励)
- 导出 JSONL 格式训练文件
- 加载 ONNX 模型进行在线推理
---
## 2. ModelInference — ONNX推理引擎
**文件**: `ModelInference.cs`
### 2.1 核心参数
```csharp
const int STATE_DIM = 802; // 游戏状态向量维度
const int ACTION_DIM = 8; // 行为编码维度
```
### 2.2 模型管理
```csharp
class ModelInference // Singleton
{
InferenceSession session; // ONNX Runtime会话
void LoadModel(
string modelPath = "AIModel/cql_model", // Resources路径
bool useGPU = false // 可选CUDA加速
);
void UnloadModel();
}
```
### 2.3 推理算法
```csharp
int Predict(float[] state, List<List<float>> legalActions)
{
// 1. 创建 (1, 802) 输入张量
// 2. 运行推理 → 获得 (1, 8) 输出
// 3. 对每个合法行为计算欧几里得距离
// 4. 返回距离最小的行为索引
// 边界情况:
// session == null → return -1
// state.Length != 802 → return -1
// legalActions.Count == 0 → return -1
// legalActions.Count == 1 → return 0
}
```
---
## 3. TrainingState — 状态编码器
**文件**: `TrainingState.cs` (21.9 KB)
### 3.1 状态向量 (802维)
```
┌─────────────────────────────────────────┐
│ 全局状态 (2维) │
│ [0] 回合进度: min(turn/100, 1) │
│ [1] 玩家索引: playerIndex/10 │
├─────────────────────────────────────────┤
│ 玩家状态 (40维 = 10玩家 × 4) │
│ 每个玩家: │
│ [0] 领土比: territoryCount/(h×w) │
│ [1] 视野比: sightCount/(h×w) │
│ [2] 金币: min(coin/50, 1) │
│ [3] 分数: score/maxScore │
├─────────────────────────────────────────┤
│ 部队状态 (400维 = 80部队 × 5) │
│ 每个可见部队: │
│ [0] 部队索引: unitIndex/100 │
│ [1] 归属: 1=自己, 0=其他 │
│ [2] 格子索引: gridIndex/500 │
│ [3] 类型: typeIndex/100 │
│ [4] 血量比: currentHp/maxHp │
├─────────────────────────────────────────┤
│ 城市状态 (160维 = 40城市 × 4) │
│ 每个可见城市: │
│ [0] 城市索引: cityIndex/100 │
│ [1] 归属: 1=自己, 0=其他 │
│ [2] 格子索引: gridIndex/500 │
│ [3] 等级: min((lv+exp/(lv×2))/10, 1) │
├─────────────────────────────────────────┤
│ 格子状态 (200维 = 100格子 × 2) │
│ 每个可见资源/地物格子: │
│ [0] 格子索引: gridIndex/500 │
│ [1] 资源类型: typeId/scale │
└─────────────────────────────────────────┘
```
### 3.2 行为编码 (8维)
```csharp
class AIActionPacker
{
// 将Action编码为8个浮点数
// 9个索引压缩到8维: ActionId + 7个实体索引
// 限制:
// ActionId < 500
// Players < 10
// Units < 80
// Cities < 40
// Grids < 500
// 归一化: (index + 1) / max → [0, 1]
// 解码: round(float * max) - 1
}
```
### 3.3 核心方法
| 方法 | 功能 |
|------|------|
| `GetMapState(map, player)` | 生成802维状态向量 |
| `GetActionBitCodec(action, params)` | 编码单个行为 → 8维向量 |
| `GetActionFromBitCodec(vector, map)` | 解码8维向量 → 行为 |
| `GetAllActionBitCodec(map, player)` | 生成所有合法行为编码 |
| `GetMapScore(map, player)` | 计算奖励值 |
### 3.4 奖励计算
```csharp
float GetMapScore(MapData, PlayerData)
{
return (GetUnitsScore() + GetCityScore()) / 5;
}
float GetUnitsScore()
{
// 友军: + (range + damage + defense)
// 敌军: - (range + damage + defense)
}
float GetCityScore()
{
// 友军: + (level + territory)
// 敌军: - (level + territory)
}
```
---
## 4. TrainingDataRecorder — 训练数据录制
**文件**: `TrainingDataRecorder.cs`
### 4.1 数据结构
```csharp
class TrainingData
{
float[] State; // 802维状态
AllActions[] Actions; // 所有合法行为
float[] SelectedAction; // 选择的行为(8维)
float Reward; // 奖励值
bool Done; // 回合结束标志
}
```
### 4.2 录制流程
```
每个Action执行时:
TrainingDataRecorder.RecordStep(
playerID,
state, // 802维
validActions, // N × 8维
selectedAction, // 8维
reward // float
)
→ 存入 _episodeData[playerID]
游戏结束时:
SaveEpisode()
→ 标记最后一步 Done=true
→ 导出 JSONL 文件
```
### 4.3 输出格式
```
路径: F:\TrainData\TrainingData\
文件名: episode_{timestamp}_{uniqueId}_{playerId}.jsonl
编码: UTF-8 with BOM
```
```jsonl
{"State":[0.15,0.2,...802个值...],"Actions":[{"data":[0.1,...8个值...]},...],"SelectedAction":[0.3,...8个值...],"Reward":1.5,"Done":false}
{"State":[...],"Actions":[...],"SelectedAction":[...],"Reward":2.0,"Done":true}
```
---
## 5. 训练管线全流程
```
┌─────────────────────────────────────────┐
│ 游戏运行 (Unity) │
│ │
#if ENABLE_TRAIN │
│ ┌─────────────────────────────────┐ │
│ │ TrainingState.GetMapState() │ │
│ │ → 802维状态向量 │ │
│ └──────────┬──────────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────────┐ │
│ │ TrainingState.GetAllActionBitCodec│ │
│ │ → 合法行为列表(N × 8维) │ │
│ └──────────┬──────────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────────┐ │
│ │ AI/玩家选择行为 │ │
│ │ → 选中行为(8维) │ │
│ └──────────┬──────────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────────┐ │
│ │ TrainingDataRecorder.RecordStep()│ │
│ │ → 存入内存 │ │
│ └──────────┬──────────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────────┐ │
│ │ 游戏结束 → SaveEpisode() │ │
│ │ → 导出 JSONL │ │
│ └──────────────────────────────────┘ │
#endif
└──────────────┬──────────────────────────┘
▼ (离线训练)
┌─────────────────────────────────────────┐
│ Python 训练脚本 (train.py) │
│ 读取 JSONL → CQL 算法训练 │
│ → 导出 ONNX 模型 │
└──────────────┬──────────────────────────┘
▼ (在线推理)
┌─────────────────────────────────────────┐
#if ENABLE_AIMODEL │
│ ModelInference.LoadModel("cql_model") │
│ → Predict(state, legalActions) │
│ → 返回最优行为索引 │
#endif
└─────────────────────────────────────────┘
```
---
## 6. 条件编译标志
| 标志 | 功能 |
|------|------|
| `ENABLE_TRAIN` | 启用训练数据录制 |
| `ENABLE_AIMODEL` | 启用ONNX模型推理 |
正常游戏构建中两者均关闭,仅在训练/测试构建中启用。

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 42b7753da8981504ca380fe9d3a7b425
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 8b3c4bc3799469f44a5750e1e47f7d95
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 0da04344d6aa64f9aa4d2f1483917086
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 7519c6cc721bd9640830e41500675444
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: db1456988a53c254b9987e6a611c48ac
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: