Friday, November 14, 2008

The problems with TCP and how to deal with the lack of UDP in Flash (Part I):

In order to even consider doing network programming in flash, we have to thoroughly understand the limitations, and what that means for your project. In this article, I will be specifically talking about the limitation in Flash CS4 to using TCP only. I will not, however, be covering the consequent lack of peer-to-peer communication in this article, which is in itself another major issue and being stuck with the client/server model is a major source of lag.

We all know that TCP/IP is awesome for its reliability and its guarantees, but the 'faster' UDP has to be the protocol of choice for a fast-action game like a multi-dimensional racing game. But, why exactly, and what will happen if I just go with TCP anyway, since UDP is not permitted in Flash? "So what?". "Whats the big deal?". Well, after my experience with the game I am currently making, I can answer that question quite precicely.

The TCP/IP protocol is really cool because it guarantees that unless the session gets disconnected, if packet B was sent after packet A, then B will, guaranteed, arrive after A. Now, this is very convenient. Firstly, it has an implicit guarantee, that every packet you send WILL arrive. So, there is no danger of 'packet loss'. A packet, simply, cannot, be, lost. Awesome! Furthurmore, suppose in a platformer I give the jump command, and then shoot in the air, I know that on the other side my guy won't shoot first and then jump. That would be bad. Finally we avoid all the nonsense of router business, which although is also a problem with TCP, it would be especially more for UDP, which often people use with peer-to-peer communication. By limiting itself to TCP, and not permitting peer-to-peer, it was much easier for Adobe to provide a solution that prevents the user from having to ever deal with router ports and all that. So, this is awesome. No one wants to deal with mess like packet loss and packet reordering. What could there possibly be not to LOVE about TCP?

Well, the TCP/IP protocol guarantees that, no matter what, no matter the cost, every packet will arrive in the order it was sent. And, unfortunately, there is a cost. There is a cost that can sometimes be in the magnitude of seconds of delay. Packet A will arrive before B and C. Even if B and C got to their destination ages ago, the protocol will tell them, 'guys', 'sorry but you're gonna have to wait'. 'We have a lagger'. Then finally when A arrives, all 3 of them, A, B and C are immediately processed at once together, so you'll get a bunch of packets at once.

There are many reasons why A could have gotten delayed. Perhaps it took the 'long way round' in the network. Perhaps it tried to take the shortest route, but unfortunately, also the most congested route. Perhaps it gost lost in the ether some where? 'Oh oh. Now what?' wonders TCP/IP, 'I know! I'll just get the source to re-send A :)'. So again, TCP makes the source try to send A again, and along goes A through the network eventually arriving at the destination. If it keeps failing, then the protocol will eventually give up and disconnect the entire session.

Ok so now we know how TCP, in theory, can mess up, but how can I make it mess up practically? Well, I have found that, in general, the more packets you try to send simultaneously (e.g, in the same Frame), the longer the delay. There is only a certain number of packets that can be reliably sent in a certain period of time, and this number is not undeterministic. For example, in my game an event is sent for every arrow key you press or let go. So suppose the player let go of the right key and started pressing the up and left key all in the same frame or in close proximity, and if I try to send all 3 events as packets, then similarly my server receives all 3 events and broadcasts them to all other players (this aspect itself is very fast, but it is also trying to send multiple packets to the same player at the same time which comes back to the TCP issue; also note that TCP does not support 'multi-cast', unlike UDP which would have allowed the network card to send the same packet to multiple destinations at once *cringe*). All in all, this can result in a noticable delay, more than the normal round-trip delay caused by lag (which on its own would be up to 300 ms within the US for Flash games).

So this is the problem. And unfortunately, this article is already too long, so I will continue with the solution in a future 'Part 2'.

Thursday, November 13, 2008

How to make a Multiplayer Racing Game in Flash:

Before I can tell you completely how to make a cool real-time multiplayer racing game in Flash, I will have to answer a bunch of random questions:

How should one design the Object-Oriented architecture of such a game such that I won't have to worry about redoing everything once my game gets big? How should I implement the physics of a car? How can I detect if a player is cheating by skipping a section of the track, or if he is going the wrong way? How should I design the lobby network protocol such that it provides a robust user experience? How can I deal with the Flash Security Model? How can I organize the symbols in my swf file into multiple swf files? How can I dynamically load 'plug-in' symbols? How should I structure my network communication? How can I make it hard for hackers to crack my network protocol? How should I deal with the lack of UDP and peer-to-peer communication in Flash? How can I syncronize the clocks of all the clients? How can I ensure order of events accross the clients? How can I minimize the effect of lag and make the user experience smooth? How can I make the game robust to network issues? How can I make it easier to debug such a game? How can I create a real-time shadowing effect? How can I create a camera that can center on my car and pan the track? How can I do split-screens? How can I make a mini-map view of the world? How can I possibly test such a game? Infact, can I even make such a game?

"Yes we can!"

But, it isn't easy, and it is a lot of work. And there is no way I can give you the answers to all this... in this post. But these were all just a sample of the questions that I have answered during this journey. Yet, my game is far from done. Questions I have yet unanswered are, for example, how can I draw a car? Or, how can I make some music? But, that is why you need a 'team', with more than just a programmer, who clearly already has waaaay too much on the plate.

If anyone has any more questions they'd like to ask, or if anyone wants to give any question a priority, please let me know.

It Begins!

Welcome! Welcome all visitors, to the blog of the visitee. I am, basically, a Software Engineer by profession, and a game developer by heart. I've been working on a Flash game for several months now (don't really want to say exactly how many months though), and in this journey, there is much that I have learned, and much that I have wanted to share, and much that I have wanted to rant. So alas, I've decided to start a blog...

Flash is big. BIG. Much bigger than I thought it would be before I embarked apon this endeavour. There is too much to learn, too much to understand and too much to do, in order to make the kind of game I'm trying to make: A multiplayer racing game. I will be going over several of the approaches I developed, including those that failed, and I will be discussing mostly intermediate-to-advanced topics that will dwelve deep into the science behind the art of actionscript game-development.