mcpField
G
godot-genre-moba

godot-genre-moba

github.com/thedivergentai开发928240 次安装3 周前更新
代码仓库

关于 godot-genre-moba

面向 Godot MOBA 游戏开发的技能,提供涵盖战斗、兵线、防御塔、战争迷雾和联网的脚本与实现指导。适用于单路原型和服务器权威的多人设计。

主要功能

  1. 01权威式兵线同步
  2. 02防御塔目标优先级逻辑
  3. 03战争迷雾视野检查与网格遮罩
  4. 04技能射击指示器与技能控制
  5. 05分帧寻路与工作线程任务

适用场景

  1. 01制作单路和兵线原型
  2. 02实现服务器权威的 5v5 对局
  3. 03构建防御塔仇恨与越塔规则
  4. 04添加战争迷雾和技能射击瞄准

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/thedivergentai/game-design-agentic-skills --skill godot-genre-moba

安装后在 Claude Code 中输入/godot-genre-moba确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
migration-notes.md
moba-meta-systems-deep.md
scripts/
ability_ui_binder.gd
async_arena_baker.gd
decoupled_ability_damage.gd
fog_grid_mask.gd
fog_visibility_check.gd
hero_net_sync.gd
hero_state_machine.gd
jungle_creep.gd
minion_flow_calculator.gd
minion_worker_pathfinder.gd
replay_manager.gd
server_minion_sync.gd
skill_shot_indicator.gd
status_effect_data.gd
status_effect_manager.gd
synced_ability_controller.gd
tower_priority_aggro.gd
weighted_target_selector.gd

详细介绍

绝对不要做(专家级反模式)

网络与权威性
  • 绝不要信任客户端进行伤害计算或资源消耗判定;必须使用 multiplayer.is_server(),在权威服务器上严格验证法力值、范围和命中检测。
  • 绝不要将 TRANSFER_MODE_RELIABLE 用于连续移动;必须对位置/速度使用 UNRELIABLE 或 UNRELIABLE_ORDERED,以防网络拥塞。
  • 绝不要以 60 Hz 同步单位;必须通过 MultiplayerSynchronizer 使用较低的 tick 频率(10-20 Hz),并实现插值/客户端预测以确保画面流畅。
  • 绝不要给数百个小兵逐个添加同步器;必须通过中央管理器将状态更新批量压缩为字节数组。
  • 绝不要直接同步复杂的 Engine 对象;必须将状态序列化为基本属性或 Dictionary,以实现可靠的点对点同步。
AI 与寻路
  • 绝不要每帧为所有小兵执行开销巨大的寻路;必须使用时间分片,将 get_next_path_position() 调用分散到多帧中。
  • 绝不要在 _process() 中查询 NavigationAgent 路径;必须使用 _physics_process() 与导航服务器和避障系统交互。
  • 绝不要使用复杂的视觉几何体进行 NavMesh 烘焙;应解析简单图元,以避免阻塞 RenderingServer 或导致引擎崩溃。
  • 绝不要在大型地图中将 path_search_max_polygons 设得过低;如果达到上限时尚未抵达目的地,Agent 就会停下或走错方向。
  • 绝不要使用 Area2D 实现高性能战争迷雾视线检测;必须使用无节点的物理查询(intersect_ray),以绕过节点开销。
游戏玩法与平衡
  • 绝不要忘记防御塔的“Dive”保护;如果敌方英雄在范围内对友方英雄造成伤害,防御塔必须立即切换目标(优先级:攻击友方英雄的敌方英雄 > 小兵 > 英雄)。
  • 绝不要让“滚雪球”效应没有反制手段;必须严格实现逆风追赶机制(击杀赏金、追赶经验),以保持竞技张力。
  • 绝不要将英雄属性作为标准 Node 变量管理;必须使用自定义 Resource 脚本分离数据并提高内存效率。
  • 绝不要忘记对共享的技能 Resource 调用 duplicate(true);修改共享资源上的增益效果会影响所有英雄。
技术与性能
  • 绝不要使用普通字符串检查状态(例如 "stunned");必须使用 StringName(&"stunned")进行指针级速度的比较。
  • 绝不要使用浮点数遍历大型战争迷雾网格;必须使用 Vector2i 和 TileMapLayer,以避免精度抖动。
  • 绝不要在主线程执行繁重的世界/小地图逻辑;必须将复杂的数组运算转交给 WorkerThreadPool,以维持 60 FPS 以上的帧率。
  • 绝不要将 UI 冷却时间与英雄脚本紧密耦合;必须使用 Signal Bus 或 Callable 绑定实现解耦架构。
  • 绝不要判断浮点数是否完全相等(==);必须使用 is_equal_approx() 验证范围、冷却时间和法力值。

决策树:单人原型还是权威 5v5

目标优先加载跳过/延后
单人对线原型(1 名英雄、本地兵线、没有其他玩家)tower_priority_aggro.gd、weighted_target_selector.gd、skill_shot_indicator.gd、hero_state_machine.gdserver_minion_sync、完整战争迷雾网格、预测
权威 5v5(专用服务器/监听服务器)server_minion_sync.gd、synced_ability_controller.gd、fog_visibility_check.gd + fog_grid_mask.gd、minion_worker_pathfinder.gd客户端可信伤害、每个小兵一个 MultiplayerSynchronizer
对等技能godot-multiplayer-networking、godot-navigation-pathfinding、godot-ability-system在这种类型的技能中另造一套网络堆栈

🛠 专家组件(scripts/)

原创专家模式
模块化组件
  • server_minion_sync.gd - 使用压缩字节数组对大量单位进行权威同步。5v5 兵线必需(不要为每个小兵单独使用一个同步器)。
  • fog_visibility_check.gd - 通过物理射线投射实现高性能视线检测。在绘制战争迷雾遮罩前必需。
  • fog_grid_mask.gd - 使用 Vector2i 网格逻辑、由 TileMap 驱动的可见性遮罩系统。
  • minion_worker_pathfinder.gd - 何时加载: 当兵线规模导致 _physics_process 中的寻路负担过重时,使用 WorkerThreadPool 批量处理路径。优先于每帧对每个小兵执行完整 A*。
  • weighted_target_selector.gd - 何时加载: 英雄/小兵/防御塔按群组加权优先级获取目标(普攻和简单仇恨)。与 tower_priority 搭配使用以实现塔下强攻规则。
  • synced_ability_controller.gd - 何时加载: 在权威模式下施放 QWER 技能——客户端预测冷却时间 UI,服务器负责验证。离线原型可跳过。
  • status_effect_data.gd - 用于定义增益、减益和眩晕的轻量级 Resource 容器。
  • status_effect_manager.gd - 用于应用和管理独立状态效果实例的模块化逻辑。
  • decoupled_ability_damage.gd - 使用安全的鸭子类型模式实现英雄间战斗交互。
  • hero_state_machine.gd - 基于 StringName、经过优化的英雄逻辑状态机。
  • async_arena_baker.gd - 用于动态竞技场的后台线程安全导航网格更新。
  • ability_ui_binder.gd - 基于信号的 UI 解耦,用于追踪技能冷却时间。
  • minion_flow_calculator.gd - 使用 WorkerThreadPool 并行处理寻路和智能逻辑。
  • replay_manager.gd - 使用二进制 var_to_bytes 存储对局回放帧(而非 JSON)。
  • hero_net_sync.gd - 通过物理插值 + MultiplayerSynchronizer,在低频率下同步英雄。
  • jungle_creep.gd - 野怪营地的牵引范围状态机(FSM)——超出 leash_radius 后无敌并返回营地。

核心循环

  1. 对线:玩家在指定线路击杀小兵,获取金币和经验。
  2. 换血:玩家与敌方英雄互相造成伤害。
  3. 游走支援:玩家前往其他线路,出其不意地袭击敌人。
  4. 推进:团队摧毁防御塔,打开地图。
  5. 终结:摧毁敌方核心/水晶枢纽。

技能链

阶段技能用途
1. 操控rts-controls右键移动、A 键移动、停止
2. AIgodot-navigation-pathfinding小兵波次、防御塔仇恨逻辑
3. 战斗godot-ability-system、godot-rpg-statsQWER 技能、冷却时间、数值成长
4. 网络godot-multiplayer-networking权限控制、延迟补偿、预测
5. 地图godot-3d-world-building线路、野区、河道、基地
6. 平衡godot-monte-carlo-balancer英雄/非对称性矩阵(不能只覆盖从挂机玩家到职业玩家的范围)

架构概览

1. 线路/小兵波次(权威端)

不要临时编写 lane_manager/minion_ai 示例。

必读:server_minion_sync.gd,用于批量同步波次状态;当 Agent 数量需要使用 WorkerThreadPool 时,阅读 minion_worker_pathfinder.gd;阅读 weighted_target_selector.gd,了解行军→战斗目标的选择。生成节奏应由服务器上的数据/计时器驱动;客户端根据同步数组进行渲染。

2. 防御塔仇恨逻辑

优先级:攻击友方的英雄 > 攻击友方英雄的单位 > 最近的小兵 > 最近的英雄。

必读:tower_priority_aggro.gd。结合 weighted_target_selector.gd,按组别确定优先级。

3. 战争迷雾

必读:fog_visibility_check.gd,用于无节点 LoS;将结果绘制到 fog_grid_mask.gd 中。绝不要将 Area2D 重叠检测用作战争迷雾判定依据。

4. 指向性技能循环

“QWER”瞄准的实现模式:

  1. 待机:等待输入。
  2. 预告:按住鼠标时显示指示器(skill_shot_indicator.gd)。
  3. 生效:松开鼠标时生成命中框/投射物——在多人游戏中,通过 synced_ability_controller.gd 处理。
  4. 恢复:短暂的后摇动画,期间锁定移动/施法。

关键机制实现

点击移动(RTS 风格)

从摄像机向地形进行射线检测。

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("move"):
        var result = raycast_from_mouse()
        if result:
            nav_agent.target_position = result.position
技能系统(数据驱动)

无需为每个技能编写独立脚本,即可定义“火球”或“钩子”。

# ability_data.gd
class_name Ability extends Resource
@export var cooldown: float
@export var mana_cost: float
@export var damage: float
@export var effect_scene: PackedScene

Godot 专属技巧

  • NavigationAgent3D:为小兵启用 avoidance_enabled,让它们像水流一样彼此绕行,而不是堆叠在一起。
  • MultiplayerSynchronizer:同步生命值、法力值和冷却时间。如果使用客户端预测(高级),不要逐帧同步位置。
  • 战争迷雾:使用带有迷雾纹理的 SubViewport。在盟友所在位置于纹理上绘制“空洞”,再将此纹理投射到地形着色器上。

常见问题

  1. 滚雪球:获胜队伍过快变得过于强大。解决方法:加入“翻盘经验/金币”机制(赏金)。
  2. 寻路延迟:100 个小兵每帧都在寻路。解决方法:将寻路更新分散到多个帧中(分时处理)。
  3. 作弊:客户端声称“我造成了 1000 点伤害”。解决方法:客户端只发送“我朝方向 V 施放了技能 Q”,由服务器计算伤害。

MOBA 高级元系统

专业实现对局回放、网络平滑处理和高级野区 AI。

1. 对局回放系统(二进制序列化)

为了高性能地录制对局,使用 var_to_bytes() 将状态字典序列化为压缩的二进制格式。回放应避免使用 JSON,以尽量减少磁盘 I/O 和文件大小。

class_name ReplayManager extends Node

var frame_history: Array[PackedByteArray] = []

func record_frame(state: Dictionary) -> void:
    # Efficiently convert data to bytes
    frame_history.append(var_to_bytes(state))

func save_replay(match_id: String) -> void:
    var file := FileAccess.open("user://replays/" + match_id + ".dat", FileAccess.WRITE)
    if file:
        file.store_var(frame_history) # Stores the whole array as a variant
        file.close()

func play_frame(frame_index: int) -> Dictionary:
    return bytes_to_var(frame_history[frame_index])
2. 网络插值同步

使用 Godot 4.x 内置的物理插值来掩盖网络抖动。结合 MultiplayerSynchronizer,即使在较低的 tick 速率(15-20Hz)下,也能让英雄移动保持流畅。

class_name HeroNetSync extends CharacterBody3D

func _ready() -> void:
    # Enable native engine interpolation for visual smoothness
    physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_ON
    
    if is_multiplayer_authority():
        setup_synchronizer()

func setup_synchronizer() -> void:
    var sync := $MultiplayerSynchronizer
    var config := SceneReplicationConfig.new()
    # Sync position/rotation via unreliable ordered packets
    config.add_property(NodePath(".:global_position"))
    sync.replication_config = config
3. 丛林 AI(营地脱战)

为丛林怪物实现一个状态机,监控它们与出生点的距离。如果英雄将它们引得太远,它们就会进入“脱战”状态,获得无敌效果并返回出生点。

class_name JungleCreep extends CharacterBody3D

@export var leash_radius: float = 12.0
@onready var spawn_pos := global_position

func _physics_process(_delta: float) -> void:
    var dist_from_home := global_position.distance_to(spawn_pos)
    
    match state:
        State.CHASING:
            if dist_from_home > leash_radius:
                state = State.LEASHING
        State.LEASHING:
            # Move back to spawn_pos using NavigationAgent3D
            nav_agent.target_position = spawn_pos
            if global_position.distance_to(spawn_pos) < 1.0:
                state = State.IDLE
                health = max_health # Reset health on return

专家提示:生成后允许 AI 寻路前,务必使用 NavigationServer3D.map_get_iteration_id() 确保导航地图已完全同步。

必须阅读,以深入了解决策树和脚本目录之外的内容:moba-meta-systems-deep.md。首次接线时不要加载——请先使用打包的 scripts/。

参考资料

渐进式展开:仅在研究特定 API 时打开官方文档链接; 在将工作路由到相关领域时加载相关技能——不要预加载整个技能体系。

官方文档
  • 高级多人游戏 — 了解权限、RPC 和传输模式,用于经服务器验证的施法和不可靠移动。
  • MultiplayerSynchronizer — 了解英雄生命值/法力值/冷却时间的属性复制,避免为每个小兵都添加同步器。
  • SceneReplicationConfig — 了解与低 tick 速率英雄同步配合时,哪些属性会复制以及复制频率。
  • 使用导航代理 — 了解点击移动、小兵推进和避让,实现兵线流动且避免堆叠。
  • 使用导航网格 — 了解如何烘焙兵线、丛林和基地,以及在竞技场几何结构变化时进行异步重新烘焙。
  • 优化导航性能 — 了解数百个小兵每波寻路时的分时处理和代理预算。
  • 射线投射 — 了解通过直接空间状态射线实现点击地面拾取和无节点战争迷雾视线检测。
  • 物理插值简介 — 了解网络同步以 10–20 Hz 运行时,如何让英雄画面保持流畅。
  • 使用视口 — 了解如何使用 SubViewport 战争迷雾遮罩和根据盟友视野绘制小地图投影。
  • 使用多线程 — 了解如何使用 WorkerThreadPool 模式在主线程之外处理小兵批量逻辑。
  • 资源 — 了解使用 duplicate(true) 创建技能/状态 Resource 数据,避免增益效果修改共享模板。
  • 鼠标和输入坐标 — 了解如何进行屏幕→世界坐标映射,以实现技能射击指示器和 RTS 风格的移动指令。
相关技能
前置技能
补充技能
  • godot-ability-system — 数据驱动的 QWER 冷却时间、消耗和效果场景,并接入权威施法验证。
  • godot-rpg-stats — 英雄成长、护甲/魔抗类修正,以及供防御塔和技能读取的 Resource 支持属性。
  • godot-combat-system — 为技能射击、普通攻击和防御塔攻击提供命中/受击约定,无需强耦合类。
  • godot-raycasting-queries — 更深入的空间状态方案,用于战争迷雾视线检测、越塔检查和高负载下的点击拾取。
  • godot-signal-architecture — 解耦技能 UI 绑定器和施法总线,避免冷却时间写入英雄战斗脚本。
  • godot-3d-world-building — 与导航网格烘焙表面匹配的兵线通道、野区几何结构和碰撞设置。
  • godot-performance-optimization — 当小兵同步数组或战争迷雾网格影响帧时间时进行性能分析和批处理。
  • godot-genre-rts — 借鉴 RTS 控制体验打造 MOBA 英雄玩法时,可复用点击移动、选择和战争迷雾遮罩模式。
下游/使用方
  • godot-adapt-single-to-multiplayer — 将单人兵线原型扩展为本类型游戏所需的大厅、权威控制和预测流程。
  • godot-monte-carlo-balancer — 英雄非对称性、击杀赏金和追赶经验矩阵——模拟对局胜率,而非只模拟从挂机玩家到职业玩家的 PvE 区间。
主索引
  • godot-master — 资料库路由器和镜像入口,用于在相关领域中查找 MOBA 模式。

评论

支持 Markdown