With a heavy heart, I left the Android project late last week. I have been extremely stressed out since the project started. The stress largely came from my experiences with other hobby projects, and comparing those failures to this budding project. I felt like I was nay-saying absolutely everything, and I was; Trying everything I could to get a smaller project, yet only rocking the boat more.
So… after a more than slightly bitter break-up, I am returning my attention to Asteroid Outpost (AO) and my Sprite Maker. I am trying to find small things to work on in AO while I get my teeth into my Sprite Maker.
Over the past week or so, I have decided to tackle the lag issue when slower computers host a multiplayer game. Kind of a funny cause: A long while back, for testing purposes, I disabled XNA’s frame rate limiter so that I could see how many frames per second my modern computer was pumping out. Turns out it’s usually between 500 and 700. In AO, the miners mine at a constant rate over time, so each update, they will generate 2 events and 2 packets: one to decrease the minerals of the asteroid, and one to increase the player’s minerals. After putting two and two together, I figured that XNA has probably tied the Draw and Update loops into one, causing 500 to 700 draws AND 500 to 700 updates per second, in turn causing 1000-1400 packets per second to be created for a single miner! That could cause some lag eh?
The obvious, simple solution is to turn the frame limiter back on, but that would only be a bandaid solution. The real solution is to change the miner’s logic from a constant rate to a burst rate, something like: take and give minerals only 4 times a second. This would reduce the number of packets to 8 packets per second for a single miner, regardless of the frame rate.
An other optimization I will be looking at, is to remove older versions of the same packet in the same outgoing batch. What I mean by that is if miner A is updated first and takes 10 minerals from the asteroid, and gives the player 10 minerals, then miner B is updated and takes 10 minerals from the same asteroid and gives the same player those minerals, there will be a lot of duplicate packets. I intentionally collect all of the outgoing packets for a single frame, then send them all at once at the end of the frame. Here is an example of what packets could be generated for the above example:
Packet 1: Asteroid 1 current minerals is now 250 Packet 2: Player 1 current minerals is now 110 Packet 3: Asteroid 1 current minerals is now 240 Packet 4: Player 1 current minerals is now 120
As you can see… if these packets are executed in order, packets 1 & 2 will be rendered completely useless, more recent information is available for the same entities in packets 3 & 4. I plan to resolve this with a hash-table (or dictionary) where the hash would represent the packet type and destination in such a way that previous, non-useful packets of the same type could be discovered and overwritten with new information before getting sent to the client(s), reducing the packet count yet again.