• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Pfaeff

Mixing reliable and unreliable messages

9 posts in this topic

Hi,

I am currently working on a network abstraction layer that will be able to deliver reliable and unreliable messages over UDP.
Each UDP packet contains a user id, the current sequence number, an ACK field and an ACK bitfield (as described [url="http://gafferongames.com/networking-for-game-programmers/reliability-and-flow-control/"]here[/url]) and a payload among other things like the current tick.
The payload contains the games messages. Each message is simply a message type id followed by the message data.

I now want to be able to send certain message reliably and unreliably, but that seems to be very tricky if I have packets that contain mixed message types, due to the fact that the ACK field refers to the packet and not to its content. Three solutions came to my mind:[list=1]
[*]Send all packets reliably (most simple solution, but I am not sure how big the effect on network performance would be)
[*]Don't mix message of different reliablity type in the packets payload. Have packets that only contain reliable messages and packets that only contain unreliable messages, but let unreliable packets be able to acknowledge reliable packets. The question here would be, how frequently should reliable and unreliable messages be sent? Sometimes there might even be no reliable messages to be send, because they're only created for consistent events (in my specific use case). If I'd send let's say 20 packets per second, what percentage of those should be reliable packets that contain only reliable messages?
[*]Have a sequence number and a reliability flag for each payload and treat them like single packets, but bundle them together before sending them over the network.
[/list]

What would be the best approach to do that? Is there maybe a fourth alternative that I didn't think of that could solve all my problems?
Thanks in advance.

Greetings,
Pfaeff
0

Share this post


Link to post
Share on other sites
Hi, I'm currently working on pretty much the same thing :)

my approach is to have the first 16 bytes in each package as a header, consisting of four integers.
0 = hash tag to sign the package (hash of package content + shared session key)
4 = package confirm (the last received package from the connected peer)
8 = package id where value 0 - 9 are reserved (0 => unreliable)
12 = session id

In short:
If I receive a package with package id = 0 I'll verify the content of the package, copy the confirm value to my outbox (so i know which packages not to resend), and finally pass the remaining data on to the user.
If I receive a reliable package (package id > 9) I'll do the above steps, and set a flag to confirm the last received package. On the next send call I'll set the confirm value in all outgoing messages to latest received package and send them. If my outbox is empty I'll send an unreliable package to confirm.

To answer your questions:
1 )
Since you are using UDP you might as well use the power of UDP - besides easy NAT punch through, so I would not recommend you to send everything reliable.
2 )
If you want the unreliable packages to be fast you should not bundle them with reliable ones. Unless you are going to send an reliable package at the same time. Then you might as well bundle them (but not necessarily the second time you send the reliable package (if first try should fail)).
Yes you should defiantly acknowledge reliable packages in your unreliable packages.
Knowing nothing of your game, and not being that experienced in networking I don't know the answer for the last question in (2)
3 )
The answer for this is pretty much the same as for (2). I don't - I neither deals with payloads, but only packages.

Hope this helps :)
1

Share this post


Link to post
Share on other sites
[quote name='Pfaeff' timestamp='1335700705' post='4935803']
Each UDP packet contains a user id...
[/quote]
Are you expecting for one client to be serving multiple users? The user id can be inferred from the IP / port of the packet. Including a user identifier in packets only yields to vulnerabilities where the user id is accidentally used unverified, allowing clients to impersonate one another.

[quote]
What would be the best approach to do that? Is there maybe a fourth alternative that I didn't think of that could solve all my problems?
[/quote]
If the peer records which reliable messages are associated with each packet, when a packet is acknowledged then all reliable messages that were included in this packet can be marked as delivered.
1

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1335720720' post='4935850']
[quote name='Pfaeff' timestamp='1335700705' post='4935803']
Each UDP packet contains a user id...
[/quote]
Are you expecting for one client to be serving multiple users? The user id can be inferred from the IP / port of the packet. Including a user identifier in packets only yields to vulnerabilities where the user id is accidentally used unverified, allowing clients to impersonate one another.
[/quote]
I also thought about this and I think you are right. It would be better to just identify the users based on the IP address.

[quote]
[quote]
What would be the best approach to do that? Is there maybe a fourth alternative that I didn't think of that could solve all my problems?
[/quote]
If the peer records which reliable messages are associated with each packet, when a packet is acknowledged then all reliable messages that were included in this packet can be marked as delivered.
[/quote]
Why didn't I think about this [img]http://public.gamedev.net//public/style_emoticons/default/ohmy.png[/img] ? The sender just needs to know which messages where in the packet that got acknowledged and mark them all as received. This seems to be the best solution. Thanks a lot. Edited by Pfaeff
0

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1335720720' post='4935850'][quote name='Pfaeff' timestamp='1335700705' post='4935803']Each UDP packet contains a user id...[/quote]Are you expecting for one client to be serving multiple users? The user id can be inferred from the IP / port of the packet. Including a user identifier in packets only yields to vulnerabilities where the user id is accidentally used unverified, allowing clients to impersonate one another.[/quote]
Looks like I'm shaving four bytes off my header as well then :)
0

Share this post


Link to post
Share on other sites
1 byte for last ack ID.


- MTU = 536 - 1500
- 1 byte for last package, 256 unique values
- 137,216 - 384,000 bytes of data

At 5kB/sec, it takes 20-40 seconds till wraparound.

To detect wraparound, count number of sent packages locally with some larger counter, 32 bit int or so. Add that to checksum. If silent wraparound occurs (exactly 256 packages lost), the hash won't match.
----
1 byte for package ID:

They contain only control data (connect, disconnect, ping, login, etc...). The rest goes into payload.

----
Checksum: 2 or 4 bytes


Which means the entire protocol header is 4 or 6 bytes.

Session ID and all that isn't needed, as mentioned.
0

Share this post


Link to post
Share on other sites
Ok, for my new implementation I've created a six bytes header with a checksum in the first four bytes, package id in the next and last confirmed package id in the last byte. the last ten values of the package id is dedicated to special (i.e. FAST(unreliable), SYN, SYNACK, etc.).

But apparently (as far as I can see) there is no way to get the MTU through Java - I don't have access to IP headers or DF-bit - So would you recommend me to go for the lowest MTU? Since the aim of my network library is fast updates not file transfer, It would primarily be very long chat messages that would be split up even if I go for max package size of 500.
Or is the percentage of small-MTU-networks so low that practically no one would be affected by the overhead of package fragmentation, if I go for package size of 1460? (considering that most packages wont be that big anyways).

Bonus question:
For checksum I'm using CRC32, would CRC16 be enough? or should I find some thing more secure than CRC32?

Edit: Also, sorry for going a little off the original topic. Edited by VildNinja
0

Share this post


Link to post
Share on other sites
[quote]
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][size=3][left][background=rgb(250, 251, 252)]For checksum I'm using CRC32, would CRC16 be enough? or should I find some thing more secure than CRC32?[/background][/left][/size][/font][/color]
[/quote]
Checksums aren't designed to be secure. They are designed to detect accidental corruption.

If you think need "security", then you first need to define your goal. Once you have a goal, then the technical measures you can take to try achieve this goal can be discussed. Such discussion should not occur in this thread (as you have realised).
0

Share this post


Link to post
Share on other sites
[quote name='Pfaeff' timestamp='1335722983' post='4935860']
I also thought about this and I think you are right. It would be better to just identify the users based on the IP address.

[/quote]

You need to use both the remote IP address and the remote port to uniquely identify a remote player. Else, two players behind the same NAT gateway would be confused with each other (same house, same company, same school, same ISP, ...)
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0