决策系统综合指南
本文档由以下文件合并生成 (2026-01-09)
🧠 通用加权决策系统 (Unified Weighted Decision System)
本文档旨在抽�?Project Vampirefall 中多个核心系统的底层逻辑,构建一�?*通用的、基于上下文的加权选择�?(Context-Aware Weighted Selector)**�? 通过统一仇恨 (Aggro)、塔防索�?(Tower Targeting) �?肉鸽抽卡 (Perk Drafting) 的决策代码,我们可以减少重复逻辑,提高系统的可维护性和扩展性�?1. 系统概述 (Overview)
在游戏中,我们经常面临这样的问题�?“从一堆选项中,根据当前情况,选择最合适的一个(或几个)。�?- 仇恨系统: 从一堆怪物中,选出威胁最大的攻击�?
- 塔防索敌: 从射程内的敌人中,选出价值最高的击杀�?
- Perk 抽取: 从几百个强化词条中,选出最适合玩家当前流派的展示�?
Input -> Scoring -> Selection 的模式�?
2. 核心架构 (Core Architecture)
2.1 流程�?(Flowchart)
2.2 核心组件 (Components)
-
候选人 (Candidate
T): 待选择的对象(Enemy, Tower, PerkData)�? -
上下�?(Context
C): 决策时的环境信息(距离、玩�?HP、已拥有�?Tags)�? -
评分�?(Scorer
IScorer<T, C>): 一个独立的逻辑单元,负责计算单项分数�? - 选择�?(Selector): 负责运行所有评分器并汇总结果�?
3. 评分器策略库 (Scorer Strategy Library)
通过组合不同的评分器,我们可以“拼装”出不同�?AI 行为,而无需重写代码�?3.1 基础评分�?
| 评分器名�? | 逻辑描述 | 适用场景 |
|---|---|---|
| DistanceScorer | 距离越近,分数越�?(线性或指数衰减)�? | 仇恨(近战�?、塔�?近程�? |
| HealthScorer | 生命值越低,分数越高 (斩杀逻辑)�? | 刺客型怪物、收割型防御�? |
| TagSynergyScorer | 拥有相同标签 (Tag) 数量越多,分数越高�? | Perk 抽取、战利品生成 |
| FixedPriorityScorer | 基于硬编码的优先�?(Boss > Elite > Minion)�? | 塔防(优先打大�? |
| MemoryScorer | 之前互动�?(造成伤害/被选中) 则加分�? | 仇恨(反击逻辑)、连击系�? |
3.2 评分公式
标准的归一化评分公式:- Multiplier (乘区): 用于调整权重(例如:刺客怪的
HealthScorer权重�?5.0,�?DistanceScorer权重�?0.5)�? - FlatBonus (加算): 用于强制覆盖(例如:嘲讽状态直�?+10000 分)�?
4. 实战应用配置 (Configuration Examples)
Case A: 怪物仇恨 (Aggro System)
- 目标: 选一个攻击目标�?
- 选择模式:
Top 1(确定�?�? - 配置:
DamageReceivedScorer: 权重 1.0 (谁打我,我打�?�?DistanceScorer: 权重 2.0 (谁离我近,我打谁)�?TauntStatusScorer: 权重 100.0 (嘲讽强制最�?�?
Case B: 狙击塔索�?(Sniper Tower Targeting)
- 目标: 选一个敌人开火�?
- 选择模式:
Top 1(确定�?�? - 配置:
DistanceScorer: 权重 -1.0 (反向,优先打远的)�?HealthScorer: 权重 2.0 (优先打残血,确保击杀)�?ArmorTypeScorer: 若目标是重甲,权�?0.5 (打不�?;若轻甲,权�?1.5�?
Case C: 肉鸽 Perk 抽取 (Perk Drafting)
- 目标: �?3 �?Perk 给玩家�?
- 选择模式:
Weighted Random(加权随机)�? - 配置:
RarityBaseScorer: 传说(5) < 史诗(15) < 稀�?30) < 普�?50)�?TagSynergyScorer: 玩家若有[Fire],火�?Perk 权重 x 1.5�?BanListFilter: 若玩家选了[NoMagic],剔除所有法�?Perk�?PityTimerScorer: 若连�?10 次没出传说,传说权重 x 10�?
5. 代码实现参�?(C# Implementation)
为了保证性能(避免每�?GC),建议使用结构体或预分配内存�?6. 性能优化指南 (Optimization)
由于 AI 决策可能每一帧都在跑,必须注意开销�?- 分帧计算 (Time-Slicing): 不要让所有怪物在同一帧跑决策逻辑。将怪物分组,每帧只更新一组�?
-
空间划分 (Spatial Partitioning): 在运�?
DistanceScorer之前,先通过四叉�?(QuadTree) 或网格系统获取附近的候选人,避免遍历全图�? - 脏标�?(Dirty Flags): 对于 Perk 系统,只有当玩家获得�?Perk 或进入新房间时才重新计算权重,而不是每帧计算�?
-
提前退�?(Early Exit): 在寻�?
SelectBest时,如果发现一个“绝对优先”的目标(如嘲讽),直接返回,跳过后续计算�?
🏗�?通用决策系统架构�?(Unified Decision System Architecture)
本文档作为系统的工程蓝图,详细定义了类结构、接口关系及运行时序�?1. 类图结构 (Class Diagram)
该图展示了核心泛型引擎与具体业务系统(仇恨、塔防、Perk)的继承与组合关系�?2. 运行时序�?(Sequence Diagram)
2.1 怪物索敌流程 (AI Select Best)
展示了怪物如何通过多重评分器选出最佳攻击目标�?2.2 Perk 抽取流程 (Weighted Random Draft)
展示了如何根据玩家流派权重抽�?Perk�?3. 数据流设�?(Data Flow Specs)
为了支持通用�?Context,我们需要一个灵活的黑板机制�?
3.1 Context Blackboard 结构
DecisionContext 不仅仅是位置信息,它包含了一�?Dictionary<string, object> 或强类型�?Blackboard 结构,用于传递特定业务参数�?
| Key (String) | Type | Description | Used By |
|---|---|---|---|
"AttackerPos" | Vector3 | 发起者的位置 | DistanceScorer |
"PlayerHP" | float | 玩家当前血量百分比 | MercyScorer (低血量降低怪物攻击欲望) |
"PlayerTags" | List<string> | 玩家拥有的流派标�? | SynergyScorer |
"PityCounter" | int | 保底计数�? | RarityScorer |
"LastTarget" | Entity | 上一次攻击的目标 | StickinessScorer (粘性评分,防止频繁切换) |
4. 优化策略 (Optimization Plan)
在架构层面预留性能优化接口�?IJob兼容�? 设计IScorer时尽量使�?struct�?NativeArray,以便未来可以将计算繁重的评分逻辑放入 Unity Job System 并行处理�?- 预分配列�?(Pre-allocation):
DecisionEngine内部维护静态或对象池化�?List<float> scores,避免在SelectBest中产�?GC Alloc�?
💻 核心代码定义 (Core Code Definitions)
本文档定义了通用决策系统的关�?C# 接口与类结构,包括核心引擎和一组标准评分器�?0. 基础数据接口 (Core Data Interfaces)
为了让评分器能够通用,候选对�?T 需要实现这些接口,以暴露必要的数据�?
IPositionable
IHealth
IHasTags
IHasEntityType
1. 基础接口 (Interfaces)
DecisionContext (上下�?
用于在评分过程中传递环境数据。使�?Dictionary 实现灵活的黑板模式,同时也提供常用属性的快捷访问�?
IScorer<T> (评分�?
核心逻辑单元�?
IFilter<T> (过滤�?
用于在评分前剔除无效目标(硬性门槛)�?
2. 核心引擎 (Core Engine)
DecisionEngine<T>
负责组装评分器并执行选择逻辑�?
3. 标准评分器实�?(Standard Scorer Implementations)
DistanceScorer (距离评分)
通用性极强,用于 AI �?塔防�?
HealthScorer (生命值评�?
根据生命值高低进行评分�?
TagSynergyScorer (标签协同评分)
用于 Perk 系统,根据标签匹配度评分�?
PriorityScorer (优先级评�?
根据实体类型给定固定分数�?
🚀 决策系统性能优化示例 (Decision System Performance Optimization Demo)
本文档展示了如何将时间分�?(Time-Slicing) 和空间划�?(Spatial Partitioning) 策略集成�?DecisionEngine 的工作流中,以确保游戏在高并发计算时依然流畅�?
1. 时间分片 (Time-Slicing)
在游戏中,有数百�?AI 同时进行索敌或决策是非常常见的。如果所有单位都在同一帧内更新�?DecisionEngine,会导致帧率骤降。时间分片通过在多帧之间分配计算负载来解决这个问题�?
1.1 IDecisionRequester 接口
定义一个接口,任何需要定期执行决策的 AI 或塔都应实现它�?
1.2 DecisionScheduler (决策调度�?
一个单�?(Singleton) 或全局服务,负责管理和调度所�?IDecisionRequester�?
1.3 AggroAgent (或其他AI) 集成调度�?
2. 空间划分 (Spatial Partitioning)
空间划分系统是提�?Candidates 列表�?DecisionEngine 的关键优化。它将整个游戏世界划分为多个区域,从而将“遍历所有敌人”的操作变为“查询局部区域的敌人”�?
2.1 概念:Grid �?QuadTree
- Grid System (网格系统):
- 原理: 将世界地图划分为均匀的网格,每个网格单元存储其中的所有单位引用�?
- 查询: 塔或 AI 只需查询其射程覆盖的几个网格单元,就能获得潜在目标列表�?
- 适用: 地形平坦、单位分布相对均匀�?2D 或伪 3D 游戏(如标准塔防)�?
- QuadTree (四叉�?八叉�?:
- 原理: 递归地将空间划分为更小的象限,直到每个象限内的单位数量达到某个阈值�?
- 查询: 快速定位到包含查询区域的象限,并只检索这些象限内的单位�?
- 适用: 单位分布稀疏、地图广阔、有垂直高度�?3D 游戏�?
2.2 伪代码:优化 GetAllAggroTargetsInRadius
这个方法现在应该由一个专门的 空间管理服务 提供,而不是遍历一个大列表�?
2.3 AggroAgent 中的应用
�?AggroAgent.PerformDecision 被调用时,它不再依赖一个全局�?_allAggroTargets 列表�?