WOW. I just learned a ton.
#1: I learned that I can serialize data with Godot’s built-in methods.
For strings, there’s to_utf8_buffer(), which was the example used in the documentation.
UTF stand for Unicode Transformation Format. I read the provided Wikipedia articles from the docs and it’s super interesting, as 99% of the internet is encoded using UTF-8, which cover 8-bit values across nearly all languages.
#2: I learned about serialization and deserialization as a concept.
Essentially, serializing data like strings and variables turns them into bytes to send over the network.
Deserialization is converting them back into useable information.
#3: I figured out why the Godot docs specifically say “DO NOT SERIALIZE OBJECTS”
For one, the object is likely too big to send in one packet and costs a lot of performance.
And two, it’s a massive security risk, as players can send anything directly into another player’s computer. Yikes.
#4: Sending a single packet is surprisingly simple. And a lot more interesting than a standard, abstracted RPC
I feel like the lower level I go and the less I let the engine abstract, the more power I truly have.
I felt the same way when I learned to use RPCs instead of the multiplayer spawner & synchronizer.
The best way I can describe it is using individual LEGO bricks instead of prebuilt pieces. With those smaller pieces, I can create what I want from them.
Ok, what PacketPeerUDP, I’ve created a new client/server setup.
My goal is to punch through one of my playtester’s routers to send a simple print message. The code is the following (Minus my IP and selected port):
var Server_Packet_Peer : PacketPeerUDP
var Client_Packet_Peer : PacketPeerUDP
func _ready() -> void:
set_process(false)
if OS.has_feature("dedicated_server"):
Server_Packet_Peer = PacketPeerUDP.new()
if not OS.has_feature("dedicated_server"):
Client_Packet_Peer = PacketPeerUDP.new()
Client_Packet_Peer.bind(Demetrius_Port)
set_process(true)
func _process(delta: float) -> void:
if OS.has_feature("dedicated_server"):
send_packet()
if not OS.has_feature("dedicated_server"):
receive_packet()
func send_packet() -> void:
if OS.has_feature("dedicated_server"):
Server_Packet_Peer.set_dest_address(Demetrius_Server_IP, Demetrius_Port)
Server_Packet_Peer.put_packet("Message Sent".to_utf8_buffer())
func receive_packet() -> void:
if not OS.has_feature("dedicated_server"):
if Client_Packet_Peer.get_available_packet_count() > 0:
var array_bytes := Client_Packet_Peer.get_packet()
var packet_string := array_bytes.get_string_from_ascii()
print("Received message: ", packet_string)
It works on my end, but I’ve learned that statement means NOTHING without other people’s input.
Now, I need to contact members of the Monkanics discord to test it. I’ll provide the client file to testers, while I spin up the server file.
I’d recommend all interested readers join the discord here:
Not only will you be able to test Monkanics when I have a build ready, but it’s also a chill place to hang out, talk about anything on your mind, and meme around. ![]()

