1
0
mirror of https://github.com/godotengine/godot.git synced 2026-01-05 19:31:35 +00:00

GDScript: Fix incorrect default transfer_mode for @rpc annotation

The `@rpc` annotation was registered with "unreliable" as the default
transfer_mode, but the runtime (SceneRPCInterface) defaults to
TRANSFER_MODE_RELIABLE. This caused a mismatch between the documented
default and the actual behavior when using Node.rpc_config().

Changed the parser default to "reliable" to match the runtime behavior
and C# RpcAttribute. Added comments in all three locations to help
prevent future drift.

Fixes godotengine/godot-docs#8874
Related docs fix: godotengine/godot-docs#11554
This commit is contained in:
Max Aller
2025-12-21 12:00:36 -08:00
committed by Rémi Verschelde
parent 7692a3d53b
commit e304b4e43e
3 changed files with 6 additions and 3 deletions

View File

@@ -788,7 +788,7 @@
<return type="void" />
<param index="0" name="mode" type="String" default="&quot;authority&quot;" />
<param index="1" name="sync" type="String" default="&quot;call_remote&quot;" />
<param index="2" name="transfer_mode" type="String" default="&quot;unreliable&quot;" />
<param index="2" name="transfer_mode" type="String" default="&quot;reliable&quot;" />
<param index="3" name="transfer_channel" type="int" default="0" />
<description>
Mark the following method for remote procedure calls. See [url=$DOCS_URL/tutorials/networking/high_level_multiplayer.html]High-level multiplayer[/url].
@@ -804,7 +804,7 @@
@rpc("any_peer", "unreliable_ordered")
func fn_update_pos(): pass
@rpc("authority", "call_remote", "unreliable", 0) # Equivalent to @rpc
@rpc("authority", "call_remote", "reliable", 0) # Equivalent to @rpc
func fn_default(): pass
[/codeblock]
[b]Note:[/b] Methods annotated with [annotation @rpc] cannot receive objects which define required parameters in [method Object._init]. See [method Object._init] for more details.

View File

@@ -186,7 +186,8 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@warning_ignore_start", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::STANDALONE, &GDScriptParser::warning_ignore_region_annotations, varray(), true);
register_annotation(MethodInfo("@warning_ignore_restore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::STANDALONE, &GDScriptParser::warning_ignore_region_annotations, varray(), true);
// Networking.
register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("authority", "call_remote", "unreliable", 0));
// Keep in sync with `rpc_annotation()` and `SceneRPCInterface::_parse_rpc_config()`.
register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("authority", "call_remote", "reliable", 0));
}
#ifdef DEBUG_ENABLED
@@ -5199,6 +5200,7 @@ bool GDScriptParser::rpc_annotation(AnnotationNode *p_annotation, Node *p_target
return false;
}
// Default values should match the annotation registration defaults and `SceneRPCInterface::_parse_rpc_config()`.
Dictionary rpc_config;
rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
if (!p_annotation->resolved_arguments.is_empty()) {

View File

@@ -84,6 +84,7 @@ void SceneRPCInterface::_parse_rpc_config(const Variant &p_config, bool p_for_no
ERR_CONTINUE(config[name].get_type() != Variant::DICTIONARY);
ERR_CONTINUE(!config[name].operator Dictionary().has("rpc_mode"));
Dictionary dict = config[name];
// Default values should match GDScript `@rpc` annotation registration and `rpc_annotation()`.
RPCConfig cfg;
cfg.name = name;
cfg.rpc_mode = ((MultiplayerAPI::RPCMode)dict.get("rpc_mode", MultiplayerAPI::RPC_MODE_AUTHORITY).operator int());