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

19 KiB
Raw Permalink Blame History

P5 Gameplay 玩法体系落地规划(类土豆兄弟 Brotato)

文档定位:针对当前项目“性能优化/架构重,Gameplay 较少”在校招面试中的痛点,将项目从单纯的割草压测 Demo 升级为具备深度系统设计、复杂公式结算、规则可插拔的商业级“类土豆兄弟(Brotato)”完整玩法原型。

结合现有技术栈:UGF + Luban 配置表 + 5层UI架构 + SimulationWorld(Burst + Job)。


目录

  1. 背景与核心设计目标
  2. 总体架构分层与工程边界
  3. Phase 1: 复合属性修饰器管线与伤害结算系统
  4. Phase 2: 武器标签、羁绊与合成升阶系统
  5. Phase 3: 战斗触发器总线与状态/Buff系统
  6. Phase 4: 局内波次经济循环与商店系统实战
  7. Phase 5: 差异化角色特质系统(规则颠覆)
  8. Phase 6: 机制化敌人与波次节奏导演
  9. 阶段里程碑与推进检查表
  10. 校招简历重塑与面试对线指南

1. 背景与核心设计目标

1.1 面试痛点诊断

  • 现状:简历重构了 SimulationWorld,落地了 Burst + Job System,Android 压测 2k 敌人降耗 56.4%;但面试官全在问 Gameplay,因缺乏深度玩法而陷入被动。
  • 面试官心理:
    1. 校招 Gameplay 岗核心看重:能否承接复杂策划需求、业务抽象能力、数据结构与算法应用、面向对象与开闭原则(OCP)。
    2. 对单纯纯移动/无复杂状态的 Job 压测持防御态度(担心逻辑复杂后无法扩展)。
  • 破局方案:
    • 保留底层性能作为技术壁垒,展示“不仅能写底层高性能 Job,还能在上层支撑复杂多状态 Gameplay”。
    • 落地土豆兄弟最具有代表性的核心机制:深度属性网络、武器羁绊与合成、规则颠覆型角色特质、事件触发器与 Buff、波次经济商店。

2. 总体架构分层与工程边界

为防止业务逻辑与现有的 Job/Burst 模拟层产生混乱耦合,确立以下分层原则:

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 与重算:

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 伤害结算流水线

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 框架

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):

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 编写复杂业务时的灵活性与面向对象表达能力。”