Saturday 14 May 2011

Splash Damage!

If you read my last blog entry, you'll know that I'd hit a brick wall with the Tank project. My TCP-based network code simply wasn't cutting it for multiplayer data transfer over the internet. If I'd have done more research before putting pen to paper (well, fingers to keyboard...) then I'd have known this before I started.

Lesson learned.

So after wrestling with the intricacies of UDP over the last week, I've finally made some headway and managed to rewrite the network communication routines based on this new protocol. I don't want to rave too much about it at this point, because the new build is currently untested over the internet, although it does work well over my home network. Then again, so did the TCP version. A note; if you are considering converting something from TCP to UDP, don't look at some TCP code and think "hmm, how would I make the UDP version of that?" because if you do, you are asking for trouble. The two methods of data transfer are completely and utterly different to each other and the conversion involves so much more than simply replacing TCP commands with UDP ones. Trust me on this. Anyway, I'm not going to write any more about it until I've tested it with the guys from DaGodz, other than to say that I'm glad I took a few steps away from the project for a while. You don't know how close it was to ending up in the trashcan.

So, new developments...

At last, tanks can shoot at each other! A bit of a plus for a multiplayer Tank game I think. To actually show enemy projectiles, I had two realistic choices.

Either
  • Send the positional data of the active projectile to all players except the one who fired it (because they already know). The other clients could then render the projectile based on this data.
  - Plus points: Ridiculously accurate positioning of the projectile, relatively small routine to handle it.
  - Minus points : Massive increase of network data flow, dropped/bad data packets would cause mayhem.

Or
  • Send a signal to say a player has fired, use the client to render the projectile and calculate its path and velocity based on known turret position and angle values.
 - Plus points : Nearly zero additional data to be transferred for each shot fired, client already knows where the projectile will land (even before it is fired!), dropped data packets wouldn't be an issue.
 - Minus point : Not quite so accurate, but damned close (2 or 3 pixels maybe), quite a complex routine to handle the ballistic path.

In addition to this, players who are seeing a projectile being shot (but haven't fired it themselves) would need to generate the explosion at the point of impact, as well as all associated sounds. Bearing in mind these sounds need to be positional, otherwise an explosion at 500 metres would have the same volume as one hitting at 5 metres etc... (Same goes for size of explosion). So much to think about.

So I decided it's best to go for option 2. The "firing" player tells the server it has fired. The server tells all the other players this has happened. All the other players render a projectile and handle its trajectory, point of impact, collision damage and everything else. Here is a picture of my base routine for doing this. (Note this is an early version, and some comments probably won't make any sense. They don't to me, so why should they to you?! My comments are in Green by the way, in case you're a muggle.)

You can click on the image for a larger version if you're interested.



Whilst writing this routine, I noticed a few other areas that could do with tweaking, so I tweaked them. Bad mistake. When the program crashes with some error or other, I don't know whether it's my new routine, or the tweaks I did to the existing ones.

Lesson learned.

One huge problem I have found, which I never expected to be an issue at all, is that enemy tanks are seriously hard to hit! If they are moving, it's nigh on impossible. I'm imagining this will be somewhat of a problem. The grid doesn't look that big when you are driving around in a tank, but when you see how small an enemy tank appears, you get a completely different sense of scale. You only truly see how big the map is once you are dead, and you are presented with an overhead view of the "action". The active tanks are simply minute. To give you an idea of scale, each tank is designed to be 6x4x2 units in size. The game grid is 1000x1000 units.

To counter this unexpected problem, I am planning to introduce two "features". The first one is to have an icon floating over each player, which alerts enemy players to their position. This icon will be highly visible even from a distance (though not through buildings to begin with). I had originally intended to use this as one of the "perks" that a player could achieve during game play, but I think it needs it as standard, otherwise it's possible to drive around for ages without seeing anyone else.

Secondly, and I have no idea at all about how I'm going to implement this, is that the projectiles will have a "Splash Damage" effect on impact. This means that an area around the impact point will also generate damage. Less damage than a direct hit, but still damage. This way it will be possible to cause damage to an enemy tank even if you don't score a direct hit. I could even make this splash damage radius variable depending on power-ups.... (Getting ahead of myself yet again.See? I do that all the time...)

So still plenty to do with the project. I really hope the UDP netcode has sorted out the lag issues, because frankly if it hasn't, this will probably be a LAN-only game. I'm itching to get on to something more original now I have cut my teeth with Tank, and I really don't fancy spending any more time messing with data packets and crap like that.

First few items of the ToDo list...

  • Work out some sort of "Splash Damage" function
  • Make some sort of "enemy is right here" indicator
  • Handle the event if a player disconnects mid-game
  • Improve the view a player gets if he/she is dead and are waiting for the others
  • Start thinking about a front end for all this...

No comments:

Post a Comment

Please leave a comment...