GameMaker:Studio Basic UDP

I’m writing this because, as far as I can tell, nobody else has. It’s non-comprehensive and probably inaccurate, its only purpose is to explain the minimum necessary setup for UDP communication in GM:S. I learned this yesterday, fair warning.

Example project file.

What’s a UDP?

Here’s a detailed comparison of TCP vs UDP. Long story short: TCP is crap for time-sensitive communication over the internet (i.e most games), use UDP instead.

What do I need for a UDP?

GameMaker has a whole lot of network functions, but for extremely basic UDP functionality, you only need 2:

-network_create_socket_ext

-network_send_udp

Plus some of the buffer functions for reading and writing packets.

How do I UDP?

Unlike TPC, which has servers and connections and junk, UDP just has sockets. What’s a socket? It’s a thing that lets you send and receive packets through a port. What’s a port? It’s a magic, numbered door that your computer gets messages through. Each port can have one socket, each socket may access one port.

To communicate over UDP you need three things:

  1. A socket of your own.
  2. The IP address of the machine you wish to contact.
  3. The port of a socket on that machine.

To create a socket, you use:

socket = network_create_socket_ext(network_socket_udp,port);

where port is whatever port number you like. Tip: Use a high one, like 7000 or more, to avoid collision with other programs on your computer.

If you don’t care what port your socket is on, just use network_create_socket(); instead and you will be assigned one. Only the server’s port number matters initially, as you will soon see.

To send a packet (message) with UDP, you use:

network_send_udp(socket, url, port, buffer, size);

socket: the UDP socket that this instance of your game created.

url: the IP address you want to receive the packet, written as a string e.g “127.0.0.1”.

port: the port that the other instance of your program assigned to its socket. You must know this to be able to communicate. Packets to other ports will be ignored even if you have the correct IP.

buffer: a buffer created with buffer_create() containing the actual data you want to send.

size: the size of that buffer, easily found with buffer_tell().

And that’s it, you’ve now sent a UDP packet. Wasn’t that exciting.

How do I read these packets?

Glad you asked. When you receive a packet, a special event called the Networking Event will trigger, and any objects that have actions for that event will get to perform them. You get one networking event per packet received, so you should be using it to process the packet’s contents.

During the networking event, a special ds_map will be created called async_load. This contains a number of useful things, including the port and ip of the program that sent the packet. Because of this, even though UDP has no connections, you can send packets to anyone you have received at least one packet from. async_load also contains a buffer, called buffer, which is the very same buffer that once would send with network_send_udp()! There’s a full reference in the docs, just be aware that async_load gets deleted as soon as the networking event ends so you need to extract everything you want as soon as you receive it.

Just give me a checklist.

The simplest possible sequence for getting UDP communications going, either between two machines on your LAN or just two instances of your game on your own computer, is as follows:

  1. Server creates a UDP socket on some known port, say 7500. And sits down to wait.
  2. Client creates a UDP socket on some random port (make sure its different to the server if they are on the same computer).
  3. Client sends a packet to the server, using the server’s IP address and known port number.
  4. The server extracts the client’s IP and port from that packet and stores them.
  5. Both machines can now send packets to each other, containing whatever you want them to contain.

That seems easy.

It is, it’s also pretty rubbish. You’ll need to implement a bunch of other stuff (here is a good starting point) for your network protocol to actually be useful, but this is the bare minimum needed to get started.

Can I have an example?

I guess. GameMaker’s event system makes it tricky to demonstrate code that’s spread across multiple events, but here it is:

Server Create

///Initialise the server object
var type = network_socket_udp;
var port = 8000;
socket = network_create_socket_ext(type,port);
//Placeholders
remote_port = 0;
remote_ip = “0.0.0.0”;
//Make a buffer to hold packet data
var size = 1024;
var type = buffer_fixed;
var alignment = 1;
send_buffer = buffer_create(size,type,alignment);

Client Create

var type = network_socket_udp;
socket = network_create_socket(type);//no port since the client doesn’t care
//Server IP and port, needed to send packets
remote_ip = “192.168.0.2”;
remote_port = 8000;
//Make a buffer to hold packet data
var size = 1024;
var type = buffer_fixed;
var alignment = 1;
send_buffer = buffer_create(size,type,alignment);

Server Async (networking event, triggers on packet receipt)

//Get the port and ip of the client, so we can reply
remote_port = async_load[? “port”];
remote_ip = string(async_load[? “ip”]);

//get the buffer so we can process it

var buffer = async_load[? “buffer”];
buffer_seek(buffer, buffer_seek_start,0);
process_packet(buffer);//explained below

Client Async

//check for data
var buffer = async_load[? “buffer”];
buffer_seek(buffer, buffer_seek_start,0);
process_packet(buffer); //explained below

Write A Packet

//encode mouse position and transmit
buffer_seek(send_buffer, buffer_seek_start,0);
buffer_write(send_buffer, buffer_u8,1); //id. Use different ones for different msg types
buffer_write(send_buffer, buffer_u32,mouse_x);//mousepos
buffer_write(send_buffer, buffer_u32,mouse_y);
network_send_udp(socket,remote_ip,remote_port,send_buffer,buffer_tell(send_buffer));

Read A Packet

///process_packet(buffer)
var buffer = argument0;
var msg_id = buffer_read(buffer,buffer_u8);
var clickx = buffer_read(buffer, buffer_u32);//mousepos
var clicky = buffer_read(buffer, buffer_u32);
//do something with that mouse position
instance_create(clickx,clicky,oClick);

Conclusion

UDP is piss-simple and GameMaker’s networking documentation badly needs a “What’s A Network, Daddy?” section. I started with this video tutorial which is focused on TCP and stumbled my way forward from there. Good luck.

Advertisements

About nooneiverse

I am on the interbuts, look at me go!
This entry was posted in Articles, game dev and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s