Tuesday, September 10, 2013

Server Updates

Temporary Login/Title Screen
So, after having good success moving the client to Unity, there were still some issues.

My primary concern was that there were now two physics engines involved:  BEPU on the server, and an old version of PhysX which Unity was running as the client.

Now, I wasn't certain that this would cause problems, but I'd done some fairly deep dives into the quirks and behaviors of BEPU, so it seemed pretty likely.

It would have been really nice to be able to use the Unity engine from the Zone Server.  If there was some way to simply include it as a DLL and run it, that would have been fantastic.  This is a familiar refrain you see all over the Unity forums, particularly the networking on.

Sadly you can't, of course, and I'm not surprised.  So, one would think that-would-be-that.

Tuesday, August 13, 2013

New Posts Soon

I've just finished moving, and let me say that if I don't do that again in a long time it will be too soon.

Anyway, quite a lot of interesting dev work has happened in the last week or so, but I've been too busy packing and moving to write anything.

Monday, July 15, 2013

Radical Changes

I'm making some radical changes to the development path I'm on.  I've had an increasing number of small but extremely irritating and time consuming problems with the game client.

I've decided that I just don't have enough time to work a full rendering engine as well as the back end servers, database and game administration projects.  So I'm taking a new path with the most troublesome, the game client.

Monday, July 8, 2013

A Tiny Slice of DLL Hell

So I've begun preparing for a little ultra-pre-Alpha.  No real gameplay, just a test of the networking and physics.

In order for this to proceed, though, I naturally had to test to make sure the client would work on other machines.  Also I wanted to run the servers on another machine as well.  Everything worked fine together on my Dev box... but you know how that is.

Saturday, June 1, 2013

Physics Mismatch... of Bepu Physics and Small Rotations

So I've been working on syncing the physics between the client and server implementations.  It's been... a bit painful.

Varying Update Rates Hertz a Lot

One of the first things that tripped me up was the different update rates.  The client is running at the regular 60 fps, i.e. updating every 0.016ms.   The server is running a much more sedate 10 updates per second, or every .1ms.

I had assumed that passing the delta time into the physics simulation would deal with the difference.  I.e. it would know either one sixtieth of a second or one tenth of a second had passed, and simulate that amount of time passing:

physicsSpace.Update(elapsedMilliseconds);

First, this was WRONG, and a very common mistake!  Turns out Bepu wants the time in seconds, so really I'm telling it to simulate x1000 speed!  This is correct:

physicsSpace.Update(elapsedMilliseconds/1000.0f);

Why didn't I notice this right away?  Well, it turns out Bepu has a default timestep for its simulations, which happens to default to 1/60th of a second.  And it will only perform a certain amount (default three) physics steps per update.  So by default Bepu will simulate .005 seconds of time (3x0.016), maximum, per Update call.  Mind you, these are quite sensible numbers for defaults.

So really when I was passing in weird values like 16 (16 milliseconds, 1 frame at 60fps) I was actually asking it for SIXTEEN seconds.  In return it gave me 0.05 seconds, which is near enough to .16 that by the naked eye I couldn't tell the difference.  On the server it was getting 100 (100 milliseconds, the update period at 10 fps), so it though I was asking for a bit over a minute and a half...

So, problem number one was I was passing milliseconds rather than seconds.  The defaults were ok for the client, but clearly the server running at 10hz would still be wrong.  Each update would need to simulate 100 milliseconds of time, but by default Bepu would only step 50 milliseconds.

Easily fixed by a bit of reading through the docs and forums, however.  You can change the maximum number of timesteps simulated:

physicsSpace.MaximumTimeStepsPerFrame

... though I did not change this.  Really you want a one-to-one normal ratio, with the ability to simulate extras if for some reason the simulation falls behind.

More importantly, you can change the expected simulation step temporal duration:

physicsSpace.TimeStepSettings.TimeStepDuration = timeStepDuration

where physicsSpace is the Bepu object, and timeStepDuration is set in the simulation engine initialization call.  So the client and server both pass in their expected update tempo, and the physics engine deals with it.

Velocity Mismatches

That fixed some of the differences I was seeing between the client and server, but there was still one bothersome one.

For small accelleration values (angular or linear) despite the fact that I had set the entity's AngularDamping and LinearDamping values to zero (this is a space simulation after all) the AngularMomentum and LinearMomentum values were still damping down to zero over a short time... but only if they were very small.

I was deeply confused and verified again and again that the damping was zero, and kept looking for where I had gone wrong.  This was throwing off the client and server sync, ans the client seemed to damp down quite a bit quicker (which seemed like a useful clue, as I knew it ran more, but shorter, simulation steps.  So it had to be some sort of per-step, rather than per-time-unit effect).

I finally found the answer. On the Bepu forums, someone poses basically the same question, and Norbo answers:
That's caused by the deactivation system. It will attempt to stabilize and disable very slow objects. You can prevent it from freezing entirely by setting the object's IsAlwaysActive property to true. However, stabilization will still be applied. You can disable stabilization separately by setting the Space.DeactivationManager.UseStabilization to false.
Stabilization is nice to have on in the general case, though, particularly if you have complicated interactions like large stacks or constraint systems.
You can also tune the Space.DeactivationManager.LowVelocityTimeMinimum and Space.DeactivationManager.VelocityLowerLimit. Stabilization only occurs under the velocity limit, and deactivation will not occur until an object is below the velocity limit for the time minimum.
By default the velocity lower limit is .026f.  Thus I added:

physicsSpace.DeactivationManager.VelocityLowerLimit = .001f;

Well, that solved a lot of problems.

Tuesday, April 30, 2013

Outlining Post Process

I've been working on the (temporary simplified) screen where you select a ship.  Currently when you click a ray is cast into the scene's physics space and the first entity hit is pulled back.  That's the one you clicked on, basically.

To visually implement this I had simply tinted the selected entity red when it was drawn (from the model rendering shader):

 if (isSelected)
  output.Color.r = output.Color.r * 2;

Clearly that was a bit... simplistic, though it was enough at the time and it worked.  But now I needed something a little better.

Sunday, April 28, 2013

Temporary 'Hangar' Screen

In working towards something vaguely playable, I've fleshed out the screen you get after logging in, the 'Hangar' screen.  Here you'll pick a ship type, then you'll be able to move on to actual gameplay.

When a client connects to the Hangar 'zone', the server gives it the entity list.  For now, there are three items (well, one is a group):  a destroyer, a corvette and a fighter squadron.  These are all synced from the server, so this list can easily change without any changes to the client.