Hello! I am trying to make a game controlled by a custom controller. For this, I use an arduino to give input to a python script which gives the data to a godot script using UDP. With a lot of help I have scrambled together a script that accomplishes that, but I would like to be able to send data from godot to python and then to the arduino too (for example the player's character died, so the player can't shoot until they respawn). Whatever I tried didn't work, so here is the scripts so far, in case anyone can help me.
gdscript:


 extends Node
 
 # Configure the UDP socket for receiving data from Python
 var python_address : String = "127.0.0.1"
 var python_port : int = 12345
 var python_socket := PacketPeerUDP.new()
 var data_list
 var begin = false
 
 func _ready():
 	# Bind the socket to the specified address and port
 	python_socket.bind(python_port, python_address)
 
 func _process(delta):
 	# Check for incoming data
 	if python_socket.get_available_packet_count() > 0:
 		# Receive data from Python
 		#var data : PacketPeerUDP = python_socket.get_packet()
 		var data = python_socket.get_packet()
 		print(data)
 		# Process the received data as needed
 		var decoded_data : String = data.get_string_from_utf8()
 		
 		data_list = decoded_data.split(",")
 		#print(data_list)
 		begin = true

python:


import serial
from serial import Serial
from pynput.mouse import Button, Controller
from socket import socket, AF_INET, SOCK_DGRAM
m_left = False
m_right = False
godot_address = ('127.0.0.1', 12345)  # Adjust the IP and port as needed
godot_socket = socket(AF_INET, SOCK_DGRAM)
try:
       # Setting Serial port number and baudrate
	ser = serial.Serial('COM4', 9600)
except:
	print("Mouse not found or disconnected.")
	k=input("Press any key to exit.")
mouse = Controller()
while True:
	try:
		dump = ser.readline()                           # Reading Serial port
		dump = str(dump)                                # Converting byte data into string
		dump = dump[2:-5]                               # Cleaning up the raw data recieved from serial port
		data = dump.split(',')                          # Spliting up the data to individual items in a list. the first item being the data identifier
		print(data)   
		data_bytes = ','.join(data).encode('utf-8')        
		godot_socket.sendto(data_bytes, godot_address)            
	except (ValueError, IndexError):
		pass

P.S.: I know there are better ways to do this (with gdnative for example), but this is the simplest one. I use godot 4.1

  • xyz replied to this.

    Is this the simplest way? A GDExtension (GDNative's successor) would be straightforward. I'd be surprised if someone hasn't already even made one to enable arbitrary Python execution. Sorry, but you're probably going to have a hard time finding someone who has done specifically what you're trying to do here on this forum.

      Looking at your scripts more closely, I don't see anything even trying to communicate from Godot to Python?

      award I didnt have much luck finding straightforward tutorials about gdextension, but maybe I didn't search a lot. Also, yes there is no code for sending data from godot to python, since non of my attempts even remotely work. I guess if there is a way to send messages from a godot client to a godot server, it would work for my case (put_packet() didnt work)

      PaulosK didn't work

      What do you mean didn't work? What happened? Any errors? What's preventing you from just sending data through the socket?

        xyz
        godot:

        extends Node
        
        # Configure the UDP socket for receiving data from Python
        var python_address : String = "127.0.0.1"
        var python_port : int = 12345
        var python_socket := PacketPeerUDP.new()
        var data_list
        var begin = false
        
        func _ready():
        	# Bind the socket to the specified address and port
        	python_socket.bind(python_port, python_address)
        
        func _process(delta):
        	# Check for incoming data
        	if python_socket.get_available_packet_count() > 0:
        		# Receive data from Python
        		#var data : PacketPeerUDP = python_socket.get_packet()
        		var data = python_socket.get_packet()
        		print(data)
        	if Input.is_action_just_pressed("enter"):
        		var a : PackedByteArray = [1]
        	
        		python_socket.put_packet(a)

        python:

        import socket
        import time
        # Server configuration
        server_address = ('127.0.0.1', 12345)
        
        # Create a socket
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        
        # Bind the socket to a specific address and port
        server_socket.bind(server_address)
        
        # Listen for incoming connections
        server_socket.listen()
        # Handle incoming data
        print(f"Server listening on {server_address}")
        
        # Accept a connection from the client
        client_socket, client_address = server_socket.accept()
        print(f"Connection established with {client_address}")
        
        while True:
                # Receive data from the client
                data = client_socket.recv(1024)
                if not data:
                    break
                print(f"Received from client: {data.decode('utf-8')}")
        
                # Send a response back to the client
                response = "Hello from server!"
                client_socket.send(response.encode('utf-8'))

        I tried the python code with a python client and it work. The error from godot's side is this:
        E 0:01:25:0032 global.gd:24 @ _process(): Condition "!peer_addr.is_valid()" is true. Returning: ERR_UNCONFIGURED
        <C++ Source> core/io/packet_peer_udp.cpp:123 @ put_packet()
        <Stack Trace> global.gd:24 @ _process()

        • xyz replied to this.

          PaulosK Have you tried connect_to_host() instead of bind()?

            xyz I just tried, godot doesn't even get the message from python

            • xyz replied to this.

              PaulosK Does it return an error? What's the error code? What's the error code returned by put_packed(). Check all the error codes returned by functions you use.

                xyz connect_to_host doesnt return an error code, it just doesnt connect. i tried it at code i knew was working and it didnt work. The pu_packet() return this error:
                E 0:01:25:0032 global.gd:24 @ _process(): Condition "!peer_addr.is_valid()" is true. Returning: ERR_UNCONFIGURED
                <C++ Source> core/io/packet_peer_udp.cpp:123 @ put_packet()
                <Stack Trace> global.gd:24 @ _process()

                • xyz replied to this.

                  PaulosK connect_to_host doesnt return an error code, it just doesnt connect

                  Doesn't return or doesn't print? Do you explicitly test the return value? Let's see the exact code. Also try it with set_dest_address()