Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 03 Jun 2003
Online Last Active Today, 01:45 PM

#5082663 UDP network layer must-haves?

Posted by hplus0603 on 02 August 2013 - 10:26 PM

For metrics, you want various kind of parameters for gross trouble-shooting:

- customer class (if you have it)

- session state (not-established, negotiating, lobby, game, etc)

- size of packet

- number of payload messages per packet

- payload message types

- packet direction (to server or from server)

- number of dropped packets detected

- number of duplicate packets detected

- number of reordered packets detected

- measured round-trip latency

- number of malformed packets


In the best of worlds, you chuck all of this at some reporting infrastructure, and generate an online cube where you can slice your traffic across arbitrary dimensions (each of the things above classify packets across some dimension.) This doesn't necessarily need to be real-time, because it's useful for finding things you didn't know about your game. Each individual dimension could separately be real-time, and the drill-down would be relegated to a baked cube, for example.

At that point, you can get reports like "number of packets that are re-ordered, containing the 'fire weapon' payload."


Now, there's a second level of diagnosis, where you can get this data sliced, in real-time, based on specific identifiers. Specific IP. Specific game instance. Specific player. Random sampling. Etc. Being able to have a customer on the line and turn on tracing of that particular customer's traffic is super helpful while debugging.


Another useful feature is the ability to capture and play back traffic, both for analysis, and for actual system analysis. If you can capture all packets that go in since server start, then you can reproduce any server state offline for debugging!

#5081864 UDP protocol to minimize latency?

Posted by hplus0603 on 30 July 2013 - 10:47 PM

If you don't have some way to support reliable-in-order where it's really needed, then each dev will try to build it alone in each application system, which is a much worse place to put it than in the network layer proper.

#5081836 network problem

Posted by hplus0603 on 30 July 2013 - 08:30 PM

First, posting all your source will not help anyone.


Second, what is the problem? Are you getting a compile error? If so, you should copy-and-paste the error, and the few lines of code that generate that error.


Third, tracking down compile errors should be very easy for someone who actually knows how to program. If you don't know how to fix that, you are not prepared to develop distributed, asynchronous, systems, such as networked games. I suggest you learn to program and use your tools first, or your project will be an exercise in frustration.


Moving to a better forum for this particular question.

#5081793 TCP/IP latency over wifi

Posted by hplus0603 on 30 July 2013 - 03:10 PM

My guess is that you haven't turned off TCP nagle-ing. In C, it's the TCP_NODELAY socket option.

#5081730 UDP protocol to minimize latency?

Posted by hplus0603 on 30 July 2013 - 09:44 AM

I agree: It depends on the network! It's probably better to design robust re-connection mechanics. If you can't get a message through for a second, that may start to severely impact gameplay, and sometimes when some IP address changes route through the Internet, it may take a minute to come back.

#5079893 Server side physics, what would you want to see?

Posted by hplus0603 on 23 July 2013 - 10:52 AM

Many things you say are true, such as system design is more important than language choice when it comes to scalability. As long as you're I/O bound, your memory throughput and CPU utilization doesn't matter, for example.


I have two additional comments:

1) There exists a large, open source, game server engine that attempts massive scalability. This was Project Darkstar from Sun, since then moved off of Sun/Oracle into the RedDwarf Server project. By trying to be general, it unfortunately lost out on the scalability part.

2) Without a specific game with specific performance requirements and specific rule sets, I fear that your system will not actually solve anyone's particular problems.

#5079720 Handling Extra Messages

Posted by hplus0603 on 22 July 2013 - 08:04 PM

The code above will decrease messages sent up to 16 times before I shutdown or start booting players.

Decreasing the rate you send messages isn't going to help if you still generate messages faster than you can send them.

You have to decrease the rate at which you *generate* those messages. For example, do not generate a new update for an entity if the previous update for that entity is still pending in the queue -- that would auto-balance the network to send no faster than it could support.

The next question is: what do you use as an indication that you "can't send" a packet? Are you using TCP or UDP? If UDP, then your local network interface can send messages very quickly without blocking, but those get dropped as soon as they hit your upstream cable modem / DSL router / ISP interface if you exceed capacity.

#5079618 Server side physics, what would you want to see?

Posted by hplus0603 on 22 July 2013 - 11:34 AM

Do you have a particular game you want to support, or is this "a general purpose server"?


Solving the MMO problem "generally" is very hard, because with MMOs, the "constant factor" matters, and different games have different requirements on rules. Some games really need server-side physics simulation. Other games just need a "phone switch" that sends commands between players, with the ability to arbitrate rules-based die rolls every once in a while. Trying to shoe-horn all different kinds of games into a single server structure is unlikely to meet most games' needs all that well.


When it comes to fast spatial queries, we used a multi-resolution grid for There.com, but if I were to do it again, I'd probably just go with something like a loose quad- or oct-tree. Also, it's not always that CPU is scarcer than network bandwidth, so whether "getting a few more entities" is OK or not depends on the game specifics. Once you have an entity in cache, though, doing an additional distance-squared test is close to free, if you need the precision.


My advice would be to design a particular game, and make sure your server can meet the needs of that particular game, mainly related to player/player communications (how about flagging abusers?) transactions (player trade, monster drops, etc) and rule events (did I hit or not? For how much damage?)

#5079616 Problem with sending unreliable packets. ENET & UDP

Posted by hplus0603 on 22 July 2013 - 11:27 AM

The point of the suggestion above is likely to add your own instrumentation on top of the ENet layer, so that you can see how it actually behaves with your game data.


It may be that you're not getting what you think you're getting. Or it may be that you're using ENet wrong. Or it may be that your network is actually really bad. Or it may be that the "jitter" is actually caused by local thread scheduling problems, rather than networking. Or something else -- there are lots of possibilities.

#5079615 Handling ISP throttling of our servers...

Posted by hplus0603 on 22 July 2013 - 11:25 AM

First: As Hodgman said, are you sure that the problem is ISP throttling?


Network connections have limited capacity. Users may run BitTorrent, stream Netflix, have automatic backups, get Windows Updates, or be signed up for IPTV-based "cable" TV. Your game may generate more traffic per event than strictly necessary.


If you know that the problem is ISP throttling, then tell users to get a better ISP :-) There's a reason places like serverbeach.com rent out game servers by the month.

If not, then you should probably make sure to make your game use as little bandwidth as possible per event.

#5077374 TCP Packet boundaries

Posted by hplus0603 on 13 July 2013 - 11:06 AM

Optimization generally means punching through layers and putting knowledge in places where it doesn't normally belong.


You have to make some trade-offs. Is it worth it saving a few bytes, and having to put knowledge of the protocol into the network class? If not, then you should length-prefix each packet, and you'll be fine. Have the sender put in length, type, payload, and you're good. The network class can then de-frame packets to the type,payload level, and pass that on to the registered handler for each type.


class PacketHandler {
  virtual void HandlePacket(size_t size, void const *data) = 0;
class Network {
  void AddPacketHandler(int type, PacketHandler *handler);
  size_t CheckBuffer(size_t size, void const *data);
size_t Network::CheckBuffer(size_t size, void const *data) {
  size_t packetsize = 0;
  size_t offset = 0;
  if (!TryDecodeSize(size, data, &offset, &packetsize)) {
    return 0;
  if (size - offset < packetsize) {
    return 0;
  int type = 0;
  size_t typesize;
  if (!TryDecodeType(size-offset, (char *)data + offset, &typesize, &type)) {
    return packetsize + offset; // bad packet, skip past it
  PacketHandler *handler = LookupTypeHandler(type);
  if (!handler) {
    return packetsize + offset; // unknown packet, skip it
  handler->HandlePacket(packetsize - typesize, (char *)data + offset + typesize);
  return packetsize + offset;


If saving that length byte (or two?) matters, then you have to do something like registering type-specific protocol decoders with the networking subsystem. You'd then find the decoder class for the given type code, after you've decoded the type code, and ask that class whether there's enough data to actually dispatch the packet. This means the decoder code may run several times for a given packet before you have enough data to actually dispatch the packet.


class PacketDecoder {
  virtual bool CanDecodePacket(size_t available, void const *start, size_t *o_size) = 0;
class PacketHandler {
  virtual void HandlePacket(size_t size, void const *data) = 0;
class Network {
  void AddPacketDecoder(int type, PacketDecoder *decoder);
  void AddPacketHandler(int type, PacketHandler *handler);
  bool CheckBuffer(size_t size, void const *data) = 0;

size_t Network::CheckBuffer(size_t size, void const *data) {
  int type = 0;
  size_t typesize;
  if (!TryDecodeType(size, (char *)data, &typesize, &type)) {
    return 0; // don't have type yet
  PacketDecoder *decoder = LookupTypeDecoder(type);
  if (!decoder) {
    exit(1); // the connection is in a bad state and there is no way to recover
  size_t packetsize = 0;
  if (!decoder->CanDecodePacket(size - typesize, (char *)data + typesize), &packetsize) {
    return 0; // can't decode packet yet
  PacketHandler *handler = LookupTypeHandler(type);
  if (!handler) {
    exit(1); // the network system is mis-configured and can't proceed
  handler->HandlePacket(packetsize, (char *)data + typesize);
  return packetsize + typesize; // packet consumed


#5077368 What is ping time?

Posted by hplus0603 on 13 July 2013 - 10:48 AM

ping refers to ICMP ping


"ping" is actually the name of the utility that generates ICMP protocol ECHO packets (PDUs) and measures packet loss and round-trip time to some given target. There's no such thing as a "pick packet" except, perhaps, to name "packets created by the ping utility."

Thus, in turn, "ping time" is the time value reported by the "ping utility." Which happens to be round-trip time.


In games, the low-level echo time is only half the story, though, because it doesn't account for queuing and processing times in the client and server. In a game, the time that really matters is time from giving a command, through the client processing and sending that command, through the server receiving and processing that command and sending a reply, through the client receiving and processing that reply. Things like OS scheduling jitter or graphics frame rate can affect this game-level round-trip time, and because that's the time that matters, that's often the time displayed by particular games as "ping time" even though they don't use the particular command-line tool called "ping."

#5077119 Free / Open source multiplayer servers

Posted by hplus0603 on 12 July 2013 - 10:15 AM

There are some recommended opensource network packages, including ENet and RakNet.

Unfortunately, Java is not the native language for those; they're C or C++ based.

Sun tried to make a Java system for multiplayer networked games called Project Darkstar, but they tried to solve too much at once and ended up not being able to deliver despite years of effort.

If all you need is local multiplayer, then you could build something super simple on top of the aio Java sockets support and UDP broadcasts!

#5076799 Client/Server model without port forwarding

Posted by hplus0603 on 10 July 2013 - 09:22 PM

You are correct that you need NAT punch-through to get through residential NAT routers, if you don't want to require port forwarding.


You can read about it in <a href='http://www.mindcontrol.org/~hplus/nat-punch.html'>my article on NAT punch-through</a> or in the chapter about the same thing in Game Programming Gems 5. You can also google for other resources.


Note that NAT punch-through generally works best for UDP networking, but the theory also works fine for TCP connections using "simultaneous open." In practice, that's less often actually successful than UDP, though, depending on implementation specifics of residential NAT routers.

#5075625 recvfrom and WSAECONNRESET

Posted by hplus0603 on 05 July 2013 - 10:34 PM

Yes, it's faster than a timeout, but it's not guaranteed. Some hosts don't send the ICMP; some networks filter them; some machines may quit by being turned off (not being able to respond at all) etc. So you need the timeout, and can perhaps accelerate detection of some disconnects with this message.