Sunday, December 17, 2006

Replicating Weapons and Damage

This replication is more involved than the movement replication I did previously. It involves firing a missile, homing in on the correct target, insuring unique missile id across the network, placing explosions in correct places once the missile hits, and replicating broken joints in physical simulation.

All of the above requires decent amount of designing. Just imagine entangling those, and you will get yourself a really messed up system.

So far I had only made on major change - I added robot owner for each gun and missile shot. This was needed to properly report missile events to other clients with ability to check if the missile was shot by a local player (and thus needs to be replicated) or by a remote player (and thus does not need to be replicate).

----

Basic network framework is being tested by every addition of network events. Every new event tests the framework for extendability and maintainability. The framework holds well.

Saturday, November 25, 2006

Movement Replication Completed

The idea has proven to be good.

Now, any time a vehicle moves (by player or by environment, etc.) the event of that movement is sent to the rest of the players. Those other clients receive a message, read where that vehicle must be, and let the robot handle the operation of the vehicle to achieve the desired position and rotation.

According to my tests, it definitely overcomes lag. The worst case scenario is when an event comes in rather late (lag). The vehicle does lag behind the actual location on the originating client, but the robot does move the vehicle to the desired location and rotation. So, this works great.

I have also implemented accuracy setting. Movement updates are sent every time current position is P units far away from the last sent position, or the rotation is R degrees different from the last rotation sent. Currently, this pair of values (P,R) is (1,5), where P=1 means 1/6 of the vehicle's length.

These values have direct affect on two things. One is the accuracy of replication across the network. Another is how much trouble the robot has to go through to achieve the desired position and rotation.

This last issue can be a problem at low values of P and R. The reason is that vehicle does not turn on a dime, instead its turning mechanism (4 wheels on one side, 4 more on another side) has an error, so the rotation causes the tank to move away from its original position. This means that vehicle gets too far from the desired position (more than P units), and now it must first get back into the position, before continuing to turn. You can now imagine that at low values, this turning error will cause the robot to really struggle to get the vehicle into the position. And that is what it did in my tests.

While the above is not a problem, since I intend to keep values of P and R high, it is an indication that turning mechanism of the tank must be improved. One possible solution is to alter the power of both sides (set of 4 wheels) in order to achieve equal turning power, kind of like ABS for vehicles, which alters the power of the breaks on the wheels to prevent loss of contact with the ground. This is, however, is rather complex, so if I do decide to do it, it won't be soon.

Sunday, November 19, 2006

Improving Movement Replication

By far, the most important events to copy across clients are the movements of the vehicles. In my current implementation, I simply send events that describe what command a player pressed: forward, backward, turn left or right, etc. This works, however, there are two problems that create large difference between clients.

One is lag. Events do not reach other clients right away, so all commands are executed later than they are actually started on the original client. So, this leads to some differences. However, this difference is not that big. The main problem comes from the second problem.

Physical simulations do not run the same way on different computers. This means that if a vehicle turns to the left for one second on computer A, the vehicle may turn 40 degrees, while on computer B it will turn 35 or 45 degrees. This causes large differences very quickly.

So, another solution is required. One roadblock is the way my vehicles move. Their movement is produced by a complex interaction of bodies, joints, and motors. So, I cannot do what many other simpler games do: manually "move" the tank from one position to another, and then smooth out the movement by using dead reckoning. I simply can't do that on my vehicles. They want to be controlled by physical laws (Newtonian), and do not like to be warped from one place to another (This may be limited to the specific engine I am using) or be forced into one position or another (by using direct external forces on vehicles, for example).

However, while these vehicles want to be "manly" and not be pushed around, I can control those vehicles via usual commands, exactly the same way that player controls the vehicles: IVehicle::moveFoward(), etc.

So, my idea is to send updates on vehicles position and orientation, and have vehicles on other clients, try to get into this position. They can turn turn and move, whatever they decide to do to get into desired location. (Btw, control is performed via IRobot's)

This solves one important problem for vehicle movement: even though simulation may run differently, robot-controlled vehicles will take care of the differences by adjusting their movements to get into the position.

Granted, this does not resolve the first problem, the problem of network lag. But this is something I cannot remove at this moment. Lag simply exists. I may decide to predict the movement on remote clients, however, if there will be a need to further improve the movement replication.

Monday, November 13, 2006

Child Steps across the Network

After spending 25 hours of coding in just two days during weekend, I have developed first operational network events.

Server is now operational. Clients can connect at any time. Once connected, they are sent appropriate Id for vehicle and robot for the new player, and those same Id's are sent to existing players. Thus, all players are now replicated.

Current event cover all tank movements, tank's tower rotation, and missile firing. All such events are now broadcasted across the network.

Overall, I had a blast this past weekend. It has been a while, since I made an awesome progress with URumble. And this one was hard earned, but was well worth it. I can feel pride kicking in again. This means I can push harder then before to develop more and more features into the project. I may have a working demo within months now. And possibly a beta for the New Year's Eve! :D

That would be the best gift I ever had.

----

OK, I have a few technical comments as well. The entire network code runs on RakNet library. It is GPL licensed for free projects, such as mine. Many thanks go to the creator of RakNet for the free version of his library.

RakNet is not a high-level library. It does provide a tons of low level features, and a few medium-level ones, but overall, I had to built an entire event framework on top of RakNet. I will probably release my framework at some point in the future as GPL or similar license.

I first tested the connection on my wireless at home, between my desktop and laptop. I had a really bad lag, though, from 0.25s - 0.5 seconds. This is really bad. I was stunned. I suspected that my wireless connection is really bad, so I tested at my university on 1Gbit LAN. Oh, man, what a difference, I could not notice any lag at all with my eyes. It must have been in the order of a few milliseconds!

Other than that, developing events has been very easy. One thing though is that I have create a new class for every event (by implementing an abstract interface), as well as adding a new type Id for the event, and adding a few lines to EventFactory, so it knows about this new type, and appropriate new class. This is rather annoying. I'll think about a better solution in the future.

Saturday, October 28, 2006

Refactored Core Framework, Back to Network

After a very long pause, and hours of work and designing new component-based framework, the code is operational once more. I had disabled a lot of features, such as particle effects, and graphics optimizer, since I have designed how to integrate it into component framework.

However, new framework is awesome, especially, new XML format for it.

Before I finished migrated all components, such as particles, etc., I want to delve into network once more. This time I have a better vision of what and how things need to be done, and have already implemented basic server. Events are being sent across the network, new players requests and receive their data.

It is time to start dishing out new features yet again. It is time to return from the sleep of many months where I developed very little.

Friday, August 04, 2006

URumble2 on YouTube.com

Some time ago I've uploaded a video on video.google.com. Now I've uploaded the same video to youtube.com: http://www.youtube.com/watch?v=EQjnSBOSgTM

Let's see how it will go.

Saturday, May 13, 2006

Oops! Time to Refactor Messy Code.

I decided to make a major, very major rewrite of the code class in URumble 2. Here is how it started, if you've coded something large enough, you probably already know the story.

(I will lay out my thoughts below. It was a discussion between a worker and a insulter (both parts played by me))
---------------------------
Worker:
Well, it is finally time to kick the network code, and get something going. Let's see I've got basic framework ready to go.
Insulter:
Are events being sent to the server? I bet something is messed up there. :D You've not touched network code since last year.
W:
Hmm, StopVehicleEvent is flouding the network.
I:
Bingo!
W:
That's cool I've migrated to OIS from OGRE demos input system, so something has changed.
I:
Nooo, really? I thought you write unittests for everything?
W:
Well, not that one.
W:
How about implementing events to report new player, get a vehicle id, and transmit it to other clients as well, so we can have a 2 player battle? No problem, I just wrote some docs, so now I have an idea what to do.
I:
This network looks complicated. I bet something is going to fail.
W:
RequestVehicleEvent should do it. Alright, that's done, now connect it to something, so that a vehicle is created as requested by the event.
I:
Hahaha, I can see how messy rgf::scene::Scene has become! Oh, I see you hard-coding what vehicle to load from RequestVehicleEvent.
W:
Just for a test, man, I'll improve it later. OK, compile and test.
I:
Booya! It compiles but doesn't link. Principles still hold, baby.
W:
Shooo! What's the problem?
I:
rgf::scene and rgf::physics can't resolve their linking, b/c they are so tightly coupled. Nice, I thought some smart ass was going to cleanly decouple rgf:: components?
W:
No problem, let's decouple them.
I:
I like it, it's getting uglier. Some core classes in rgf::scene are half-implemented, half-used, and just bloated with various hacks and hooks to get stuff done. That "assert(false);" looks really good.
W:
Jesus, where was the last time I've touched this?
I:
A year ago.
W:
Dang, I will put the network aside for now. I gotta rewrite this rgf::scene and rgf::physics.
I:
Haha, not so quick, plenty of other things depends on how rgf::scene and rgf::physics work, for example, their concrete implementations: ur::scene and ur::physics.
W:
8-O Indeed. Time to make a SVN branch, and get started.
---------------------------
To be continued...

Friday, May 12, 2006

Passed Physics, starting Network again

I have cleaned up and updated physical tasks. A simple castle was created to populate the scene. A tank has been redesigned into a more complex structure. It has 8 wheels and 17 more parts. At the moment, there are no graphical models for them, so I created empty placeholders - very nice white boxes. If you can model anything that is beyond white boxes, drop me a message. I'll be pleased to show your work in the project. Take a look at this manual. It describes what I'm looking for.

Now I feel I have enough content and features for network testing. The first goal is to have two player interact. One server accepts both of them and exchanges events. That's not much to ask, and that's the point. One small step at a time has gotten me this far.

Once network is up and running, I will add a firing event, and see how the game feels at that moment, and reassess the goals.

A little bit of history: network framework was started a year ago, Summer 2005, but was left off at the basic level of functionality - ability to simply sends events between server and the client. That was accomplished by another programmer on the team, Greg Horvay. However, Greg did not continue network development and instead switch to GUI development. Now, I'm done with current physics iteration, and have a choice to make. My choice is to develop networks.

Why networks and why now?

I would like to close the loop. By the "loop" I mean have some game play experience. At the moment, a user can drive around and shoot stuff, but there is no one and nothing to play with. AI code is far from ready, but the networks are close, and can be accomplished in, what I hope, next month. This will allow two player to play against each other. Thus the loop will be closed, and from proof of concept, the project will enter the stage of a playable demo.

Sunday, April 30, 2006

Movie on Video Google

I have created a movie of the recent development code running on some really high-end machine, and uploaded it to the Video Google program. I highly recommend both the Video Google and the movie.

The movie was recorded on Linux using xvidcap.

Music from "Dark Overlords of the Universe"

A fellow from my university has gracefully agreed to provide me with his band's music. For now, I have picked one song for the introduction GUI. It's the song "Going Agro!" ('agro' means getting angry).

Here is the band's site: http://www.darkoverlordsoftheuniverse.com/
And their logo:

Big thanks, guys!

Pulling GUI and Sounds

Another developer on the team has created GUI component of the project along with a new project states management - GameStates. This makes for a better approach then old way of simply following OGRE demos code. Now, GUI and the rest of the code are tied up. And more importantly the code feels a lot better, that is cleaner and easier to maintain.

Another big component that made its way is Sound. For this, I rewrote my old code for OpenAL to work with Fmod. I had some problems with OpenAL running on my Windows, so I decided to ditch it. When comparing Fmod with OpenAL, Fmod has a slightly better interface since it uses a bit of C++ as opposed C-interface of OpenAL (I prefer OOP when dealing with large project such as Ukrainian Rumble). The problem however is that Fmod still feels like a C-library. Even though it offers "Objects", they are very rudimental. For example, error handling is done by each function returning a FMOD_RESULT objects which is a enum (yes, every function does that with a few exceptions). So after each Fmod call, you need to call some method to check for errors. This is rather annoying. Exception handling would be much better, but those guys have their reasons. Nice C++ interface is not on top of their list. One way or another I made a wrapper around Fmod to give myself something I can live with. Other than the interface, Fmod seems to be a powerful system that supports all major platforms, including upcoming next-gen consoles.

Now, writing a wrapper for Fmod is a simple task compared with making sounds feel right for the game which heavily relies on physics. This means that I am dealing with a "messy" system (physics engine) that does not provide exact same results for every run. Furthermore, physics give you a range of results. For example, let's say you want to play a sound for each collision. OK. I create and assign the right classes, etc. Run the application. Here is what I get: a sound for each collision, no matter how small or big it was. Alright, a threshhold is put in place, and now collisions are filtered out. Now, I notice that those collisions don't reflect real life, for example I might get 5 collision for an object simply sliding. Another thing is that collisions vary in magnitude (big and minor ones). So, now I need to add a filter to set a correct volume of the sound. After this, we get into situation where different collisions should sound different. Think of sliding motion or simply different surfaces. Mmm...

One note about sound. Once you add one, you need all of them. This is because with no sound you don't notice that everything is silent, but once you have a single sound effect, your mind expects to hear other sounds as well.

All in all, GUI and sounds add a lot to the project. It feels more complete now.

Saturday, April 08, 2006

Missile Controllers are done.

After "some" work, missiles actually fly, and home in to their targets. It turned out to be much harder than I thought they'd be. Most problems came from improper math calculations. Especially hard to track were bugs that were related to local coordinate system of the objects, which caused problems for missile rotations, spin, and control thrust. This in turn caused confusion in the controllers that did not receive correct missile status, and made wrong decision how to correct them.

What this means for bug fixing, is that there were multiple layers of interactions, so a digging was necessary to identify actual problems and not their results.

Man, I imagine how much work it took to implement control for real-life air missiles.

Here are missile trying to hit each other. Yeah, missiles at the moment are trying to hit anything you click on.

Sunday, March 26, 2006

Missile updates

Missile controllers have been implemented to a certain degree. However, there is a bug, which causes them to improperly spin in the flight. It seems that spin is always around side axis (perpendicular to the target and lying in the plane parallel to the ground).

There is a bug where deletion of a target is not handled properly. I think I'm closed to nailing that one, though.

Migrated to OGRE 1.2RC1

A week ago, I've migrated code to OGRE 1.2RC1 from 1.0.x Overall, it came through without blocks, but with a few rough spots here and there.

First of all, crosshair does not appear anymore in Linux, but it appears in Windows builds. This remain untackled for now.

Second, mouse control is wacky on Linux. For some reason Ogre::InputManager::getMouseRelativeX() returns large numbers from time to time. Maybe something changed. I'll take a look at OGRE demos to see if anything different has appeared in them with mouse control.

Big thanks to OGRE team for awesome open-source 3D engine.

Thursday, March 09, 2006

Missile Controllers and CrossHair

The framework for new missiles and their controllers have been finished. Crosshair have been added as well, which is the first time it's been added to the project. I wasn't planning to have them actually, but here is why I've added crosshair. The idea is that manual firing of missile is hard. To simplify aiming, I've decided to implement homing missiles. The crosshair will be used to point at the object you want to shoot, and the missile will follow the missile even if the object will be moving. Of course, homing missiles won't be perfect, and I expect plenty of cases when they will miss or hit an obstacle before reaching the target. This should make for some fine strategy and tactics.

Sunday, March 05, 2006

Watch Out For Parasites!

Here is a funny bug, I've uncovered from working with latest missile framework. (It's a rewrite of old clunky system.) Those look like really nasty parasites, don't they? Got some spray to ward them off? :D Or maybe it is a new weapon? :DDD

Full size screenshot is here.

parasite attack screenshot

Wednesday, March 01, 2006

Jet Thruster laid off. Game logic continued.

Recently, I took a long and hard look at the jet tank. What I saw was that flying controls and mechanics have taken a lot time, but have not progressed to a usable state. So, I decided to leave it for now, and move on to everything else. I will come back to flying tank later after the core of the game play is done.

Game logic. The first thing to tackle is a better missile - homing missile. You don't need to guess the arc of its motion anymore. You just point at the object you want it to go, and press/click fire. The missile homes in to the target, though it may miss if the object does something tricky, such as hiding behind an obstacle, or maybe shoot the missile down.

Once the homing missile is implemented, I will work on creating a crosshair for aiming, add ray casting according to the position and orientation of your camera. Then the whole missile feature will be done. You will able to aim and send homing missile anywhere you want them to go.

Though, I will have to add an option to a homing missile to simply go in some direction, if you missed everything on the map, such as clicked on the sky or something. I'll think about that. 8)

Tuesday, February 14, 2006

Jet Tank Turning

Recently I have been battling the complexity of the jet tank control. My estimations came true, as I struggled to counter-balance the tank's rotation, balance, and movement features. Balancing was an easy part with barely any problems at all. Movement seems to be OK, although I've not dealt into it deeply enough yet to really assess the situation. The turning has been the feature that has been boggling my mind for the past couple weeks.

It is coming along with a glacial speed. Learning from my College class, Software Engineering, I've been busy performing root-cause analysis. For us, simple folks, it stands for debugging and tracking down improper behavior of your code.

Recently, I have gotten some "fresh air" and tackling the implementation with new vigor.

P.S. Another thing, that is getting in the way, is that I would like to show off this jet tank on the upcoming internal College competition among Engineering departments. Only 2.5 weeks left.

Monday, January 16, 2006

Jet Powered Tanks

I have recently read the book titled "New Space Era and the Fall of NASA." It opened my eyes on many things and had altered my game idea. Ground vehicles are not the hype anymore. Flying ones are the way to go. Imagine an ion-thruster tank that can hover/fly low above the ground, and quickly decent on the enemy's location.

Imagination is a nice thing to have, but the implementation and control schema are challenging. The results have been cool so far, so I will stick to the idea and get it done.

Wednesday, January 04, 2006

Praise for KDevelop

Most of my development is done in KDevelop under Gentoo Linux. On the other hand, I still compile the code for Windows platform via MSVC .NET

In my opinion, KDevelop is much better overall, while not in all aspects.

I have stumbled upon a good article about KDevelop vs. MSVC .NET.