Skip to content

Packet Loss in unreliable UDP localhost #98143

Open
@TheYellowArchitect

Description

@TheYellowArchitect

Tested versions

  • Reproducible in 4.4 dev3 (and probably earlier versions)

System information

Godot v4.4.dev (0a9ad8f) - Artix Linux #1 SMP PREEMPT_DYNAMIC on Tty - X11 display driver, Multi-window, 1 monitor - OpenGL 3 (Compatibility) - NVIDIA GeForce GTX 1050 Ti (nvidia; 560.35.03) - AMD Ryzen 5 2600 Six-Core Processor (12 threads)

Issue description

I use an RPC with "unreliable" or "unreliable_ordered" mode. The channel doesn't matter.
The bug is that sometimes, some RPCs aren't received (aka packets are lost)
Now, that is normal because of UDP, but I am uncertain if this is the case because this is localhost.
As in, I have no LAN or wifi connected, and send just integers. I searched if UDP packets can drop at localhost and https://stackoverflow.com/questions/7968566/what-would-cause-udp-packets-to-be-dropped-when-being-sent-to-localhost#7968907 users claim yes at MB/s to overflow the buffer, but this isn't even 1 KB/s

Granted, packets dropping at localhost are rare, but it got me to wonder and at least want to report it in case there is some ENET initialization bug or something, given it often happens near the start of joining.
So feel free to close this issue without warning, as it is very likely a false flag.

As for my testing, this is a tldr video

unreliable-losing-packets.mp4

of the MRP. And I have to admit it takes like 5+ boots to get it to happen.

Steps to reproduce

  1. Open the MRP
  2. Press F5/F6
  3. Host as server
  4. Join as client
  5. Await a few seconds, if no errors, F8, repeat step 2 until you get an error.

Minimal reproduction project (MRP)

(The MRP is a tweak of a very old MRP made by @Mathis-Z)

mrp.zip

Its code is just 1 class with this code, posted below by filtering away the host/join code:

extends Node

var peer: ENetMultiplayerPeer = null

var last_tick: int = 0

func _process(delta: float):
	if peer and not multiplayer.is_server() and peer.get_connection_status() == ENetMultiplayerPeer.CONNECTION_CONNECTED:
		last_tick += 1
		set_num.rpc(last_tick)

@rpc("any_peer", "call_remote", "unreliable")
func set_num(tick: int):
	if tick != last_tick + 1:
		if tick < last_tick:
			push_error("SHUFFLED! Received tick %s while last tick is %s" % [tick, last_tick])
		else:
			push_error("Received tick %s while last tick is %s" % [tick, last_tick])
	last_tick = tick
	if multiplayer.is_server():
		print(tick)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions