Jump to content


Photo
* * * * * 1 votes

Gudp - guaranteed UDP


  • Please log in to reply
25 replies to this topic

#1 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 15 August 2011 - 02:36 PM

  • Title: Gudp Engine - Send Guaranteed UDP
  • Description: Allows the user to send guaranteed UDP packets instead of TCP packets, allows your online game players to host their games without having to forward ports.
  • GM Version: :GM7:
  • Registered: Yes
  • File Type: .zip (contains a .gmk and a .dll)
  • File Size: 82KB
  • File Link: Click me
  • Required DLLs: 39DLL V2.5

Last post update: 25/8/2011
Latest Gudp version: V508 (25/8/2011)


Introduction
One may wonder what advantage a Guaranteed UDP system has over the standard TCP. It is a well known fact that TCP is slow yet guaranteed, UDP is fast yet unreliable, Yet many overlook one more advantage UDP has: UDP Hole punching. UDP Hole punching is a nat traversal technique, in other words, when the server is protected by a router firewall, UDP hole punching allows the guest(client) to connect to the host(server) without the server having to forward the router ports. this is very convenient for the people who want to play your online game, because must people are not willing to play around with their router settings.
There is still one problem though, UDP does not send guaranteed packets :(

Gudp
And that is why I invented Gudp, which combines the Hole Punching power of UDP with the reliability of TCP.

Features:
  • Simulates the features of TCP, simulates a connection oriented Protocol over UDP.
  • Guranteed and ordered arrival of messages, just like TCP.
  • UDP hole punching, players don't have to forward their ports. (assuming they know each others' IP addresses)
  • Built-in timeout and keepalive system.
  • Very modular, therefore can be easily implemented in an existing game.
  • allows connections to multiple peers.
  • does not interfere with regular UDP packets.

Scripts explained
Gudp contains two sets of scripts: "Gscripts", and "Gsys_DONT_EXECUTE". obviously, the latter is not meant to be executed by the user. this short guide will explain "Gscripts", It will not explain the behind-the-scenes of Gudp, it will only explain how to use Gudp. If you are curious though, see the commenting in Gsys_DONT_EXECUTE, and feel free to PM me regarding any questions :)

Gscripts
  • G Init
  • Ginit(Source UDP socket, Game Str);
  • Gfree();
G Connect
  • Gconnect(IP, Port, Game Str); Return: GSockId
  • Gdisconnect(GSockId);
G Accept Connections
  • accept();
  • Gaddsock(IP, Port); Return: GsockID
  • Gpunch(IP, Port);
G others
  • Greceivemessage();
  • Gsend(GSockID,[optional]BufferID);
  • Gstep();

G Init
Ginit(Source UDP socket, Game Str); - This script will initlize Gudp, it must be executed once. The script will create an instance of the object Gudp, this object is only used as a variable storage for Gudp. argument0 is the udp socket Gudp will use (the one which is returned when executing udpconnect). argument1 is the GameStr, it is the string that the clients need to send in order to connect, this is done to make sure that only the proper clients are connecting.
Gfree(); - Frees Gudp by destroying all data structures then destroying the Gudp instance.

G Connect
Gconnect(IP, Port, Game Str,BufferID); Return: GSockId - Connects to a Gudp server, the game str must be equal to the game str in Ginit. returns a GsockID that will be used in later scripts.
Buffer ID is the buffer to send along the connection request (in other words, the buffer that the accept(); script will read), this usually contains username and password. leave empty or set to zero in order to send the default buffer, use -1 if you don't want to send a buffer.
usage example
clearbuffer(); //sending the default buffer
writestring(username);
writestring(password);
Gconnect(serverip,serverport,"MyOnlinePlatformer",0); //the string(Game str) should be equal to the string used at Ginit in the server side.
 
//example 2:
clearbuffer(newbuff); //sending a non-default buffer
writestring(username,newbuff);
writestring(password,newbuff);
Gconnect(serverip,serverport,"MYonlinePlatformer",newbuff);

Gdisconnect(GSockId); - No need to explain.

G Accept Connections
accept(); , and Gaddsock(IP, Port); Return: GsockID:
  • accept is a script that SHOULD BE EDITED and customized to fit your game.
  • accept is automatically triggered when a player is trying to connect to you (triggered by Gstep).
  • to accept the connection, you must execute Gaddsock(argument0, argument1);
  • to reject, simply don't execute Gaddsock();
  • Gaddsock should only be executed inside accept();
  • Gaddsock will return a GsockID, this should be stored for later use.
  • in script accept() , argument0 represents the ip of the person trying to connect, argument1 represents the port.
  • in script accept() , one must read from the buffer Gbuff, and not the default buffer.
Usage example of accept() and Gaddsock()
exit; 
ini_open("usernames.ini");
user=readshort(Gbuff);
pass=readshort(Gbuff);
if accept_player(user,pass)
{
   var playerID,MyGsock,MyIP,MyPort;

   MyGsock=Gaddsock(argument0,argument1); 
   playerID=instance_create(x,y,player);
   PlayerID.MyIP=argument0;
   PlayerID.MyPort=argument1; 
   playerID.name=user;
   
   var i;
   //-loop and get the i stuff-
   global.players[i]=playerID;  
   
   clearbuffer();  //Gsend usage example
   writebyte(129);
   writestring("Welcome "+user);
   Gsend(PlayerID.MyGsock);
}

Gpunch(IP, Port); - if we are behind a firewall and someone is trying to connect to us, this will make us punch the firewall and let them use Gconnect(); , note that we must know their IP and port, which is the drawback of hole punching.


G others
Greceivemessage([optional]bufferid); Return: message size or -1 - receives the next message and returns its' size, or returns -1 if there are no messages. note that Gudp adds a short at the beginning of any received message, this short represents the GsockID that received the message. also note that when a connection is lost UDP generates a mesid of 0.
Gstep(); - just put this in a step event, will cause an error if executed before Ginit.
step event example:
Gstep();
while (Greceivemessage()>=0)
{   
    var SOckid,player;
    SOckid=readshort(); //this is NOT sent to us by anyone, it is generated by the local Gudp.
                        //the receiving GsockID.
    mesid=readbyte();
    with (Player)
    {   
        if (MyGsock==SOckid)
        {
            player=id;
            break;
        }
    }
   switch(mesid)
    {         
        case 20:
        player.x=readshort();
        player.y=readshort();
        break;
        
        case 0: //this is NOT sent to us by anyone, it is generated by the local Gudp.
        with (player){show_message("connection lost :( ");}
        break;

    }
 
}
clearbuffer();
Gsend(GSockID,[optional]BufferID); - sends a message, works exactly like sendmessage();
usage example - see the accept(); usage example above.

Change log:

Re uploaded V508
Exactly the same version, but removed a left-over unused script folder (Binaryconversion)

V508
Fixed two critical bugs:
  • Removed simulated lag (which was used for testing and was never removed)
  • Removed buggy example code.

V507 - First GMC version

To Do list:
  • Fix the Keepalive bug: the lower the ping, the more frequent the keepalives are.
  • Implement a smarter delay system: currently, when Gudp sends a message, it waits for an ack, if no ack is received after two seconds, the message is resent. this could slow down the communication whenever the ping is lower than 2000ms(two seconds), therefore, a smarter delay system will be implemented. (which will take the average ping into account).
  • Include a simple online game example.

Edited by safwat1995, 25 August 2011 - 03:57 AM.

  • 0

#2 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Member
  • 15874 posts
  • Version:GM:Studio

Posted 15 August 2011 - 08:22 PM

The file is corrupted or something (I get file does not exist error and nothing loads in GM8 and Error Loading File in gm7). please re-upload...

Can you also re-paste your code in the second code box? the forum screwed up the formatting
  • 0

#3 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 16 August 2011 - 05:37 AM

The file is corrupted or something...Can you also re-paste your code in the second code box?

I just downloaded the file and opened it with GM7, everything seems fine. It could be your computer. Is anyone else experiencing this?

...Can you also re-paste your code in the second code box?

Done, thank you :)
  • 0

#4 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Member
  • 15874 posts
  • Version:GM:Studio

Posted 16 August 2011 - 07:16 AM

There has to be some sort of file the gmk needs, a dependency you have installed which I don't.
Maybe an dd extension package?

LateralGM opens the file but not gm7 or 8. If I open with lateralGM and save as gm6, gm7 and 8 can load it then. Is it possible this is a macOS file?
  • 0

#5 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 16 August 2011 - 07:54 AM

No extensions are installed in my GM.
The file needs 39dll to work, but it is included in the gmk itself. and even if it's not there the file should still open.
I will try packing the gmk and the dll in a zip instead, hope it works.

edit: done, host changed too.

Edited by safwat1995, 16 August 2011 - 08:07 AM.

  • 0

#6 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Member
  • 15874 posts
  • Version:GM:Studio

Posted 16 August 2011 - 08:17 AM

Yep that was it. looks like we encountered a serious bug there... Maybe it's to do with access rights on vista or my virus scanner...
  • 0

#7 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 16 August 2011 - 08:21 AM

Staff choice, awesome :D
Thank you!
  • 0

#8 sabriath

sabriath

    12013

  • GMC Member
  • 3177 posts

Posted 17 August 2011 - 08:01 PM

No offense:

- "UDP is yet {un}reliable" *fixed it for you, first paragraph.
- holepunching is not a miracle way of connecting, you still need to portforward the server
- I don't see how this is a tutorial, this should be in extensions since you are not actually teaching anything.
- You have "simulated lag" which is unnecessary (Gstep)
- I am not seeing 576 byte clamping for UDP sends
- I am seeing reliable-ordered UDP, but not reliable UDP...there is a difference (TCP is better for reliable-ordered)
- There is no throttling, you seem to be sending everything out in a burst every step, unhindered (this WILL cause congestion and eventually lockup)
- Since this new GMC skin has left me with no control over my account anymore, feel free to PM me (hopefully THAT button still works) if you have any questions.
  • 0

#9 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 18 August 2011 - 07:34 AM

- "UDP is yet {un}reliable" *fixed it for you, first paragraph.

Thanks, fixed.

- holepunching is not a miracle way of connecting, you still need to portforward the server

Not necessarily, it is possible to make a master-server that the guest and the host connect to, the master server would then act as a bridge between them and tell them the IP addresses of each other, they can then use hole punching. I should have clarified that a master-server is needed in order to fully get rid of port forwarding though. I will update the post soon.

- I don't see how this is a tutorial, this should be in extensions since you are not actually teaching anything.

I thought about that, but then I saw that there are several other engines which aren't exactly tutorials, so I posted it here, and it seems that the mods have no problem with that.

- You have "simulated lag" which is unnecessary (Gstep)

Totally right, this was meant for testing purposes, I will remove it asap.

- I am not seeing 576 byte clamping for UDP sends

What does that mean? are you talking about sending several small packets as one big 576 byte (508 data + 64 header) packet?

- I am seeing reliable-ordered UDP, but not reliable UDP...there is a difference (TCP is better for reliable-ordered)

I clearly stated it's reliable-ordered ("Guranteed and ordered arrival of messages"), I might implement reliable unordered in the future though.
Why is TCP better for reliable-ordered?

- There is no throttling, you seem to be sending everything out in a burst every step, unhindered (this WILL cause congestion and eventually lockup)

Gudp isn't meant to behave that way (send a packet every step). but it seems that a new keepalive packet is sent whenever Gudp gets an ACK about the older keepalive packet, this is causing the keepalive system to send packets every step only when the ping is extremely low (lan or localhost). this is a flaw in the keepalive system, but high ping eliminates it. This will be fixed in the next version.

To sum it up, there are two flaws:
  • Simulated lag (Ironically fixing this will decrease the ping and worsen problem number two).
  • the lower the ping, the more frequent the keepalives are being sent.

And there are two things I can add:
  • reliable unordered UDP.
  • joining small packets together to send less packets (what is the term used for such a thing?)
have I missed something?


Thank you for the feedback, It really helped :)

Edited by safwat1995, 18 August 2011 - 07:39 AM.

  • 0

#10 sabriath

sabriath

    12013

  • GMC Member
  • 3177 posts

Posted 18 August 2011 - 09:41 AM

Not necessarily, it is possible to make a master-server that the guest and the host connect to, the master server would then act as a bridge between them and tell them the IP addresses of each other, they can then use hole punching. I should have clarified that a master-server is needed in order to fully get rid of port forwarding though. I will update the post soon.

Then the "master-server" then is the actual server and it needs to have portforwarded. At some point in the communication network, you have to portforward.

I thought about that, but then I saw that there are several other engines which aren't exactly tutorials, so I posted it here, and it seems that the mods have no problem with that.

Sometimes it is better to be a leader than a follower *shrugs*

What does that mean? are you talking about sending several small packets as one big 576 byte (508 data + 64 header) packet?

In a normal network mesh, routers along any route are required to allow around 576 bytes. UDP is unfragmentable, so if a router is limited to 576 bytes and it gets a UDP packet of more, it will drop the packet as a loss. In a throttling situation, a network will normally ramp up the packet size until it experiences an increase in droprate before coming down...you don't have throttling, so you should stick to no more than 576 byte packets.

I clearly stated it's reliable-ordered ("Guranteed and ordered arrival of messages"), I might implement reliable unordered in the future though.
Why is TCP better for reliable-ordered?

Sorry, I didn't see you state that, the topic title just says "guaranteed."

TCP is better because it is built into the kernel of the operating system...it does all the work of fragmentation, throttling, ramping and state mechanics. Even if you wrote it part of the 39dll file itself, it still wouldn't be as efficient as TCP.

joining small packets together to send less packets (what is the term used for such a thing?)

Packing


For reference....

Posted Image
  • 1

#11 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 18 August 2011 - 09:52 AM

Then the "master-server" then is the actual server...

The master-server would only be used For sharing IP addresses, after that the host and guest(s) can communicate independently without forwarding ports.

...and it needs to have portforwarded. At some point in the communication network, you have to portforward.


yeah, but think about it: Only the game developer (who owns the master server) needs to forward ports ... Versus ... All hosts having to forward their ports.
In the former case, From a player's perspective: all he needs to do is run the game and play either as host or guest.
Any online game developer is enough tech-savy to know how to forward his master-server ports, while most players don't know how to do that for their servers.

Edited by safwat1995, 18 August 2011 - 10:01 AM.

  • 0

#12 sabriath

sabriath

    12013

  • GMC Member
  • 3177 posts

Posted 18 August 2011 - 06:26 PM

You're not getting what I'm saying....you ARE in a "techsavvy" (or learning) environment, which means that information is NEEDED. You cannot just say "leave it to the tech-savvy to give you the master-server," when you are training the next generation of upcoming "tech-savvy"s....get it?

Best to teach all the information, and let the students absorb what they want.

By the way, in my hastily drawing, I missed 2 key points....there should be a NACK timer for Recv messages before going to the NACK list, and a Re-Order buffer for messages that are marked "ordered."

:thumbsup:
  • 0

#13 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 18 August 2011 - 09:21 PM

OK,this is a mess...I always get errors,game crashes and pc blue screens of death :(
Try to fix it a bit(Also make it work on GM8)and add and an example or tutorial.
  • 0

#14 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 19 August 2011 - 09:45 AM

OK,this is a mess...I always get errors,game crashes and pc blue screens of death :(
Try to fix it a bit(Also make it work on GM8)and add and an example or tutorial.


Whoa, blue screen of death? the entire thing is GM code, so the worst that ever happened to me is an error message D:
The current version of Gudp is supposed to be pretty stable, I believe that you used it incorrectly.
you are right though, an example is needed.

edit: this was never tested on GM8, it could be the problem.

Edited by safwat1995, 19 August 2011 - 09:45 AM.

  • 0

#15 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 19 August 2011 - 09:51 AM

edit: this was never tested on GM8, it could be the problem.
That might be the problem...I really need to use this in GM8.
If you want I will send you all the errors in the scripts I found so far.
  • 0

#16 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 19 August 2011 - 09:58 AM

Posted Image
One problem so far.
  • 1

#17 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 19 August 2011 - 12:29 PM

One problem so far.

lol! that code is just an example code (you can see that there is an "exit" , so this is never executed)
just comment the entire thing after 'exit' out.
thanks for reporting this!
  • 0

#18 thedyingdragon

thedyingdragon

    GMC Member

  • GMC Member
  • 23 posts

Posted 19 August 2011 - 03:57 PM

This does look like it has some potential but I probably won't use until an example is posted
  • 0

#19 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 19 August 2011 - 07:32 PM

I will upload a new version tomorrow, which will fix the critical bugs, (The "buggy" example code, and the simulated lag)
I will also upload a good example in the next few days.
  • 1

#20 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 19 August 2011 - 07:40 PM

I will upload a new version tomorrow, which will fix the critical bugs, (The "buggy" example code, and the simulated lag)
I will also upload a good example in the next few days.


Thanks.
  • 0

#21 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 20 August 2011 - 05:58 AM

V508 uploaded, fixed the critical bugs:
  • Removed simulated lag (which was used for testing and was never removed)
  • Removed buggy example code.

To-do list updated as well.

Edited by safwat1995, 20 August 2011 - 06:13 AM.

  • 0

#22 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 20 August 2011 - 12:57 PM

Hmm,Works better!
Now we only need an example.I can w8 for it...
  • 0

#23 Tha_14

Tha_14

    GMC Member

  • New Member
  • 174 posts
  • Version:GM8.1

Posted 07 January 2012 - 03:56 PM

BUMP for this!
I really need an example to start from :(
  • 0

#24 safwat1995

safwat1995

    GMC Member

  • New Member
  • 394 posts

Posted 10 January 2012 - 07:31 PM

BUMP for this!
I really need an example to start from :(

Hello :)
Unfortunately, I am no longer updating Gudp.
I might post an example one day, but this is not guaranteed, and don't expect this to happen any time soon... I have little free time to do this :(
I believe that you should get the hang of it if you check out the example scripts and play around with the code.

Good luck, and feel free to PM me if you need help :)
  • 0

#25 thedyingdragon

thedyingdragon

    GMC Member

  • GMC Member
  • 23 posts

Posted 27 January 2012 - 07:03 PM

Unfortunately, I am no longer updating Gudp.
I have little free time to do this


I am so many forms of sad ...

But thats life I guess and what you have here is a start
Im sure with some tweaking I may be able to implement it in one of my side projects
Thanks for creating it in the first place
  • 0

#26 PoniesForPeace

PoniesForPeace

    puzzling

  • GMC Member
  • 494 posts
  • Version:GM:Studio

Posted 17 June 2012 - 01:56 PM

Has anyone gotten this to work? I have no idea what I'm reading.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users