potato's Spud Farm

Monday, October 6, 2008

So, if you've been following my blog (insert snickers and jeers here), you'd know that my Xbox 360 died a short while ago of the infamous Red Rings of Death. What I may not have mentioned was that my MacBook Pro has been on the fritz for a while too. In fact, it's been on the fritz for the past YEAR or so, but I simply haven't been able to afford any downtime to get it fixed.

So now that my Xbox is repaired and on its way back to me, and I've finally sent the MacBook in for repairs... I suppose it's a good idea to sum up my support experiences on both sides. Both Apple and Microsoft do some things well, and other things in really, really, really dumb ways. Particularly Apple (you might be surprised!). The two companies seem like the antithesis of each other: MS being the faceless mega-corp, while Apple is known for their cordial and friendly service... The results may be surprising, read on.

Apple

So about 3 months into my MacBook Pro's poor lifetime the front latch (the thing that keeps the thing shut) broke. The lid would no longer close, causing all kinds of problems. Unfortunately at the time the laptop was my only link to the civilized world (the student ghettoes in Ottawa, Canada, cannot be generally considered as such, especially in winter). I got it fixed a couple of months later, when I was back at school (the school was an authorized repair dealer).

The warranty process was surprisingly hard to deal with. Apple has the best phone support line I've ever experienced - short waits (usually <5 style="font-weight: bold;">

Microsoft

On the other hand, my experience with Microsoft has been nothing but smooth sailings:

Called Microsoft, got a helpful rep who spoke perfect English. No trouble at all. She walked me through a few steps to make sure my console was genuinely dead. Within about 10 minutes of calling I was giving her my mailing address to send the return box. And then something bad happened to their system, and they were unable to process the return request. She gave me a ticket ID and asked me to call back at a later time.

Called back the next day, got an Indian fellow who didn't speak English so well. Thankfully, my return was already authorized, so I gave him the number and he entered the return into the system. Box was on the way. On the side note: troubleshooting the Xbox with him would probably have been a pain given how much of a communication barrier there was... I think *when* you call may be important.

Box arrived in 4 days. Not as quick as Apple and their 2-day turnaround, Apple definitely wins this one hands down.

Return was via UPS. This worked out great, since there were FAR more UPS shipping location than DHL. Did not require me to trek all the way across downtown. Unlike Apple, they did not provide me with a tracking number...

So the Xbox 360 died the other day. I can't say I'm terribly surprised - in fact I'm terribly surprised it hasn't died *sooner*. This is the one that was a launch unit, went through the checked-baggage gauntlet that is air travel several times, and survived all of it, barring a slightly gimpy DVD tray.

It was entirely surprising to me when it died just standing there. Rock Band froze up at the most inopportune moment, I power cycled, and ahead stared the worst sight an Xbox owner can imagine :(

I was dreading the inevitable call to Microsoft tech support - oh boy, I thought, they must try to weasel their way out of as many of these as they can. Heck, even the vaunted Apple screwed me when my lemon of a laptop arrived.

Nope, I called them, and right away they shipped a box out to me to pack the Xbox in. Coolness. Never had THIS smooth of a customer experience with anyone, though I suppose they've certainly had enough practice...

And I only got a few days to use my new headset :( Slightly annoying volume control placement, but oh-so-sturdier than the piece of crap Microsoft shipped the Xbox with. Bah, now it has to sit here for the obligatory 2-3 weeks while I get no fragging done :(

Thursday, July 10, 2008

So my... third... foray into blogging about my life has so far been a pretty spectacular failure, no updates for 3 months? Lose.

So, just for kicks I've been writing a small PHP authentication library for myself lately, nothing too fancy or spectacular, and it's been kicking my ass.

The basic structure is simple - once authenticated, the system stores some data in a cookie - the username and a hash of a various bunch of things, including the user's password. As the user moves about my site the system just checks the hash for validity. Elementary, but works well enough for a low-traffic site that doesn't demand iron-clad security.

Notice the difference? PHP was friendly enough to provide this explanation:

Note: The magic_quotes_gpc setting affects the output of this function, as parse_str() uses the same mechanism that PHP uses to populate the $_GET, $_POST, etc. variables.

Which means that, as a means for security, quotes and slashes get escaped properly. Great. I don't see any quotes or slashes in my input. What gives? Google hasn't turned up anything relevant, so I'm unfortunately stuck on this.

Saturday, April 12, 2008

This won’t make much sense to anyone except people familiar with my code... But I've been thinking about writing a real-time game network library lately, and came up with this on my way home...

Variables will be wrapped in classes. CReplicatedVar is the base class.

Data types will derive from this, including CReplicatedFloat, CReplicatedBool, CReplicatedInt.

More complex data types like CReplicatedVector and CReplicatedMatrix will derive off the primitive replicant.

The class initializer should specify update frequency in terms of server frames. This allows us to effectively express network update frequency as a percentage of total throughput.

When it is created it will register itself with the network engine. The network engine will update each variable with each server update.

The network engine is responsible for keeping the last X server snapshots, enough to derive an effective interpolation and/or extrapolation of the variable’s value. Some variables are on/off and do not require interpolation.

Each variable has a Get(float time) action, which will get the interpolated value of the variable given what the network engine knows.

Note to the above: This also means we need some way to cache server snapshots so that we’re not constantly doing array lookups and interpolating, a rolling array index may be a better way to do it.

Some thoughts on game code:

Each entity will have a FrameThink() and Think() function. These are used exclusively by the server and will not execute in plain client mode.

Each entity in addition will have a ClientFrameThink() and ClientThink() function. These are used exclusively by the client.

It is expected that the vast majority of functionality, particularly gameplay-specific functions, be implemented server side only.

The Render() function is strictly client-side, as the server has no rendering capability.

Meshes and other preloads that are loaded at OnLoad() are still loaded server side, as their geometry or data may be used in the entity’s thinking.

Wednesday, March 19, 2008

Continuing from yesterday… I’ve discovered several very interesting articles on lag compensation in real-time environments. The first is from the author of the Unlagged! mod for Q3A, the second a discussion of lag compensation network transmission protocols in the Source engine, and the third is a higher-level conceptual discussion of lag comp. in terms of client/server synchronization, by Valve Software.

Unlagged proposes a pretty simple addition to normal dead-reckoned non-delayed broadcasting, by using historical data to check for weapons hits. This method produces a result that is fair to sending clients, but may seem inexplicable to receiving clients. A client aims for his enemy, pulls the trigger, and hits, but from the victim’s perspective he may have dodged the shot. Clearly, this is a good first step but not the whole thing.

Valve’s documents were much more interesting. They proposed having the client-server simulation as usual - but have the client render a fixed timestep behind the server. That way lag compensation discrepancies can have time to blend and interpolate before being presented to the user, and that clients do more interpolation than extrapolation, which is always good for everyone.

Extrapolation involves predicting the movement of objects in the future. While this is generally accurate, if the player is moving erratically it can actually be quite far off. In the Source implementation the only thing that is extrapolated is the player’s own movements, which by all accounts is fairly accurate. All other movement, including other players, is interpolated between already-known data, hence why the entire engine renders 100 ms behind the actual simulation.

I put together a little diagram with a test scenario and ran it through my head. This works rather well:

Tuesday, March 18, 2008

My last blog kind of fell apart, mostly because my life really isn’t that interested, and the interesting parts aren’t really safe for public consumption ;) Here is my newest attempt to maintain some decent documentation of what I’m doing, and for a change I’m going to focus it more towards my game development and technology-related thoughts as opposed general life goings-on.

In this issue of the Amazing Spud Adventures…

Networking in Real-Time

This is a topic that’s been on my mind lately. What is the best way to network in a real-time environment? For pab (my, and a couple others’ pet project) multiplayer isn’t exactly a focus, but for completeness and versatility’s sake I’d like to include networking capability into pab’s engine, which has brought up a few interesting points.

Entity Replication

This is a pretty simple thing to do, and is more of a code reduction issue than it is a true networking issue. An effective game engine should not force game-level coders to craft their own replication packets, nor should it expect said coders to invoke entity replication manually. Such low-level shenanigans are better left to the engine itself, both as a way to reduce error and reduce code complexity at the gameplay level. I’ve been thinking about ways to best implement this, but it leads to the next issue.

Say a nearby player’s position is updated every 20ms to avoid flooding your connection with unecesarily frequent updates, what happens in the real-time environment between entity updates? Clearly the player cannot “snap” between server updates. The obvious solution here is to have the server update not only position, but also heading and velocity of mobile entities. This will allow the game to tween the movement of said entity between updates. In heavy (or inconsistent) lag environments, though, this breaks down pretty quickly. If the object is traveling along a curved path (most likely), a straight tweening method with heading and velocity simply will not do.

Alternatives including cubic spline fitting, to best predict the movement of the object in the short term, project its course based on historical data over the last 4-5 updates. This will suffice for the vast majority of movement types, but is also not perfect. What if, for some freak reason, the server update indicates a position that is completely off from client-side prediction? Logic will dictate that server updates take precedence and the object will error-correct and “snap” into the new position. But even the best lag prediction methods are far from perfect, and small discrepancies will occur between client side prediction and server update. In this case do we still snap? Or do we attempt some sort of blended tweening to get the entity into the right position without such a noticeable and glaring motion?