Prioritizing packets
From previous articles, you have read about how heavy packet headers can be, and how much they can add onto your bandwidth. This means sending data as fast as possible is out, but buffering for too long is going to mean your data sent to the player is outdated, so it is also out. This is a system I developed myself because I could not find any information on it, but it has proven itself to work time and time again in my engine.
First off, with every buffer you have to send to the users, you want to include a variable that will state the packet's priority, along with one that will state how long it is until the packet is sent. With every packet you send, you specify the priority. For myself, I kept it simple and only specified 3 priority values: None (0), Low (1) and High (2). It is important to keep in mind that if a packet with a higher priority is passed, the higher value is used. For example, if you have a buffer with the priority None, and you add a High priority packet to the buffer, the whole buffer becomes high priority.
None: A buffer with this priority will not be sent. The only way to send it is to send a packet with a higher priority, and the whole buffer will be sent. This is useful for non time-critical information.
Low: Low priority keeps a packet in the buffer until a certain amount of time has elapsed (I used one second). This is useful for packets that are not very time critical, but you don't want to be delayed too much, such as chatting.
High: The high priority will override any other priority. Any buffer with this priority is sent immediately. This is useful for most packets, especially visuals (movement, attacking, etc).
The idea is that the packets that are not time-critical end up "piggybacking" or combining with the more important packets. The difficult part comes in when you start specifying the priority of the packets. This is completely dependant on your game, so I can't help you out there.
It is recommended that you buffer the packets for a short period of time (about 50 milliseconds should be fine). So only check if you are ready to send the user's packet buffer every 50-or-so milliseconds instead of every loop. This way, you won't end up sending a bunch of High priority packets a few milliseconds apart from each other. The client won't even notice the difference.
Movement packets
This section only applies to those who have a game with a scrolling map and as one possibility to approach a solution.
A problem I had before that helped me create this packet prioritizing system was trying to cut down on the movement packets from characters outside of the screen, but keep the characters in the screen on high-priority packets. The best system I came up with was, every time a character on the map moves, check the distance away from every user the character is. If the character is in the user's screen, set the priority to high and be done with it. If the character is outside of the screen, set the priority to None.
But another problem arises - lets say an off-screen NPC moves around a bit, then stops moving. You then move over to the NPC, and don't receive any packets in the meantime (not uncommon on a low-activity map). When you enter the NPC's position, you will not see them in their new location until you receive another packet. To fix this, you want to add a flag that states if your packet has a move packet in it. Every time a character moves while off-screen, set the flag to 1. If the user moves and this flag is set to 1, change the priority of the buffer to High. Of course, when the buffer is sent, set the flag back to 0.
This doesn't solve the problem completely - the packet priority will be set to high a lot of times when the character is still out of view. Though, you do have to take CPU usage into consideration - this is one of the better methods you can use for very minimal extra CPU usage.