Files
vampire-like/docs/P5 Gameplay 玩法体系落地规划.md
2026-09-18 21:43:22 +08:00

319 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P5 Gameplay 玩法体系落地规划(类土豆兄弟 Brotato)
> **文档定位**:针对当前项目“性能优化/架构重,Gameplay 较少”在校招面试中的痛点,将项目从单纯的割草压测 Demo 升级为具备深度系统设计、复杂公式结算、规则可插拔的商业级“类土豆兄弟(Brotato)”完整玩法原型。
>
> 结合现有技术栈:**UGF + Luban 配置表 + 5层UI架构 + SimulationWorld(Burst + Job)**。
---
## 目录
1. [背景与核心设计目标](#1-背景与核心设计目标)
2. [总体架构分层与工程边界](#2-总体架构分层与工程边界)
3. [Phase 1: 复合属性修饰器管线与伤害结算系统](#3-phase-1-复合属性修饰器管线与伤害结算系统)
4. [Phase 2: 武器标签、羁绊与合成升阶系统](#4-phase-2-武器标签羁绊与合成升阶系统)
5. [Phase 3: 战斗触发器总线与状态/Buff系统](#5-phase-3-战斗触发器总线与状态buff系统)
6. [Phase 4: 局内波次经济循环与商店系统实战](#6-phase-4-局内波次经济循环与商店系统实战)
7. [Phase 5: 差异化角色特质系统(规则颠覆)](#7-phase-5-差异化角色特质系统规则颠覆)
8. [Phase 6: 机制化敌人与波次节奏导演](#8-phase-6-机制化敌人与波次节奏导演)
9. [阶段里程碑与推进检查表](#9-阶段里程碑与推进检查表)
10. [校招简历重塑与面试对线指南](#10-校招简历重塑与面试对线指南)
---
## 1. 背景与核心设计目标
### 1.1 面试痛点诊断
- **现状**:简历重构了 `SimulationWorld`,落地了 Burst + Job System,Android 压测 2k 敌人降耗 56.4%;但面试官全在问 Gameplay,因缺乏深度玩法而陷入被动。
- **面试官心理**:
1. 校招 Gameplay 岗核心看重:**能否承接复杂策划需求、业务抽象能力、数据结构与算法应用、面向对象与开闭原则(OCP)**。
2. 对单纯纯移动/无复杂状态的 Job 压测持防御态度(担心逻辑复杂后无法扩展)。
- **破局方案**:
- **保留底层性能作为技术壁垒**,展示“不仅能写底层高性能 Job,还能在上层支撑复杂多状态 Gameplay”。
- 落地土豆兄弟最具有代表性的核心机制:**深度属性网络、武器羁绊与合成、规则颠覆型角色特质、事件触发器与 Buff、波次经济商店**。
---
## 2. 总体架构分层与工程边界
为防止业务逻辑与现有的 Job/Burst 模拟层产生混乱耦合,确立以下分层原则:
```mermaid
flowchart TD
subgraph UI_Presentation ["表现与界面层 (Presentation)"]
UI["5层UI架构 (RawData/UseCase/Controller/Context/View)"]
FX["表现层 (Animator / Audio / VFX / DamageText)"]
end
subgraph Gameplay_Logic ["Gameplay 逻辑主控层 (Managed C#)"]
RoleTrait["角色特质系统 (Rule Interceptor)"]
AttrSys["属性修饰器管线 (Attribute Pipeline)"]
WeaponSys["武器槽位/羁绊/合成 (Weapon Synergy & Combine)"]
BuffSys["Buff与状态触发器总线 (Event Dispatcher & Buffs)"]
ShopSys["商店事务与波次经济 (Economy & Wave Director)"]
end
subgraph Sim_Layer ["高性能物理与移动层 (Burst + Job System)"]
SimWorld["SimulationWorld"]
Jobs["移动 / 分离 / 空间哈希分桶 / 碰撞候选生成 (Broad Phase)"]
end
UI --> Gameplay_Logic
Gameplay_Logic --> SimWorld
SimWorld -->|命中事件缓冲区 / 坐标输出| Gameplay_Logic
Gameplay_Logic --> FX
```
1. **SimulationWorld 保持纯粹**:
- 负责:空间哈希、宽相碰撞筛选、集群移动分离、投射物飞行轨迹。
- 绝不引入:托管对象、UI 回调、复杂 Buff 状态机。
2. **Gameplay 逻辑层(托管)掌管结算**:
- 消费 Simulation 输出的命中对(Collision Pair),执行伤害公式计算、Buff 挂载、击杀判定、事件派发。
3. **表现层与 UI 解耦**:
- UI 严格遵守现有的 5 层架构与 UGF 事件通信。
---
## 3. Phase 1: 复合属性修饰器管线与伤害结算系统
### 3.1 属性定义(15+ 维核心属性)
土豆兄弟的核心乐趣在于属性间的互斥与权衡取舍:
- **基础输出**:近战伤害(`MeleeDamage`)、远程伤害(`RangedDamage`)、元素伤害(`ElementalDamage`)、百分比增伤(`DamagePercent`)、攻击速度(`AttackSpeed`)、暴击率(`CritChance`)、攻击范围(`Range`)。
- **生存与机动**:最大生命(`MaxHp`)、生命回复(`HpRegen`)、生命偷取(`LifeSteal`)、护甲(`Armor`)、闪避(`Dodge`)、移动速度(`MoveSpeed`)。
- **特殊与经济**:工程学(`Engineering`,影响炮台/地雷)、收获(`Harvesting`,波次利息)、幸运(`Luck`,箱子掉率与商店品质)。
### 3.2 属性修饰器管线(Attribute Modifier Pipeline)
采用 **Base + Modifiers** 结构,结合 **Dirty Flag(脏标记缓存)** 避免高频 GC 与重算:
```csharp
public enum StatType
{
MaxHp, HpRegen, LifeSteal, DamagePercent, MeleeDamage, RangedDamage,
ElementalDamage, AttackSpeed, CritChance, Engineering, Range,
Armor, Dodge, MoveSpeed, Harvesting, Luck
}
public enum ModifierType
{
Flat = 100, // 固定值累加 (e.g. +5 近战伤害)
PercentAdd = 200, // 百分比累加 (e.g. +10% 伤害, 与其他同类相加)
PercentMult = 300 // 最终百分比独立乘区 (e.g. 伤害变为 1.5 倍)
}
public class StatModifier
{
public float Value { get; }
public ModifierType Type { get; }
public object Source { get; } // 来源:道具/武器/羁绊/特质
}
```
- **求值公式**:
$$\text{CurrentValue} = \left( (\text{Base} + \sum \text{Flat}) \times (1 + \sum \text{PercentAdd}) \right) \times \prod \text{PercentMult}$$
- **边界钳制(Clamping)**:
- 闪避硬上限:`Mathf.Min(Dodge, 0.60f)`(最高 60%)。
- 护甲减伤公式:$$\text{DamageMultiplier} = \frac{1}{1 + \frac{\text{Armor}}{15}} \quad (\text{若 } \text{Armor} \ge 0)$$
- 生命偷取:按次命中概率触发,内置全局 CD(如最多每秒偷取 10 次,防止霰弹枪/加特林瞬间回满)。
### 3.3 伤害结算流水线
```mermaid
flowchart LR
A[武器基础伤害] --> B[类型加成: 近战/远程/元素]
B --> C[百分比伤害放大: 1 + DamagePercent]
C --> D[暴击判定: 暴击倍率 1.5x ~ 2.0x]
D --> E[目标护甲折减]
E --> F[伤害飘字 & 扣血 & 吸血触发]
```
---
## 4. Phase 2: 武器标签、羁绊与合成升阶系统
### 4.1 核心机制规范
1. **6 槽位限制**:玩家最多同时装备 6 把武器,槽位满时不可拾取/购买新武器(除非替换或合成)。
2. **武器标签(Weapon Tags)**:
- 每种武器配置 1~2 个标签,如:
- 小刀:`[Blade, Precise]`
- 霰弹枪:`[Gun]`
- 扳手:`[Engineering, Blunt]`
- 火把:`[Primitive, Elemental]`
3. **阶梯羁绊(Set Bonuses)**:
- 当装备中同标签武器数量达到阈值(如 2 / 3 / 4 / 6)时,自动挂载全队属性修饰器:
- *原始(Primitive)*:2件 +3 HP / 3件 +6 HP / 6件 +15 HP。
- *刀剑(Blade)*:2件 +1 近战伤害 / 4件 +3 近战伤害 / 6件 +8 近战伤害 + 5% 吸血。
- *枪械(Gun)*:2件 +10 射程 / 4件 +25 射程 / 6件 +50 射程且自带穿透+1。
4. **武器合成(Tier Synthesis)**:
- 武器分 4 阶:白(Tier 1)/ 蓝(Tier 2)/ 紫(Tier 3)/ 红(Tier 4)。
- **合成规则**:在商店或背包中,两把同名、同品质的武器可点击合成,升阶为高一阶武器,空出一个槽位并增强属性(CD更短、射程更远、新增弹道或穿透)。
### 4.2 数据表设计(Luban)
- **`WeaponConfig_武器配置.xlsx` 扩展**:
- `Tags`:`list,int`(标签枚举列表)。
- `Tier`:`int`(品质 1~4)。
- `NextTierWeaponId`:`int`(下一级武器 ID)。
- `ScalingStat`:`int`(加成主属性:近战/远程/元素/工程)。
- `ScalingRatio`:`float`(加成系数,如 0.8)。
- **新建 `WeaponSynergyConfig_武器羁绊配置.xlsx`**:
- `TagId`:标签 ID。
- `RequiredCounts`:`list,int`(阶梯数量,如 `[2, 3, 4, 6]`)。
- `Modifiers`:`list,bean:StatModifierConfig`(对应各阶梯触发的属性修正)。
---
## 5. Phase 3: 战斗触发器总线与状态/Buff系统
### 5.1 战斗事件总线(Battle Event Bus)
建立高性能的直接委托事件驱动,覆盖战斗高频节点:
- `OnHit(HitContext ctx)`:命中敌人时(参数含受击者、伤害、是否暴击、伤害类型)。
- `OnDamaged(DamageContext ctx)`:自身受到伤害时。
- `OnKill(KillContext ctx)`:击杀敌人时。
- `OnWaveStart()` / `OnWaveEnd()`:波次起止。
### 5.2 经典 Buff 框架
```csharp
public abstract class BuffBase
{
public int BuffId { get; set; }
public float Duration { get; set; }
public int CurrentStacks { get; set; }
public int MaxStacks { get; set; }
public virtual void OnApply(Entity owner) { }
public virtual void OnTick(Entity owner, float deltaTime) { }
public virtual void OnRemove(Entity owner) { }
public virtual void OnStackAdded(Entity owner) { }
}
```
- **堆叠策略**:
1. `RefreshDuration`:刷新持续时间,层数 +1(如点燃、流血)。
2. `Additive`:独立计时器(复杂 Buff)。
3. `Override`:高强度替换低强度。
- **代表性状态实装**:
- **点燃(Burning)**:每 0.5s 造成一次伤害,伤害受玩家 `ElementalDamage` 加成,受击者死亡时向周围 2m 内敌人传播点燃。
- **击退(Knockback)**:击退位移,接入 `SimulationWorld` 的速度冲量或阻尼位移。
---
## 6. Phase 4: 局内波次经济循环与商店系统实战
### 6.1 核心流转与双重货币(Materials)
土豆兄弟没有将经验和金币分开,掉落的**绿晶(材料 Material)**同时兼具两种职能:
1. **拾取即获得局内经验**:达到阈值触发升级弹窗(局末加点或即时加点)。
2. **拾取存入临时金库**:作为波次结束后在商店消费的唯一货币。
3. **吸附清场**:波次计时结束(如 20s~60s)时,地图上未拾取的材料自动全图飞向玩家并结算入库。
### 6.2 收获机制(Harvesting)
- 每波次结束时:玩家获得等同于 `Harvesting` 点数的材料奖励。
- **复合增长(利息)**:若 `Harvesting > 0`,每波结束其自身永久增长 5%(向上取整),形成后期经济滚雪球。
### 6.3 商店系统落地(实战验证 5 层 UI 架构)
- **商品生成**:每轮提供 4 个展示槽(武器 + 道具混合抽取,概率受 `Luck` 属性加成)。
- **锁定槽位(Lock)**:玩家资金不足时可锁定某格商品,波次刷新时不被替换。
- **刷新(Reroll)与通胀**:
$$\text{RerollCost} = \text{BaseCost} + (\text{CurrentWave} \times 1) + (\text{RollTimesInThisShop} \times 2)$$
- **属性升级四选一(Level-up Draft)**:
- 每升 1 级积累 1 次加点机会。
- 随机抽取 4 项属性,并按概率随机赋予品质(普通/稀有/史诗/传奇,加成数值成倍放大)。
---
## 7. Phase 5: 差异化角色特质系统(规则颠覆)
### 7.1 为什么不做简单的数值增减?
如果只是“角色 A 攻击力 +10%,角色 B 生命 +20”,毫无架构含金量。土豆兄弟的精髓在于**打破既有规则**。
### 7.2 规则拦截器架构(Rule Interceptor Pattern)
通过接口/抽象组件挂载,在主流程核心逻辑的关键判断点注入拦截逻辑,遵循**开闭原则(OCP)**,拒绝在全局战斗代码中堆砌 `if (role == Bull)`:
```csharp
public interface IRuleInterceptor
{
// 是否允许装备指定类型武器
bool CanEquipWeapon(WeaponConfig weapon, int currentWeaponCount);
// 受到伤害时的特殊结算(公牛自爆)
void OnTakeDamageIntercept(ref DamageInfo damage);
// 波次结算时的特殊收益(和平主义者)
void OnWaveEndIntercept(WaveResult result);
}
```
### 7.3 实装 4 个极具代表性的角色
1. **独臂(One-Armed)**:
- 规则:`MaxWeaponSlots = 1`。
- 补偿:常驻 `AttackSpeed +200%`,`DamagePercent +100%`。
2. **公牛(Bull)**:
- 规则:`MaxWeaponSlots = 0`(不可携带任何武器)。
- 特质:受击时立即触发 360° 巨额范围爆炸,基础护甲 +15,生命秒回 +10。
3. **和平主义者(Pacifist)**:
- 规则:常驻 `DamagePercent = -100%`(击杀收益极低)。
- 特质:波次倒计时结束时,场上存活的敌人每有 1 只,转化为 1 份额外材料与经验。
4. **法师(Mage)**:
- 规则:所有攻击附带点燃效果,元素伤害加成翻倍,但近战/远程基础伤害扣减。
---
## 8. Phase 6: 机制化敌人与波次节奏导演
### 8.1 典型敌人机制(区别于纯移速僵尸)
1. **冲锋怪(Charger)**:进入玩家一定距离后停步蓄力闪红(Telegraph),随后进行高移速直线冲撞。
2. **图腾增益怪(Buffer)**:自身不攻击,环绕光环为其半径 4m 内的其他敌人提供移速与减伤 Buff。
3. **远程射击怪(Shooter)**:与玩家保持放风筝距离,周期性射出直线投射物。
4. **第 11 / 20 波 精英/Boss**:
- 拥有多阶段行为(Phase 1 环形弹幕,Phase 2 召唤小怪 + 追踪地雷),击杀必掉稀有道具宝箱。
---
## 9. 阶段里程碑与推进检查表
| 阶段 | 核心任务 | 涉及代码与模块 | 交付标准与回归 |
| :--- | :--- | :--- | :--- |
| **Phase 1** | **属性修饰器与伤害管线** | `StatModifier`, `AttributePipeline`, `PlayerData` 扩展, 伤害公式重构 | 单元测试覆盖所有修饰器加法/乘法与护甲折减公式,无浮点截断异常 |
| **Phase 2** | **武器标签羁绊与合成** | `WeaponSynergyManager`, `WeaponConfig` 扩展, 背包/槽位管理 | 6槽位限制生效,同标签激活被动,2把同名同阶武器合成升阶无资源泄露 |
| **Phase 3** | **事件触发器与Buff** | `BattleEventBus`, `BuffManager`, 点燃/击退/吸血实装 | 点燃每秒跳字传火正常,击退对接 Simulation 冲量,吸血有内置 CD 控制 |
| **Phase 4** | **波次经济与商店实战** | `ShopController` (5层UI), `Harvesting` 利息公式, 锁定与加点 | 倒计时清场自动吸附材料,商店刷新递增、锁定跨波次保存、4选1加点正常 |
| **Phase 5** | **规则颠覆角色特质** | `IRuleInterceptor`, 实装独臂/公牛/和平主义者 | 零硬编码支持独臂只能拿1把枪、公牛无法拿武器且受击自爆 |
| **Phase 6** | **机制敌人与波次配置** | 冲锋怪、图腾怪、Boss 弹幕、`WaveDirector` 表驱动 | 1~20 波次节奏平滑,精英怪出场带有危险警示圈与阶段切换 |
---
## 10. 校招简历重塑与面试对线指南
完成上述系统后,简历专业度将实现质的飞跃。
### 10.1 简历 Bullet Points 建议模板
- **主流程与 UI 架构**:
> 基于 Unity GameFramework 的 Procedure/FSM 搭建波次流转与选卡循环;为 Shop / LevelUp 设计落地 **RawData-UseCase-Controller-Context-View 五层 UI 架构**,解耦商品生成、锁定事务与展示渲染,提升高频迭代模块的复用性。
- **Gameplay 核心系统架构(重点突出)**:
> - **多维属性与伤害流水线**:设计支持 15+ 维派生属性的 **Attribute Modifier Pipeline**,通过脏标记(Dirty Flag)缓存避免频繁重算;落地包含基础增伤、暴击、护甲减免与内置 CD 吸血的复合伤害公式。
> - **武器羁绊与合成升阶**:实现基于**标签(Tags)聚合驱动的武器多维羁绊系统**与 6 槽位限制,支持同品质武器 2 合 1 升阶,解耦武器生命周期、模型挂点与发射器复用。
> - **事件驱动触发器与状态机**:搭建基于**观察者模式的战斗事件总线(OnHit / OnDamaged / OnKill)**与通用 Buff 状态机,实现点燃(DoT与传火扩散)、击退与状态互斥堆叠。
> - **开闭原则特质系统**:采用**规则拦截器(Rule Interceptor)模式**实现差异化角色特质,在零修改战斗主链路的前提下无缝支持“独臂(限制单武器/高攻速)”、“公牛(禁止武器/受击自爆)”等规则颠覆型玩法。
- **底层性能保障(底牌)**:
> - **Job System + Burst 并行模拟**:重构底层 `SimulationWorld`,将海量敌人移动分离、投射物模拟与网格空间哈希候选筛选接入 Burst 并行计算;在实机 2k 敌人同屏下 Tick 热路径耗时由 21.68 ms 降至 9.44 ms,为上层复杂 Gameplay 提供了宽裕的性能预算。
---
### 10.2 高频面试真题与最佳应答套路
#### Q1: “如果策划要加一个新角色‘受到伤害时分裂出小型炸弹,且无法使用枪械’,你的代码要改哪些地方?”
* **雷区回答**:在受到伤害的地方写 `if (role == BombMan)`,在穿装备的地方写 `if (weapon == Gun && role == BombMan) return false;`。
* **满分回答**:
> “在我的架构里完全不需要改动任何战斗核心代码。我设计了 `IRuleInterceptor` 特质机制:
> 1. 新建 `BombManTrait`,在 `CanEquipWeapon` 中检查武器标签若包含 `Gun` 则拦截返回 `false`。
> 2. 实现 `OnDamaged` 接口,订阅受击事件,在自身坐标实例化炸弹实体。
> 3. 在 Luban 的 `RoleConfig` 中为该角色绑定此特质 ID,角色进入战斗时自动挂载到上下文。核心逻辑完全对扩展开放、对修改关闭。”
#### Q2: “武器羁绊系统如果有 6 件套加成,玩家在战斗或商店里频繁换装/合成,属性怎么计算才不会错乱或产生高开销?”
* **满分回答**:
> “我采用了 **Tag 计数器 + 属性修饰器句柄 + 脏标记** 的设计:
> 1. 玩家持有 `Dictionary<WeaponTag, int>`。每次穿卸或合成武器,只对对应 Tag 计数做增减。
> 2. 羁绊触发器监听计数变更,当跨越 2/3/4/6 阈值时,向角色属性池派发或撤销带有唯一来源标记(Source)的 `StatModifier`。
> 3. 属性系统自身不每帧循环遍历修饰器,而是通过 `_isDirty` 标记在下次读取(如计算攻击伤害或生命最大值)时惰性重算并缓存结果,零 GC 且保证数据唯一真相源。”
#### Q3: “你的底层用 Burst 和 Job 处理了 2k 敌人,但上面这套复杂的 Buff、点燃传火、触发器全在托管堆,这两者怎么高效协同而不打破 Burst 约束?”
* **满分回答**:
> “这是我专门设计的**逻辑分层(Simulation vs Gameplay)边界**:
> 1. Job 和 Burst 只做高密度的**纯数据计算与宽相筛选(Broad Phase)**——如空间分桶、距离剔除、包围盒相交,并将发生碰撞的实体 ID 成对输出到 `NativeQueue<CollisionEvent>` 中。
> 2. 在主线程 Tick 阶段,由托管层的 `BattleManager` 一次性消费队列事件,执行复杂的 Gameplay 逻辑(判断防御、暴击、挂载 Buff、派发 C# 事件)。
> 3. 这样既享受了 Burst 处理大批量空间遍历与移动物理的高性能,又保住了上层 Gameplay 编写复杂业务时的灵活性与面向对象表达能力。”