欢迎来到 RogueKit 框架的旗舰开发蓝图:“源力法师:突围”。
本项目的首要目标是放弃宽泛的功能陈列,转而提供一个高密度、可执行的开发指南。我们将以构建一个具体、可玩、融合了现代 Roguelite 精华的游戏为目标,展示 RogueKit 框架的全部潜力。
“源力法师:突围”的游戏设计融合了以下核心要素:
- 高强度竞技场生存:玩家在有限空间内面对持续生成的、数量庞大的敌人波次。生存的重点在于实时走位、资源管理和宏观策略选择。
- 深度能力构筑:这是游戏的核心乐趣来源。玩家的成长系统超越了简单的线性升级。玩家通过收集法术核心(Cores)和修饰符(Modifiers),并将它们自由组合,从而动态地设计和进化自己的攻击手段。
本项目严格遵循 RogueKit 库的核心设计哲学,这些哲学是实现高效开发和复杂系统的基石:
- 组合优于继承 (Composition over Inheritance):游戏实体(如玩家和敌人)是通过“组装”功能组件(如
HealthComponent、StatsComponent、AbilityManagerComponent)来构建的,而不是通过创建复杂的继承树。这为动态添加或移除能力提供了极高的灵活性。 - 数据驱动设计 (Data-Driven Design):游戏的大部分内容——包括角色属性、物品效果、敌人配置、法术组件和关卡波次——都是通过 Godot 的
Resource(资源文件,.tres)来定义的,而非硬编码在脚本中。这使得游戏设计师可以不接触代码就能调整游戏平衡和添加新内容。 - 清晰的扩展边界 (Clear Extension Boundaries):
RogueKit提供了一套稳固的基础类。当需要实现独特的游戏机制时(例如一个全新的法术修饰符逻辑),您应该通过继承这些基础类来扩展功能,而不是修改库的源代码。
本蓝图将重点展示如何应用 RogueKit 框架来实现以下高度融合的系统:
- 动态能力构筑系统:演示
RogueKit的效果引擎如何将能力分解为**“核心组件”(如ProjectileCore- 发射投射物)和“修饰组件”**(如MultishotModifier- 增加发射数量,ChainReactionModifier- 赋予连锁反应能力)。玩家在运行时可以将修饰符动态附加到核心上。 - 竞技场生存循环:演示如何配置
GameManager和WaveSpawner来驱动实时游戏循环,管理基于时间的敌人生成波次和玩家的自动攻击触发机制。 - 涌现式协同引擎 (Emergent Synergy Engine):展示如何利用框架的全局属性系统(
StatsComponent)和效果堆叠机制(EffectData),实现不同升级选项之间的乘法效应,而无需为每种协同组合编写特定代码。 - 数据驱动的 AI:使用
AIBehaviorProfile资源,为不同类型的敌人(如近战集群单位、远程狙击单位、特殊辅助单位)配置截然不同的行为逻辑。
依赖项:Godot Engine (版本与 RogueKit 库兼容)
本项目使用 Git Submodule 来管理 RogueKit 库的依赖。
-
克隆仓库(推荐方式): 使用
--recurse-submodules标志来确保在克隆主项目的同时自动初始化并拉取RogueKit子模块。git clone --recurse-submodules [repository_url]
-
针对已克隆的项目: 如果项目已经克隆,但
lib/roguekit目录为空,请运行以下命令来初始化并拉取子模块:git submodule update --init --recursive
- 导入项目:打开 Godot 引擎,使用项目管理器的“导入”功能,选择本项目的
project.godot文件。 - 检查 Autoloads:为确保
RogueKit的核心系统(如GameManager、EffectEngine、SignalBus)能够正常工作,请检查项目 -> 项目设置 -> Autoload。本示例应已预先配置好所有必需的全局单例。
本节是开发指南的核心。我们将摒弃泛用示例,转而详细演示如何使用 RogueKit 的数据驱动方法论来实现“源力法师”的具体游戏机制。
目标:构建游戏的核心乐趣循环——允许玩家将“连锁闪电”修饰符添加到现在发射的“火焰弹”上,使其变为“连锁火焰弹”。
首先,我们需要定义两种类型的能力资源:
-
ProjectileAbilityCoreData(Resource):一种具体的能力核心,定义了投射物法术的基础行为。查看extensions/custom_abilities/projectile_ability_core_data.gd。 -
AbilityModifierData(Resource):定义一个可附加的额外逻辑。查看lib/roguekit/entity/ability_modifier_data.gd。- 示例:
content/abilities/modifiers/chain_reaction.tres - 关键属性:
modifier_name: "连锁反应"description: "击中敌人时弹射到附近的额外2个目标。"tags_required: [projectile] (确保只能附加到投射物核心上)effects_to_add: [res://extensions/custom_effects/effect_chain_reaction.tres]
- 示例:
“连锁反应”需要自定义逻辑,因此我们创建新脚本:
- 创建脚本
effect_chain_reaction.gd,继承自EffectData。实际文件位于extensions/custom_effects/effect_chain_reaction.gd。 - 重写
execute(context: EffectContext)方法:context对象包含触发此效果所需的所有信息(如攻击者owner、被击中的目标target等)。- 在
execute方法中,编写逻辑:- 获取被击中目标的位置
target.global_position。 - 在一定半径内搜索除
target外的其他敌人。 - 选取最近的N个敌人(例如2个)。
- 对这N个敌人应用一个新的、伤害略微衰减的
DamageEffect实例。
- 获取被击中目标的位置
- 玩家的
AbilityManagerComponent持有一个AbilityCoreData实例。 - 当玩家在升级时选择了
modifier_chain_reaction.tres,系统执行以下操作: - 获取
modifier_chain_reaction.tres中的effects_to_add_on_hit数组(即ChainReactionEffect.tres)。 - 将
ChainReactionEffect.tres添加到玩家当前AbilityCoreData实例的hit_effects数组中。 - 完成:从下一次攻击开始,当基础的
DamageEffect执行完毕后,框架会自动遍历并执行新添加的ChainReactionEffect,实现了能力的动态扩展,而无需编写任何if/else耦合代码。
目标:展示框架如何自动处理不同来源的属性加成,实现乘法效应,而无需为每种协同编写特定代码。
场景:玩家有两个独立的升级选项:“多重射击”(增加投射物数量)和“法术专注”(增加伤害和范围)。
-
升级A (
content/upgrades/upgrade_multishot.tres):- 效果:包含一个
StatModifier资源,其逻辑为ADDITIVE(加法),目标属性projectile_count,值+2。
- 效果:包含一个
-
升级B (
content/upgrades/upgrade_focus.tres):- 效果1:包含一个
StatModifier资源,其逻辑为MULTIPLICATIVE(乘法),目标属性damage_multiplier,值+0.2(即+20%)。 - 效果2:包含一个
StatModifier资源,其逻辑为MULTIPLICATIVE(乘法),目标属性area_size_multiplier,值+0.2(即+20%)。
- 效果1:包含一个
能力的核心脚本(例如 core_fireball.gd 的执行逻辑)在触发时不使用固定数值,而是向 StatsComponent 请求计算后的属性值:
# 伪代码:在法术执行时
var projectile_count: int = stats_component.get_stat_value("projectile_count")
var damage_amount: float = base_damage * stats_component.get_stat_value("damage_multiplier")
var area_size: float = base_area_size * stats_component.get_stat_value("area_size_multiplier")
for i in range(projectile_count):
# ... 发射投射物,并赋予其计算后的伤害和范围 ...当玩家同时拥有升级A和升级B时:
StatsComponent自动计算projectile_count为1 (基础) + 2 = 3。StatsComponent自动计算damage_multiplier为1.0 * 1.2 = 1.2。- 能力脚本读取这些新值,自动发射3个伤害和范围均提升20%的投射物。
- 结论:通过将状态管理(
StatsComponent)与逻辑执行分离,实现了不同升级间的自动协同,极大地提高了开发效率和玩法的丰富度。
目标:配置一个动态的、随时间增加难度的敌人生成流程。
创建一个 WaveProfile 资源来存储关卡的时间线。
# [`content/levels/wave_profiles/wave_profile_data.tres`](content/levels/wave_profiles/wave_profile_data.tres) 示例
# 该资源持有一个 [`WaveEvent`](lib/roguekit/game_flow/wave_event.gd) 资源数组
# (查看 `content/levels/wave_profiles/events/` 目录下的具体事件)
# [`event_start_grunt_spawn.tres`](content/levels/wave_profiles/events/event_start_grunt_spawn.tres) ([`WaveEvent`](lib/roguekit/game_flow/wave_event.gd))
@export var timestamp: float = 0.0
@export var action: WaveAction = WaveAction.START_SPAWNING
@export var enemy_data: EntityData
@export var spawn_rate: float = 2.0
@export var max_alive: int = 20
# [`event_modify_grunt_spawn.tres`](content/levels/wave_profiles/events/event_modify_grunt_spawn.tres) ([`WaveEvent`](lib/roguekit/game_flow/wave_event.gd))
@export var timestamp: float = 60.0
@export var action: WaveAction = WaveAction.MODIFY_SPAWN_RATE
@export var enemy_data: EntityData # 用于定位要修改的生成器
@export var new_spawn_rate: float = 3.0- 创建一个
WaveManager节点。 - 在游戏开始时加载对应的
WaveProfileData.tres。 - 在
_process函数中,根据游戏内的计时器game_time遍历timeline_events数组。 - 当
game_time达到事件的timestamp时,执行相应的action,调用Spawner节点来生成敌人或调整生成参数。
当标准组件无法满足特定需求时,您可以通过继承 RogueKit 的基类来创建自定义逻辑。这是推荐的扩展方式,因为它不会破坏库的封装性。
场景:您需要一个“吸血”效果,在造成伤害时按比例回复攻击者的生命值。内置的 StatModifier 无法处理这种情景交互。
工作流:
- 创建新脚本:创建一个新脚本文件(例如
effect_lifesteal.gd),使其继承自RogueKit的EffectData基类。 - 实现逻辑:重写
execute(context)方法。在此方法中,编写逻辑:- 从
context中获取造成伤害的数值damage_dealt。 - 从
context.attacker的StatsComponent中获取吸血率lifesteal_ratio。 - 计算回复量
heal_amount = damage_dealt * lifesteal_ratio。 - 调用
context.attacker.health_component.heal(heal_amount)。
- 从
- 配置使用:在 Godot 编辑器中创建该新脚本的资源实例(
.tres文件)。现在,您可以将这个“吸血效果”资源添加到物品或升级选项的effects数组中。
场景:您需要一个特殊的生成通道来在地图上放置河流,RogueKit 没有提供此算法。
工作流:
- 创建新脚本:创建一个新脚本文件(例如
river_generation_pass.gd),使其继承自GenerationPass基类。 - 实现逻辑:重写
generate(map_data)方法。在此方法中,实现您的河流生成算法(例如使用随机游走算法),修改传入的MapData对象,将对应坐标的瓦片类型设置为FLOOR。 - 配置使用:创建该脚本的资源实例后,将其拖拽到
MapGenerationProfile的通道数组中,与其他生成通道(如BSPTreePass)组合使用。
场景:AI 需要一个新的决策条件:“检查 3 格范围内是否有盟友”。
工作流:
- 创建新脚本:创建一个新脚本文件(例如
condition_check_nearby_allies.gd),使其继承自BehaviorNode基类。 - 实现逻辑:重写
tick()方法。编写逻辑来扫描周围区域,检查是否存在其他“盟友”标签的实体。根据检查结果返回Status.SUCCESS或Status.FAILURE。 - 配置使用:在 Godot 编辑器中,这个新创建的条件节点现在可以作为构建块,在
AIBehaviorProfile中与其他节点一起组装,以创建更复杂的 AI 逻辑。
为了保持清晰和可维护性,建议采用以下目录结构来分离库代码、项目内容和自定义扩展:
godot-project-root/
│
├── lib/
│ └── roguekit/ # RogueKit 库 (Git Submodule),不应修改内部文件。
│
├── content/ # 游戏内容配置层 (主要存放 .tres 资源)
│ ├── characters/ # 玩家角色数据 (CharacterData)
│ │
│ ├── abilities/ # 能力构筑相关
│ │ ├── cores/ # 法术核心 (AbilityCoreData)
│ │ └── modifiers/ # 法术修饰符 (AbilityModifierData)
│ │
│ ├── upgrades/ # 升级池中的升级选项 (UpgradeData)
│ │
│ ├── enemies/ # 敌人数据 (EntityData) 和 AI 配置 (AIBehaviorProfile)
│ │
│ ├── items/ # 局内外的物品数据 (ItemData)
│ │
│ └── levels/ # 关卡配置
│ ├── wave_profiles/ # 竞技场波次配置文件 (WaveProfileData)
│ └── loot_tables/ # 掉落表 (LootTable)
│
├── prefabs/ # 游戏场景预制件 (主要存放 .tscn 文件)
│ ├── entities/ # 玩家和敌人的场景文件
│ ├── abilities_vfx/ # 技能投射物、VFX等场景
│ └── ui/ # UI界面和组件场景
│
├── extensions/ # 自定义逻辑层 (主要存放 .gd 脚本)
│ ├── custom_effects/ # 继承自 EffectData 的脚本 (如 effect_lifesteal.gd)
│ ├── custom_ai_nodes/ # 继承自 BehaviorNode 的脚本
│ └── custom_components/ # 项目特定的新组件 (如 AbilityManagerComponent)
│
├── systems/ # 项目特定的管理器脚本 (例如 WaveManager, UpgradeManager)
└── project.godot