Skip to content

Add UDPServer::get_packet() method for stateless UDP packet reception #12733

Open
@not-my-username

Description

@not-my-username

Describe the project you are working on

A peer to peer mesh networking system for communication between many nodes in a network

Describe the problem or limitation you are having in your project

In my project, I’m using Godot's UDPServer to receive stateless UDP messages, such as device discovery packets or one-shot control messages, from many remote IP/port pairs.

However, UDPServer::poll() automatically creates a PacketPeerUDP for each new sender and stores it in the pending connections list. This results in unnecessary memory usage and resource retention, even when I only need to receive a single packet from a sender and have no intention of maintaining a connection.

Additionally, I’m required to store a reference to every PacketPeerUDP and manually check each one for new packets — even for senders that only send one message and then exit. Since UDP is connectionless, there's no reliable way to detect when a remote sender has gone offline, which means these PacketPeerUDP instances remain active and are checked every frame, even if they’re no longer useful.

Currently, there’s no way to simply receive a raw UDP packet along with the sender’s IP and port without triggering this overhead. This makes UDPServer inefficient and cumbersome to use.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I propose adding a pair of new methods to the UDPServer class for lightweight, stateless access to incoming packets:

UDPServer.is_data_available() -> bool
UDPServer.get_packet_peer() -> PacketPeerUDP
  • is_data_available() returns true if a new UDP packet is waiting to be read.

  • get_packet_peer() returns a temporary PacketPeerUDP instance populated with the received data and the sender's IP and port.

  • This peer is not added to the pending list, and the server does not retain any reference to it — the user handles it manually.

This enhancement addresses the limitations of the current system by allowing efficient processing of stateless UDP messages (e.g. discovery, one-shot control packets) without triggering persistent memory allocations or tracking peer state.

Importantly, this proposal does not break compatibility with the existing poll() and PacketPeerUDP-based workflow. That system remains useful and appropriate for use cases where:

  • Stateful communication is desired.
  • Packet queuing and per-peer abstraction is
  • Reliable long-lived UDP peer tracking is needed.

This addition simply provides an alternative pathway better suited to stateless or high-throughput networking patterns, while preserving the strengths of the current design.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

var udp_server = UDPServer.new()
udp_server.listen(12345)

func _process(delta):
    while udp_server.is_data_available():
        var packet_peer = udp_server.get_packet_peer()
        
        # Read the raw packet data as a PackedByteArray
        var data = packet_peer.get_packet()
        
        # Get sender info
        var sender_ip = packet_peer.get_packet_ip()
        var sender_port = packet_peer.get_packet_port()
        
        print("Received packet from: ", sender_ip, ":", sender_port, " size: ", data.size(), " bytes")
        
        # Process the packet however you want here, or discard it
        _handle_packet(data, sender_ip, sender_port)

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not with out causing the same issue this proposal aims to resolve

Is there a reason why this should be core and not an add-on in the asset library?

Without writing your own custom UDP server in another language, this can't be worked around with an add-on

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