Game_Num_Basics_And_Calc

🧙‍♂️ 技能树设计深度研究

📚 1. 理论基础 (Theoretical Basis)

🎯 核心定义

技能树 (Skill Tree) 是一种可视化的角色成长系统,玩家通过消耗资源(技能点/经验/货币)来解锁新能力或强化现有能力。

优秀技能树的三大目标:

  1. Build 多样性 - 支持多种玩法风格
  2. 成长可感知 - 玩家能明显感受到变强
  3. 选择有意义 - 每个决策都有权衡

📐 技能树类型分类

1. 线性树 vs 分支树 vs 网格树

线性树(单路径):
等级 1: 攻击力 +10%
  ↓
等级 2: 攻击力 +15%
  ↓
等级 3: 攻击力 +20%

优点: 简单明了,新手友好
缺点: 无选择,无 Build 多样性
适用: 移动端休闲游戏

---

分支树(多路径):
        起点
       /   \
    物理系  魔法系
    /  \    /  \
  近战 远程 火 冰

优点: 有选择,Build 分化
缺点: 可能出现"必点路径"
适用: 大多数 RPG

---

网格树(自由连接):
  [A]─[B]─[C]
   │ ╲ │ ╱ │
  [D]─[E]─[F]
   │ ╱ │ ╲ │
  [G]─[H]─[I]

优点: 极限自由,组合无穷
缺点: 新手困惑,平衡困难
适用: 硬核 ARPG (如 Path of Exile)

Vampirefall 推荐: 分支树(多路径),在自由度和易用性之间平衡。

2. 主动技能 vs 被动加成

类型 玩家体验 设计难度 推荐比例
主动技能 爽感强,操作复杂度 ↑ 高(需动画/特效) 20-30%
被动加成 无感知,但持续有效 低(纯数值) 70-80%

设计公式:

技能树吸引力 = (主动技能数量 × 炫酷度) + (被动加成总和 × 实用性)

最佳配比:
- 每个分支至少 1 个主动技能(吸引玩家选择)
- 被动技能填充路径(提供成长感)

3. 递进式 vs 横向式

递进式(纵向成长):

攻击力 +10% → 攻击力 +20% → 攻击力 +30%

特点: 同一能力不断强化
适用: 简单系统

横向式(扩展玩法):

攻击力 +10% → 范围伤害 → 生命偷取

特点: 解锁新机制
适用: 复杂系统(推荐)

🧮 Build 多样性数学模型

1. 组合爆炸定律

可能 Build 数量 = C(总技能数, 可用点数)

示例:
10 个技能,5 个点数: C(10, 5) = 252 种组合

但实际有效 Build 远少于数学组合:
- 某些技能互斥
- 某些路径必点
- 某些组合无意义

实际有效 Build ≈ 20-30% 理论值

2. Build 熵(多样性度量)

Build Entropy = -Σ (P(Build_i) × log P(Build_i))

其中 P(Build_i) = 玩家选择该 Build 的概率

理想值:
- 低熵 (<2.0): Build 单一,平衡问题
- 中熵 (2.0-3.5): 健康多样性
- 高熵 (>3.5): 选择过载,无最优解

目标: 保持中等熵值

3. 必点节点问题

必点节点 (Mandatory Node):
90%+ 玩家都会点的技能

识别方法:
if (选择率 > 90% AND 无替代方案):
    标记为必点节点
    → 考虑改为基础能力或降低吸引力

示例:
❌ "+50% 伤害" 在路径起点 → 必点
✅ "+10% 伤害" 在路径起点 → 可选

🔄 重置机制设计

1. 免费 vs 付费重置

模式 优点 缺点 适用场景
完全免费 鼓励实验,友好 失去决策重量感 肉鸽类
货币重置 保留选择意义 可能导致囤积不敢点 RPG
首次免费 平衡两者 实现复杂度中等 推荐
禁止重置 选择极重要 新手可能废号 硬核游戏

Vampirefall 推荐:

2. 重置成本曲线

重置成本 = 基础成本 × (1 + 0.5 × 重置次数)

示例:
第 1 次: 100 金币
第 2 次: 150 金币
第 3 次: 200 金币
...
(避免无限制重置)

或者:
每 24 小时免费重置 1 次(时间冷却)

🛠️ 2. 实践应用 (Practical Implementation)

🎮 Vampirefall 技能树框架

双层成长系统

Vampirefall 的混合品类需要局外成长 + 局内成长双层设计:

┌─────────────────────────────────────┐
│ 局外成长 (Meta Progression)         │
│ - 永久天赋树                        │
│ - 基地建设                          │
│ - 解锁新机制                        │
├─────────────────────────────────────┤
│ 局内成长 (In-Run Progression)       │
│ - 肉鸽词条选择                      │
│ - 临时技能强化                      │
│ - Build 即时构建                    │
└─────────────────────────────────────┘

区分原则:

技能树分支设计

        【猎人天赋树】
              │
      ┌───────┼───────┐
      │       │       │
   【战士】 【射手】 【法师】
    /  \     /  \     /  \
  近战 防御 精准 移动 元素 召唤

分支特色:

  1. 战士分支(近战 + 塔防协同)
    - 近战伤害 +20%
    - 塔的攻击速度 +15%
    - 解锁:战吼(范围Buff)
    
  2. 射手分支(远程 + 机动性)
    - 远程伤害 +25%
    - 移动速度 +20%
    - 解锁:多重箭(一次射三箭)
    
  3. 法师分支(元素 + AOE)
    - 元素伤害 +30%
    - 技能范围 +25%
    - 解锁:魔法塔强化(塔获得元素属性)
    

🗂️ 数据结构

SkillTreeConfig.cs

[CreateAssetMenu(fileName = "SkillTree", menuName = "Systems/Skill Tree")]
public class SkillTreeConfig : ScriptableObject
{
    [Header("技能树信息")]
    public string treeName = "猎人天赋树";
    public SkillTreeType treeType = SkillTreeType.Meta;  // Meta or InRun
    
    [Header("技能节点")]
    public SkillNode[] nodes;
    
    [Header("重置设置")]
    public bool allowReset = true;
    public int baseResetCost = 100;
    public float resetCostMultiplier = 0.5f;
}

[System.Serializable]
public class SkillNode
{
    [Header("基础信息")]
    public string nodeID = "SKILL_001";
    public string displayName = "剑术精通";
    
    [TextArea(2, 5)]
    public string description = "近战伤害 +20%";
    
    [Header("类型")]
    public SkillNodeType nodeType = SkillNodeType.Passive;
    public SkillCategory category = SkillCategory.Warrior;
    
    [Header("连接")]
    public string[] prerequisiteIDs;  // 前置技能 ID
    public Vector2 position;  // UI 位置
    
    [Header("消耗")]
    public int pointCost = 1;
    public int levelRequirement = 1;
    
    [Header("效果")]
    public SkillEffect[] effects;
    
    [Header("视觉")]
    public Sprite icon;
    public Sprite connectorSprite;
}

public enum SkillNodeType
{
    Passive,      // 被动加成
    ActiveAbility,// 主动技能
    Keystone      // 核心节点(大幅改变玩法)
}

public enum SkillCategory
{
    Warrior,
    Archer,
    Mage,
    Universal    // 通用
}

[System.Serializable]
public class SkillEffect
{
    public EffectType type;
    public float value;
    public string targetStat;  // 例如: "AttackDamage", "MoveSpeed"
    
    public void Apply(PlayerStats stats)
    {
        switch (type)
        {
            case EffectType.AddFlat:
                stats.ModifyStat(targetStat, value, ModifyType.Flat);
                break;
            case EffectType.AddPercentage:
                stats.ModifyStat(targetStat, value, ModifyType.Percentage);
                break;
            case EffectType.UnlockAbility:
                AbilitySystem.UnlockAbility(targetStat);
                break;
        }
    }
}

public enum EffectType
{
    AddFlat,         // 固定加成
    AddPercentage,   // 百分比加成
    UnlockAbility    // 解锁技能
}

SkillTreeManager.cs

public class SkillTreeManager : MonoBehaviour
{
    public static SkillTreeManager Instance { get; private set; }
    
    [Header("配置")]
    public SkillTreeConfig metaTree;   // 局外成长树
    public SkillTreeConfig inRunTree;  // 局内成长树(可选)
    
    private Dictionary<string, SkillNode> allNodes;
    private HashSet<string> unlockedNodes;
    private int availablePoints = 0;
    private int resetCount = 0;
    
    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
            InitializeSkillTree();
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    private void InitializeSkillTree()
    {
        allNodes = new Dictionary<string, SkillNode>();
        
        foreach (var node in metaTree.nodes)
        {
            allNodes[node.nodeID] = node;
        }
        
        // 加载已解锁节点
        unlockedNodes = LoadUnlockedNodesFromSave();
        availablePoints = CalculateAvailablePoints();
    }
    
    public bool CanUnlockNode(string nodeID)
    {
        if (!allNodes.ContainsKey(nodeID))
            return false;
        
        var node = allNodes[nodeID];
        
        // 1. 检查是否已解锁
        if (unlockedNodes.Contains(nodeID))
            return false;
        
        // 2. 检查技能点
        if (availablePoints < node.pointCost)
            return false;
        
        // 3. 检查等级需求
        if (PlayerLevel.Current < node.levelRequirement)
            return false;
        
        // 4. 检查前置技能
        foreach (var prereqID in node.prerequisiteIDs)
        {
            if (!unlockedNodes.Contains(prereqID))
                return false;
        }
        
        return true;
    }
    
    public void UnlockNode(string nodeID)
    {
        if (!CanUnlockNode(nodeID))
        {
            Debug.LogWarning($"[SkillTree] 无法解锁: {nodeID}");
            return;
        }
        
        var node = allNodes[nodeID];
        
        // 1. 扣除点数
        availablePoints -= node.pointCost;
        
        // 2. 标记解锁
        unlockedNodes.Add(nodeID);
        
        // 3. 应用效果
        ApplyNodeEffects(node);
        
        // 4. 保存
        SaveUnlockedNodesToSave();
        
        // 5. 触发事件
        OnNodeUnlocked?.Invoke(node);
        
        Debug.Log($"[SkillTree] 解锁: {node.displayName}");
    }
    
    private void ApplyNodeEffects(SkillNode node)
    {
        var playerStats = PlayerStats.Instance;
        
        foreach (var effect in node.effects)
        {
            effect.Apply(playerStats);
        }
        
        // 特殊处理核心节点
        if (node.nodeType == SkillNodeType.Keystone)
        {
            ApplyKeystoneEffect(node);
        }
    }
    
    public int CalculateResetCost()
    {
        if (resetCount == 0)
            return 0;  // 首次免费
        
        return Mathf.RoundToInt(
            metaTree.baseResetCost * 
            (1 + metaTree.resetCostMultiplier * resetCount)
        );
    }
    
    public void ResetSkillTree()
    {
        int cost = CalculateResetCost();
        
        // 扣除货币
        if (!CurrencySystem.TrySpend(CurrencyType.Gold, cost))
        {
            Debug.LogWarning("[SkillTree] 金币不足,无法重置");
            return;
        }
        
        // 移除所有效果
        foreach (var nodeID in unlockedNodes)
        {
            RemoveNodeEffects(allNodes[nodeID]);
        }
        
        // 清空解锁记录
        int totalPoints = unlockedNodes.Sum(id => allNodes[id].pointCost);
        unlockedNodes.Clear();
        
        // 返还点数
        availablePoints += totalPoints;
        
        // 增加重置计数
        resetCount++;
        
        // 保存
        SaveUnlockedNodesToSave();
        
        // 事件
        OnSkillTreeReset?.Invoke();
        
        Debug.Log($"[SkillTree] 重置技能树(花费 {cost} 金币)");
    }
    
    public Dictionary<SkillCategory, int> GetCategoryDistribution()
    {
        var distribution = new Dictionary<SkillCategory, int>();
        
        foreach (var nodeID in unlockedNodes)
        {
            var category = allNodes[nodeID].category;
            
            if (!distribution.ContainsKey(category))
                distribution[category] = 0;
            
            distribution[category]++;
        }
        
        return distribution;
    }
    
    // 事件
    public System.Action<SkillNode> OnNodeUnlocked;
    public System.Action OnSkillTreeReset;
}

🎨 UI 设计建议

技能树可视化

┌─────────────────────────────────────┐
│ 猎人天赋树  [已用: 15/30 点]  [重置]│
├─────────────────────────────────────┤
│                                     │
│       [战士]    [射手]     [法师]  │
│         │         │          │      │
│      ┌──┼──┐   ┌──┼──┐   ┌──┼──┐  │
│      │  │  │   │  │  │   │  │  │  │
│     🗡️ 🛡️ ⚔️  🏹 👟 🎯  🔥 ❄️ ⚡  │
│                                     │
│ 选中: [剑术精通]                    │
│ 近战伤害 +20%                       │
│ 消耗: 1 点 | 需求: 等级 1          │
│ 前置: 无                            │
│ [解锁]                              │
└─────────────────────────────────────┘

交互设计:


🌟 3. 业界优秀案例 (Industry Best Practices)

🎮 案例 1: Path of Exile - 被动天赋树

核心机制

POE 的天赋树是网格树的极致,拥有 1300+ 个节点。

设计特色:

起始位置:
- 7 个职业,7 个不同起点
- 每个职业倾向不同(但可以走到任何位置)

节点类型:
- 小节点: +10 力量(填充路径)
- 显著节点: +30% 物理伤害(强力加成)
- 核心节点: 改变游戏规则(例如:生命不再恢复,但...)

经典核心节点示例:

"虚空之眼" (Void Gaze):
- 你的法术不再造成伤害
- 你的法术造成的伤害转化为生命值
(完全改变玩法)

"痛苦之影" (Pain Attunement):
- 生命值低于 35% 时,法术伤害 +30%
(风险收益设计)

设计哲学:

“给玩家无限可能,让他们自己创造 Build。”

优点:

缺点:

Vampirefall 借鉴:


🎮 案例 2: Borderlands - 职业技能树

核心机制

Borderlands 的技能树是分支树的典范,简洁但有深度。

结构:

每个职业 3 棵树:
- 树 1: 进攻向(伤害提升)
- 树 2: 防御向(生存能力)
- 树 3: 特殊向(独特机制)

每棵树:
- 6 层节点
- 最底层是"终极技能"(强力主动技能)

职业示例 - 猎人 (Hunter):

树 1: 狙击手
├ 第 1 层: 致命打击 (+5% 暴击率)
├ 第 2 层: 专注 (瞄准时伤害 +10%)
├ 第 3 层: 爆头 (爆头伤害 +40%)
...
└ 终极: 一枪致命(下一枪必定暴击 +100% 伤害)

树 2: 游侠
├ 第 1 层: 快速移动 (+15% 移速)
├ 第 2 层: 生命恢复 (每秒 +2% 生命)
...

树 3: 猛禽
├ 第 1 层: 召唤猎鹰(宠物系统)
...

设计巧思:

  1. 层级依赖
    解锁第 N 层需要:
    - 已点第 N-1 层至少 1 个技能
    (强制玩家在同一棵树深入)
    
  2. 点数上限 ``` 最大技能点: ~70 点 单棵树消耗: ~35 点

结果:

  1. 终极技能吸引力
    每棵树底部的终极技能都很强
    → 吸引玩家深入投资某条路径
    

Vampirefall 借鉴:


🎮 案例 3: Hades - 镜子升级系统

核心机制

Hades 的”镜子”是肉鸽类技能树的优秀范例。

设计特色:

双选升级(互斥):
┌──────────────────┐
│ +50 生命         │  ←  选其一
│      或          │
│ +25% 伤害        │
└──────────────────┘

特点:
- 每个升级项都有 2 个方向
- 玩家可以随时切换(免费)
- 鼓励实验不同 Build

升级项示例:

1. 生命系
   - +50 生命 vs +25% 死亡挑战伤害

2. 进攻系
   - +10% 攻击 vs +10% 技能伤害

3. 防御系
   - 20% 伤害减免 vs 100% 死亡后复活 1 次

4. 特殊系
   - +20% 稀有祝福概率 vs +1 额外冲刺次数

设计哲学:

“让玩家轻松尝试,频繁切换,找到最适合自己的玩法。”

优点:

缺点:

Vampirefall 借鉴:


🎮 案例 4: Grim Dawn - 星座系统

核心机制

Grim Dawn 除了职业技能树,还有独特的星座系统

设计特色:

星座图:
- 类似 POE 的网格
- 但用"属性点"解锁而非技能点

解锁流程:
1. 玩家获得"属性点"(力量/智力/灵巧)
2. 用属性点解锁星座节点
3. 激活整个星座获得特殊效果

示例:
【毒蛇座】(需要: 3 灵巧点)
└ 节点 1: +3% 攻速
└ 节点 2: +5 智力
└ 节点 3: +10% 毒伤
└ 完成奖励: 触发"毒蛇之咬"(10% 概率中毒敌人)

设计巧思:

  1. 收集感
    玩家会想"集齐所有星座"
    → 长期目标
    
  2. 组合爆炸
    职业技能树 × 星座系统 = 海量组合
    
  3. 分离资源
    技能点 → 职业技能
    属性点 → 星座
    (避免资源竞争)
    

Vampirefall 借鉴:


🔗 4. 参考资料 (References)

📄 理论与设计

  1. Skill Trees and Player Choice
    Damion Schubert (BioWare)
    GDC 论文

  2. The Math of Skill Trees
    Game Balance Concepts
    在线课程

  3. Build Diversity in RPGs
    Extra Credits
    YouTube 视频

📺 GDC 演讲

  1. [GDC 2013] Path of Exile: Designing the Passive Tree
    演讲者: Chris Wilson (Grinding Gear Games)
    GDC Vault

  2. [GDC 2020] Hades: Balancing Roguelike Progression
    演讲者: Greg Kasavin (Supergiant Games)
    YouTube 链接

🌐 技术博客

  1. Skill Tree Design Patterns - Gamasutra
    文章链接

  2. Build Entropy Analysis
    Reddit 深度讨论

  3. Balancing Skill Trees
    Game Developer 文章

📚 推荐书籍

  1. 《RPG 设计指南》 (Tabletop RPG Design)
    作者: Jennifer Scheurle
    第 8 章: “角色成长系统”

  2. 《游戏平衡艺术》 (Game Balance)
    作者: Ian Schreiber, Brenda Romero
    第 12 章: “技能树平衡”


🎯 附录:Vampirefall 技能树实施检查清单

✅ 阶段 1: 基础框架(必须)

✅ 阶段 2: 技能内容(必须)

✅ 阶段 3: 平衡调优(推荐)

✅ 阶段 4: 重置系统(推荐)

✅ 阶段 5: 双层成长(可选)

✅ 阶段 6: 数据分析(可选)


最后更新: 2025-12-04
维护者: Vampirefall 设计团队