Wednesday, October 24, 2007

Getting a responsive interface

Now that one was a nice challenge. In the first 3 demos, you might notice that movements of avatars were done one after the other and not in a fluid way. Of course, it was ok for the prototype but it was clear it would be unacceptable for the final interface.

After 4 days of pulling my hairs, I finally got it.

My first shot was to lock the keyboard while movement was processing. What I mean is that when a move event was received, the interface couldn't send more /move commands to the server until the animation was done. You need to remember that avatars are moving inside a grid and there's no "free" movements here. So when you move your avatar, you're moving from one cell to another.

Of course, this first shot gave strange results. The avatars were lagging and strangely, I had some difficulties to reset the keyboard state (well, the keypress event) to allow back movements. Anyway, it gave me some weird looking code so I knew I was off track.

After I tried to separate client movement from server events, meaning that a player's avatar movements were handled only by the client while events were sent to server for other players to see. Again, that wasn't a good approach. I ended up with the avatar not showing where it should really be on the server and again weird code for synchronizing events sent with movement on the client. That and all my collision logic was thrown out the window this way (to prevent the current avatar to walk over buildings and such).

Finally, it came to me. All events really need to be raised by the server (as movement) to make sure that what is seen is really what is on the server (assuming there's no lag). Any avatar (current player included) should really only move when the server allow it. And an event sent to the server should really not be aware of what's happening on the screen. The delay between each moves is handled on the server anyway.

So now, each events received are added to an array of events linked to an avatar. Then each avatar has its own thread looking for events inside its array. If an event is available, it is executed and the loop is on hold to prevent 2 events being shown at the same time on screen. This way, I've been able to get fluid avatar movement while a key is hold.

All of this seems pretty trivial now that it's working but I had a hard time figuring out the good way of doing it. Now, I need to do some heavy cleaning on this code and will probably have to tweak some interval values for the loops.

The demo will have to wait since I want to have at least what I had in the last one before showing it. One's thing sure now, things are really getting exciting!