Reading and writing to and for a PackedByteArray (gdscript & c#)

Godot Version

4.3

Question

TL;DR at the bottom, most of this stuff I’ve figured out :point_down:

I’ve moved my game over to Godot from Unity and I’m having some trouble with reading and writing floating points and strings. Really not a fan of thePackedByteArray.

My client runs gdscript and my server is written in C# using vscode, and runs in a terminal or console.

I’m able to send integers to the server by first getting the size of the integer in bytes, writing that to a PackedByteArray followed by the actual integer that I want to send.
Then when the server receives it, it reads the first byte (the byte-count), then converts the following n number of bytes into that int type.

byte numBytesInNumeric = readBuffer[readPosition++];
switch(numBytesInNumeric) {
    case 1: 
        value = readBuffer[readPosition];
        break;
    case 2: 
        value = BitConverter.ToInt16(readBuffer, readPosition);
        break;
    case 4: 
        value = BitConverter.ToInt32(readBuffer, readPosition);
        break;
}

That works pretty well.

That strategy doesn’t quite work with floating point types though. I don’t quite understand how floats are represented in binary but if I remember right bits are shifted to the left-hand side leading a lot of zeros on the right. And I might be mistaken but I think a lot of those bytes are getting discarded by the PackedByteArray.

I understand there’s a PackedFloatArray and I could write to that then call to_byte_array, but I feel as though i’d still end up in the same place. Maybe I’m wrong, I’ll be sure to test it when I’m next at my computer.

My client is able to send String types to the server which can read those messages, but the client can’t read messages sent by the server.

Server:

public void WriteString( string input ) {
    //bufferList.AddRange( BitConverter.GetBytes( input.Length ) );
    bufferList.AddRange( Encoding.ASCII.GetBytes( input ) );
    bufferUpdate = true;

Client:

func read_string() -> String:
	var value = packet.get_string_from_ascii()
	index += 4
	return value

Maybe what I could do is have the server write the byte length and then have the client first read the length of bytes, then do something like packet.slice(index, byte_count).get_string_from_ascii()

TL;DR: How do I read a PackeByteArray in C# (not utilizing any godot library or extension), specifically a floating point.

alright, so I just discovered StreamPeerBuffer which inherits StreamPeer and has an internal “cursor”, so I can send a 32-bit type from the server and have the client read it even if the whole binary for it isn’t there because the PackedByteArray squashed the binary.
Now I just need to figure out how to read packed floating points on the server.

2 Likes