Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Multiplayer command details - Is it UDP?

Author
Message
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 10th Apr 2012 22:17
Hello!

In the following post, TGC notes the broadcast function is sending out UDP packets:

http://forum.thegamecreators.com/?m=forum_view&t=188143&b=41

My question is, are all the multiPlayer commands basically wrappers for incoming and outgoing UDP Packets? I'd like to determine if I can send UDP packets from non AppGameKit sources (like Processing, or even an Arduino), and have the AppGameKit commands read those packets.

Thanks
Paul G.
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 11th Apr 2012 01:24
The broadcasts are UDP packets, but everything else is TCP. Currently there is no way to accept arbitrary UDP or TCP packets in AGK.
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 11th Apr 2012 01:48
Thanks for the response. Any chance of a future upgrade or add-on package to support external UDP or TCP?

Paul G.
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 11th Apr 2012 04:27
It's possible, but probably not in the near future.
bitJericho
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location: United States
Posted: 12th Apr 2012 18:32
there's http commands coming in the near future, I haven't seen any specs on it, but we'll hopefully be able to download arbitrary text files and upload data via URL requests. (if it's anything like dbp's commands)

md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 12th Apr 2012 22:34
I'm also looking forward to 1.07. I have to admit my questions on UPD / TCP are just me trying to use AppGameKit for something it was never intended for - Controlling & Monitoring a hobby robot. While I can do that easily on a PC, I'd really like to use my Android based Kindle Fire. You know, nice portable touch screen and all. And AppGameKit makes it so easy to get a good looking interface onto an Android. I've managed to struggle through compiling the AppGameKit app into an APK, so I wanted to see if I could get the Kindle to talk to another (Non AGK) point on my home network - Like an Ethernet Arduino. Given Paul's answer above, maybe not. However, I was looking at the TCP Packets being sent back and forth, and think I'll try and emulate the packets from existing AppGameKit transmissions like SendNetworkMessage and GetNetworkMessageString. Who knows, if I limit myself to fixed length/type packet going in and out, rather than "arbitrary"?

Paul G.
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 13th Apr 2012 04:06
If you are using tier 2 you should have access to the AGKSocket class that whilst undocumented will give you synchronous TCP functionality. Look for the AndroidNetwork.h file for the definitions.

If you want to stick with tier 1 you can try to emulate an AppGameKit client connecting to an AppGameKit network but it has a certain protocol that must be followed. When I have time I can write up the details if someone wants to have a go at implementing an AppGameKit compatible TCP client?
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 13th Apr 2012 22:17
Paul -

I know the TCG team has it's hands full with the 1.07 update, but I would definitely be interested in the protocol details when you the have time. I'll be happy to post my results with the forum.

Paul G.
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 14th Apr 2012 06:09 Edited at: 14th Apr 2012 06:21
I took a few minutes in the network code to note down all the details that should be relevant, note that when I say "message" I mean an internal protocol message and not the AppGameKit messages exposed by the command set. Those are encapsulated by message ID 5.

There may be a few mistakes as I haven't double checked it.


1) Open a TCP connection on the correct IP and port for the connection you hosted from AGK.
2) Send a unique client name to identify your client in the following format: (4 byte int for length)(x bytes of string data without the null terminator)
3) Flush the TCP stream and wait for a 4 byte int to return, this will be 1 or 0 for success or failure. On failure close the connection and try again.
4) Receive a 4 byte int, this will be your client ID.
4) Wait for another 4 byte int, this is the number of other clients on the network
5) For each other client receive the following: (4 byte client ID)(4 byte length)(x bytes of string data for the client's name, no null terminator)(4 byte int for the number of variables this client is sharing) for each variable receive (4 byte length)(x bytes of string data for variable name)(4 byte int for variable type)(4 byte int for variable mode), you can dump the variable data if you just want to use the network messages, but you must receive it to clear the stream.
6) you are now a client on the network and will receive network messages that start with a 4 byte int message ID as follows

Message ID 0 is a ping from the server and ping stats. Send a 4 byte int (must be 0), flush the TCP stream to make sure the ping reply goes out now, receive a 4 byte int for the number of clients and for each client receive (4 byte int client ID)(4 byte float for ping time to this client). This message is sent to all clients every 2 seconds.

Message ID 1 is a new client joined the network. Receive (4 byte int for its client ID)(4 byte int length)(x bytes of string data for the client name)

Message ID 2 is a new shared variable(s) from another client. Receive (4 byte int for client ID)(4 byte int for the number of new varaibles) for each variable receive (4 byte int length)(x bytes string data for variable name)(4 byte int for variable mode)(4 byte int for variable type)(4 byte int/float variable value). variable type=0 for int, type=1 for float.

Message ID 3 is a changed variable(s) from another client. Receive (4 byte int for client ID)(4 byte int for number of variables changed) for each variable changed receive (4 byte int variable ID)(4 byte variable value). Variables are given an ID based on the order they were shared, starting at 0. You need both the client ID and the variable ID to reference a variable as all clients start their variables at 0. Variables cannot be deleted to make variable handling easier.

Message ID 4 is a client left the network. Receive (4 byte int for client ID that left)

Message ID 5 is receiving an AppGameKit network message. Receive (4 byte int for the ID of the client that sent it)(4 byte int for message length in bytes)(x bytes of raw message data). Max raw message data is 1400 bytes.

Implementing messages 2 and 3 are optional if you don't set any shared variables in AGK.
Implementing message 5 is optional if you don't use network messages in AGK.

You can also send messages to the server which will then notify the other clients of any necessary changes they need to be aware of. Start each message with a 4 byte int for the message ID as follows:

Message ID 0 reserved
Message ID 1 reserved

Message ID 2 to notify the server that you want to share a new variable. Send (4 byte int for the number of new variables) for each variable send (4 byte int length)(x bytes of string data for variable name)(4 byte int for variable mode)(4 byte int for variable type)(4 byte int/float for variable value). variable type=0 for int, type=1 for float.

Message ID 3 to notify the server of a local change in a shared variable value. (clients can only modify variables they themselves have shared, they get notified of other client's variables in a read only fashion). Send (4 byte int for number of variables changed) for each changed variable send (4 byte int for the variable ID)(4 byte int/float variable value). Variables are given an ID based on the order they were shared, starting at 0. You need both the client ID and the variable ID to reference a variable as all clients start their variables at 0. Variables cannot be deleted to make variable handling easier.

Message ID 4 reserved

Message ID 5 to send an AppGameKit network message to one or all clients. Send (4 byte int of your own client ID)(4 byte int of the recipient client ID, 0 to send to all)(4 byte int length)(x bytes of raw message data, max 1400 bytes)

Message ID 6 to notify the server that you are disconnecting, looking at the code now this may not be implmented properly. Simply closing the TCP connection may be a better option and this will trigger the message 4 to the other clients.

Message ID 7 if you just want to check the connection is still open, only the message ID is sent and the server will not reply, check for TCP errors for closed sockets.

Implementing messages 2 and 3 are optional if you don't set any shared variables in AGK.
Implementing message 5 is optional if you don't use network messages in AGK.
Messages 6 and 7 are optional.

* All strings are sent without a null terminator, a length field is sent first.
* ARM devices have problems with unaligned floats, for example if a 3 byte string is followed by a 4 byte float the float is not on a 4 byte boundary and will crash ARM code. Testing shows that reading as an int and casting to float by converting pointer types does work, but may not be reliable long term. AppGameKit client code uses this method. To avoid this issue completely make all strings a multiple of 4 bytes.
* Note that the parameters between sending and receiving a message don't always match up as the server modifies it on the way through, for example by adding a client ID.
* The hoster of the network acts just like any other clients with its own client ID, and is always the first client on the network.
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 16th Apr 2012 22:59
Paul -

Thanks for the information. I'll start experimenting this week, and let you know what I come up with.

Paul G.
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 24th Apr 2012 22:37
Hi Paul -

I'm still working on this little interface project - I do have a couple of questions though:

1.) When a player elects to "Host" the game, do they effectively become the server? I ask because the first batch of data sent by the host in steps 4,4, &5 identify the joining player as ID 2, with 1 other client on the network. If both player are clients, who/what acts as the server?

2.) I notice that when receiving msg ID 5, there seems to be an extra byte showing up - 4 bytes for msg 5, 4 bytes for from client, 4 bytes carrying hex 0C (FormFeed), then the 4 bytes for msg length, and the raw message data. Is this correct?

3.) Can you point me to any information about shared variables? I've searched this forum, but didn't find anything. Since a number of the msg described above use them, I'd like to see how they are used. Or is that maybe a tier 2 thing?

Thanks
Paul G.
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 25th Apr 2012 05:08
Quote: "When a player elects to "Host" the game, do they effectively become the server?"


Yes, the host starts an instance of the server, and an instance of the client that then connects to themselves. So they are the first client with ID 1.

Quote: "4 bytes for msg 5, 4 bytes for from client, 4 bytes carrying hex 0C (FormFeed), then the 4 bytes for msg length"


I can't see any reason why that 0C value would be there, as far as I can tell that would be the msg length value.

Quote: "Can you point me to any information about shared variables?"


There should be some description of it in the documentation under SetNetworkLocalInteger and GetNetworkClientInteger. Essentially each client can broadcast a list of local variables to all clients on the network that can then read them as if they were a local value.
md10bldr2
12
Years of Service
User Offline
Joined: 29th Sep 2011
Location:
Posted: 25th Apr 2012 09:45
Thanks for the information. As far as the 0C value, I've attached a wordpad file showing the TCP traffic following the initial UDP broadcast. The fuschia colored text is from a modified version of the multiplayer example that's running on a Kindle Fire in the host role using the AppGameKit player, while communicating with the AppGameKit IDE on my desktop(Blue).

The modification to the multiplayer example consists of sending a message with "Hello123" upon a screen touch, rather than continuous sprite position data.

This results in the expected Msg ID 0 pings every 2 seconds, and the Msg ID 5 with Client from, the extra 0C, length, and raw data, when a screen touch has occurred.

Paul G.

Attachments

Login to view attachments
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 25th Apr 2012 19:12
Ah, I see what's happening, 0C is the length of the message, which is then followed by the length of the string, then the string. This is because the message could contain raw data rather than AppGameKit strings, ints, and floats, so the message length lets you read the whole data.

Login to post a reply

Server time is: 2024-05-04 08:40:23
Your offset time is: 2024-05-04 08:40:23