关于 godot-multiplayer
godot-multiplayer 是面向 Godot 4.7 联机游戏开发的技能,涵盖 ENet 连接、RPC、节点权限和状态复制,并说明如何在服务器端验证客户端输入。
主要功能
- 01配置 ENet 主机与客户端
- 02使用 @rpc 调用远程函数
- 03分配节点级权限
- 04跨节点生成场景并同步状态
- 05在服务器端验证输入
适用场景
- 01添加在线创建或加入游戏
- 02将玩家输入发送到服务器
- 03在各对等端生成节点
- 04同步选定的节点属性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill godot-multiplayer安装后在 Claude Code 中输入/godot-multiplayer确认已加载。
附带文件references/replication-and-rpc.md
详细介绍
Godot Multiplayer(4.x 高级)
连接对等方,使用 @rpc 远程调用函数、分配权限,并通过 MultiplayerSpawner/MultiplayerSynchronizer 复制状态。目标版本为 Godot 4.7(ENet)。将所有客户端输入视为不可信;保持服务器权威。
适用场景
- 添加网络多人游戏功能时使用:通过 ENet 创建或加入游戏、调用 RPC、分配节点权限,或在对等方之间自动生成/同步节点。
不适用场景: 本地分屏(无网络);原始 TCP/UDP/WebSocket 协议处理(低级 PacketPeer);HTTP 请求。保存/持久化请参阅 save-systems。
核心工作流
- 创建对等方(
ENetMultiplayerPeer),调用create_server(port, max)或create_client(ip, port),并将其赋给multiplayer.multiplayer_peer。服务器的唯一 ID 始终为1;客户端会获得随机的正 ID。 - 处理
multiplayer上的连接信号:peer_connected(id)、peer_disconnected(id)、connected_to_server、connection_failed、server_disconnected。 - 定义 RPC,使用
@rpc(...)。通过Callable调用rpc()(所有对等方)或rpc_id(peer_id)(单个对等方)。在函数内部,multiplayer.get_remote_sender_id()可告诉你 发送者是谁。 - 确保每个运行该脚本的对等方上的 RPC 签名完全一致——Godot 会校验脚本中所有
@rpc方法的校验和;不匹配时会静默失效。 - 为每个节点分配权限,使用
set_multiplayer_authority(id);通过is_multiplayer_authority()限定输入/RPC。 - 复制状态,使用
MultiplayerSpawner(在客户端自动实例化场景)和MultiplayerSynchronizer(自动同步选定属性)。 - 在服务器上进行验证。 不要信任客户端上报的位置/结果。
常用模式
1. 创建主机或加入游戏(ENet)
const PORT := 7000
const MAX_PLAYERS := 8
func host() -> void:
var peer := ENetMultiplayerPeer.new()
var err := peer.create_server(PORT, MAX_PLAYERS)
if err != OK:
push_error("Cannot host: %s" % err); return
multiplayer.multiplayer_peer = peer
multiplayer.peer_connected.connect(_on_peer_connected)
func join(ip := "127.0.0.1") -> void:
var peer := ENetMultiplayerPeer.new()
peer.create_client(ip, PORT)
multiplayer.multiplayer_peer = peer
multiplayer.connected_to_server.connect(func(): print("connected"))
func leave() -> void:
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
2. RPC:客户端向服务器发送输入(any_peer、call_local)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("fire") and is_multiplayer_authority():
request_fire.rpc_id(1) # send only to the server (id 1)
# Clients may call this; it runs on the server (and locally if server is a player).
@rpc("any_peer", "call_local", "reliable")
func request_fire() -> void:
var sender := multiplayer.get_remote_sender_id()
if not _can_fire(sender): # server-side validation
return
spawn_projectile.rpc(sender) # tell everyone to spawn it
@rpc("authority", "call_local", "reliable")
func spawn_projectile(owner_id: int) -> void:
_do_spawn(owner_id)
3. 节点级权限(每个玩家控制自己的角色)
extends CharacterBody2D
func _ready() -> void:
# The node name is the owning peer's id; that peer is the authority.
set_multiplayer_authority(name.to_int())
func _physics_process(delta: float) -> void:
if not is_multiplayer_authority():
return # only the owner reads input & moves
velocity = Input.get_vector("left", "right", "up", "down") * 200.0
move_and_slide()
4. MultiplayerSynchronizer 配置(编辑器 + 复制)
# Add a MultiplayerSynchronizer child; in its Replication editor add the properties to
# sync (e.g. position, velocity). Set "Sync"/"Spawn" flags per property. From code you
# can scope visibility:
@onready var sync: MultiplayerSynchronizer = $MultiplayerSynchronizer
func _ready() -> void:
# Only replicate this node to a specific peer (e.g. private info).
sync.set_visibility_for(target_peer_id, true)
注意事项
- RPC 签名校验和。 脚本中的每个
@rpc方法都必须在客户端和服务器构建中存在且声明相同——即使从未使用。不匹配会导致报错,且错误信息可能指向错误的函数。不会检查参数名称/数量,但会检查 RPC 集合及其注解。 @rpc的默认值为"authority"。 除非设置"any_peer",否则客户端调用会被忽略。使用"call_local",以便主机(也是一名玩家)也能运行该函数。- 各对等方的 NodePath 必须一致。 RPC 路由使用节点的路径/名称;在所有对等方上生成名称相同的节点(使用
MultiplayerSpawner,或通过add_child(node, true)创建可读且确定的名称)。 - 不要信任客户端。 绝不能让客户端直接设置权威状态(生命值、位置、命中情况)。发送意图,由服务器验证,然后广播结果。
- 在非 Node 类上使用 RPC 会失败。
@rpc方法必须属于派生自Node的类,不能属于普通的Resource/RefCounted。 - RPC 不会序列化 Objects/Callables。 请传递普通数据(整数、字符串、数组、字典、PackedArrays)。
- 不要忘记重置对等方。 若要干净地断开连接,请设置
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()。 - Android 需要在导出预设中启用 INTERNET 权限,否则所有网络功能都会被阻止。
参考资料
- 有关
MultiplayerSpawner设置、传输模式/通道、SceneMultiplayer身份验证 (auth_callback/complete_auth)、大厅框架以及专用服务器导出说明,请阅读references/replication-and-rpc.md。
相关技能
godot-nodes-scenes— 实例化要生成/同步的场景。godot-signals-groups— 连接信号和事件流。godot-export— 导出无头专用服务器构建。
评论
支持 Markdown