• entries
298
1135
• views
231580

# The "Online" part of "Skirmish Online"

128 views

ONLINE!?

Finally the networking begins!

There's not yet a fancy interface for selecting one's alias, or some spiffy way of informing the game whether you'll be hosting a game or joining one, but for now it's just a simple no-hassle console app query. Ugly but effective. Nothing is in stone yet, but I may be checking out the nifty CEGUI library for my future GUI needs.

Since the IP to connect to is hardcoded at the moment (me! me!), most of you will be choosing 'C'. Based on said choice, the game will create either a GameServer or GameClient instance and get things rolling via the wonderful RakNet lib, which has been nothing but an asset thus far. [smile]

Long story (very long, gah!) short, the server and client do their jobs in listening and sending data in/out, can detect connections/disconnections, maintain a list of remote players, and such. I dislike how it sounds pretty darn simple when I do over the gist of what I've done here, but in the code it's a completely different story. I've been refactoring my head off today, removing a useless abstraction class called RemoteClient that resided between the network interface and the actual Player class. Useless!

The first step -- after boring initialization and foundation stuff -- was to get player creation/login occuring both: a) when a new player logs in, and b) when sending all existing players to a newly logged-in player. This didn't take long; Mushu, Ravuya, and DarkCampaigner assisted with the testing. (Thanks guys!)

Next up was basic movement. I know that movement prediction is a really crucial step, since its accuracy will determine the playability of the game. If I do a poor job, then bullets will appear to hit on some clients, and be clear missses for others. It's this kind of this that makes writing action games online a nightmare. I intend on keeping the server-authoratative system I had previously, since it proved not only the most accurate, but additionally prevented devious hackers from doing nefarious deeds. Anyways, basic movement consists of merely sending the player's position and rotation 4 times per second (every 250ms). The server simply bounces the message off to all other clients, and they update the remote player's sprite. Very simple, but it looks a heck of a lot better than everyone sitting on their collective arses. :P

(Click for bigger)

Fonts revisisted (and DirectX temptation!)

I don't care what anyone says: fonts/text-output in OpenGL is a huge pain in the backside. There's a smorgasboard of ways to do it, whether it be outline fonts, bitmap fonts, texture-mapped fonts, or some combination of those, but all are fairly equally a pain to implement. At least compared to the awesome D3DXFont interface that Direct3D provides.

And had I not chanced a conversation with Ravuya (GD.NET's active cross-platform (and by association OpenGL) proponent), I would have been spending part of tonight, tomorrow, a few days thereafter rewriting all of my graphic code to Direct3D. Phew.

Basically, I gave Ravuya's RavBitmapFont class another go. Apparently the constructor I used was deprecated -- it didn't like Targa images, or somesuch -- so I converted the image containing the relevant image data to a PNG, whipped in the new constructor, and BAM! It worked. Sort of. I tweaked things around a little and soon had it working exactly like it did when I was using the wgl bitmap fonts. Except now it was running several times faster. Wonderful.

In my thankfulness, I offered to beef up his class a bit. He was using plain intermediate calls (glBegin(GL_QUADS)) and such for each character, so I decided to give a shot at having it render via display lists. And so 30 minutes or so passed. I was disappointed to learn that my work resulted in a speed drop. Turns out for something as tiny as a single quad, DLs don't offer any real speed gain. All was not lost, however. I optimized several of his state-changing calls and now I'm getting fonts rendering even faster than the lightning speeds I was already getting.

If one looks at the above screenshot with me and Ravuya, it may be worth noting that when Skirmish was using Delphi+Direct3D, I was getting around 40 FPS with that much text and scenery going on. Now I'm getting upwards in the 130 FPS zone. This is a real thrill because earlier in development (with those SLOW rasterized bitmap fonts) I was really worried about performance being cruddy. Now I'm absolutely thrilled that speed shouldn't be a problem even on lower-end systems. System tests to come. [smile]

Further optimizations

The idea of having collision groups has sped up my execution speed hugely, as well. The gist of it is, there are (will be) three types of game objects capable of collisions: players, map objects, and projectiles. My old collision detection loop looked something like:

for a = 0 to big_sprite_list.length-1  for b = a+1 to big_sprite_list.length-1    CheckCollisions(a,b)

With much prettier C++ code, I assure you.

(As a cool sidenote, I find it very neat that my taking of Discrete Math/Geometry last earlier this year has had such great benefits for game development. My gained knowledge of permutations/combinations has been hugely useful in determining things like how many collision combinations can occur, and the vector math was also a huge boon. In short: stay in school!)

This code is bad, since not all sprites have a relevant collision result with other sprites. If there are 500 sprites in the game, we'd be seeing a hideous 124,750 iterations/checks. Gah.

So the new idea is that we store all sprites in one of three lists: playerList, mapobjectList, and projectileList. Map objects don't need to check collisions against any other sprite (they are purely passive), projectiles need to check against both players AND map objects (purely active), and players only need to worry about colliding with map objects (semi-active). So our total number of collision iterations falls down to:

(numPlayers * numMapObjects) + (numProjectiles * numPlayers) + (numProjectiles + numMapObjects)// Which conveinently can't be factored :P

This has resulted in a big boost in performance -- in a sample case, 5000 versus 100,000+, gah! -- which also adds to the overall FPS at the end of the day.

Not really an optimization..

I (stupidly) found myself amazed today, when I ran Skirmish in Release mode (no Debug data generated/used) and my FPS suddenly doubled. Wow. In Delphi -- which until now has been my main gamedev medium -- never really gave a speed difference in Debug versus Release modes, so this was a whack in the forhead to me. Uh, the good kind of whack in the forhead. [smile]

White magic :)

I think you have the same wallpaper as me >.>... Digital Blasphemy?

That's the last thing I would have suspected someone to notice in his screenshots! Looking good HopeDagger. Just a question, how hard was it to start out in 2D with openGL? I've been trying to do that in Direct3D, albeit very very half-heartedly, and it's giving me a headache (probably because I'm not motivated <_<).

Cheers
Jacob

Do you have an estimate on how long it'll be before you start knifing me again? I'm assuming you can get it to a playable state before school starts for you, you productive deviant! [wink]

Damnit. Make this thing portable you fool. Just because I own a Mac doesn't mean I don't want to frag the shit out of you.

Looking niceeee

Quote:
 TheSeer wrote.. White magic :) I think you have the same wallpaper as me >.>... Digital Blasphemy?

Indeed. Although that wasn't quite the focus of the entry. :P

Quote:
 Jacob scribed.. Just a question, how hard was it to start out in 2D with openGL? I've been trying to do that in Direct3D, albeit very very half-heartedly, and it's giving me a headache (probably because I'm not motivated <_<).

I didn't have any real problems, but I've been using OpenGL on and off for a couple of years now, so I'm no stranger to it. ;)

Direct3D isn't something I'm quite a knowledgable in, but I would likely just be using the D3DXSprite interface to handle most of the 2D needs. Give the folks on the DirectX forum a poke if you need a hand. They'll be more than happy to help. [smile]

Quote:
 Mushu proclaimed.. Do you have an estimate on how long it'll be before you start knifing me again? I'm assuming you can get it to a playable state before school starts for you, you productive deviant!

I think it will be after school starts, for sure. Things are moving well, but there's no way I can create the new item/weapon editor, implement said weapons, a particle engine, and proper collisions in 9 days. Skirmish might be cool, but it's no Simon. [smile]

Quote:
 visage declared.. Damnit. Make this thing portable you fool. Just because I own a Mac doesn't mean I don't want to frag the shit out of you.

I'm very interested in doing this, actually. I've intentionally used all portable libraries so far (SDL, DevIL, OpenGL, etc) so it shouldn't be too bad to port it to Mac and Linux. Ravuya has already offered to do the former.

Per your Delphi optimization comment: Delphi does weird shit with optimization. I've read over the assembly that Delphi programs generate, and it is just fucked up.

It's not slow, but damn. I can understand why their code works so strangely; the optimizer appears to have no understanding of code movement.

Check out Writing Great Code Vol. 2: Thinking Low-Level, Writing High Level for a bit more on the various optimization qualities of different languages.