Wednesday, May 30, 2012

Working!

It's by no means perfect, but it's mostly working, with a few glitches!

Glitches:
Thrust doesn't display fully FIXED
Win-lock (game won't return for another round) FIXED
Double-Killing? two lives decrement at a time FIXED
Client-side fences animate strangely FIXED

Other than that, the game is fully networked!  Awesome!  A few easy (well, should be, knock-on-wood) bugs to get through and the game is set!  I'm really excited, and I can't wait to apply what I've learned here to actual games (or games that I create, rather)

I learned a few things:

Client/Server can be a bitch.  You have to be careful with what you send to whom and how they apply the changes.  I guess my first approach was very p2p, but I ended up switching halfway through to the more "common" client/server approach, which means all processing (essentially) is done on the server minus input which is applied on the client side.  Relevant or important events are triggered on the server and sent to the client.

However I had my queues set up to run exactly the same, which resulted in some strange errors and doubled or  echoed creation going on.  If I could go back and do it again (unlikely with my workload) I would separate the server queue implementation from the client queue implementation.  That would have saved me a great deal of trouble.

P2P management can be very hap-hazard, ownership has to belong to specific machines and that needs to be explicit, else all you really have is a bunch of very similar simulations running simultaneously, which is fine until your images and game states start looking different.  You'd need either every piece to be owned by a specific machine and have a quick-n-dirty abstraction method to make quick work of such a structure, or some way to keep ID numbers synced between multiple machines doing their own creation/deletion locally that needs to be broadcasted to multiple machines.  This is why I switched from an organic P2P to a Client/Server model.

And now back to those bug fixes.

EDIT:

W00t! All bugs fixed! Now, if I have time, to fix prediction!  The way I did my code was to send data only when absolutely necessary (only when input has been read or collisions have triggered, etc) which is awesome, but also not so much.  It means the games run "apart" until an event is triggered and something is sent, which results in slight rubber-banding I would like to be taken care of with prediction (a loose model, basically targeting or lerping to desired values)

Kickass.

Thursday, May 24, 2012

Rage

Not the game, the real and burning feeling inside the pit of my stomach at the moment.

I have a somewhat sloppy yet functioning lobby, and the game is set to be networked and tested, just in time for me to figure out that I have no access to a second computer.  I cannot run my final project, I can't test it, all I can do is sit and stare at all of my hard work sitting in a lobby, waiting for someone else to connect who never, ever, will.

Every computer I've tried at the CDM requires an update to windows live, and I can't update them because I don't have administrative access. All of the school computers are "locked" from downloading programs and receiving updates.  Which is the only way windows live will let me onto windows live.  So I am stuck in the muck and mire of red tape and bullshit.

What a way to end the week.

Currently looking into every option I can, but I don't know where any of it will go.  Most of my friends use Macs, those who run PC's are either gone at the moment or require heavy use of their own PC's and I can't monopolize on their machines to do my testing.

Just wonderful.

Mo' Work No Time

I've now moved beyond the queue-driven part of the assignment.  I just recently was able to achieve a second account on the XNA creators club with which to actually test my game, so for the majority of the past few weeks, all of my networking has been purely theoretical.  Which is quite worrisome for me, but with any luck I can plug it into a separate computer tomorrow and the universe will not implode and my laptop will not set on fire.  If I'm really, really lucky, maybe then the game would even run.  But that's stretching things a bit.

Theoretically speaking, I even have prediction in my current "networked" game.  If a remote player receives a ship update, it's local copy will have a "desired state" that gets updated, and then the physical state interpolates (A very, very simple version of Dead Reckoning, I recon. [See what I did there?])
It's not quite so simple, though. Extra prediction is added in, when packets come across and set new states or create new objects (at least I think I have this for new objects? Making  a mental note to go back and check that) it takes the estimated trip time (which XNA so nicely provides) and moves the given state forward based on the trip time so that the received state is as close to the state back on the original sending machine as possible.  Then both the desired state (with the last given input) and the actual physical state are updated side-by-side while the psychical state continues to interpolate to the desired state (in terms of position, velocity, acceleration, rotation, rotational velocity, the whole shebang)

So, at the very least if I turn in a pile of steaming waste at the end of the quarter, at least I had my prediction model running, and I guess that's worth something?

I also almost forgot (since I'm not actually networked yet, you see...) about object creation/destruction, which I have now somewhat-sloppily yet successfully packaged into the game.  I'm very uneasy about how it works only because it seems a bit to hard-coded for my liking, I would appreciate a more flexible and abstracted system, but given my time constraints and my still-growing familiarity of OmegaRaceX I just first need something to work before I can then go back and make everything all nice and fancy looking.

I just have to also split time between this project and creating a particle Shader for Real Time Graphics.  I found some source code that should be able to help me with the setup of that project, at least, but this next week is going to be killer... hopefully not literally.

Anything else I've added? Well, not that I can think of at the moment.  I'll finish up the lobby tomorrow and plug this sucker in and see if it works.

Fingers crossed, right?

-Kevin

Wednesday, May 16, 2012

Switchin' and swizzlin'

I still haven't sent anything across a network, yet.  At least not for OmegaRaceX.  And I probably won't get a chance to do so for some time yet.  That's the problem everyone having Macs.  Even my roommates have them, and I can't find anyone to test with/against.  I did, however, re-vamp the Data-Driven queue to be "state-based"

It ignores commands of a lesser sequence number (meaning I can "spam" messages in case any are lost without major concern) and it sends state information (position, velocity, rotation, etc) instead of event based information (such as input info) which hopefully will help and enable very quick networking.  There are still a great deal of issues to solve, but there's no real one way to go about doing so.  There's hardly a "way" at all, it seems like "whatever works" is the way to go for networking.  Or rather, whatever works best, I should say.

I'm leaving for home this weekend, hopefully I can drum up somebody running windows back there to begin the testing.  I'll have more updates by this weekend, somehow, regardless.

I'm thinking about adding in extra information for prediction.  At this point, though, everything is funneled through one data type, at least, which is convenient!

Saturday, May 5, 2012

Updatez

So collisions wasn't too much a hassle to resolve.  My solution is by no means elegant or hyper-efficient and it will have it's bumps in the future to come, but I ran across some weird sections of code.

For collisions, the previous programmer copied the entire list of objects into a separate array of SceneObjects and then used a foreach() to loop through the scene objects and checked against each object.

The copy couldn't have incurred too much overhead, since each SceneObject in the list was a reference to the SceneObject in memory, but the double-checking is a strange way to go about doing your collision checking.  The game is small, so that could be a justification for a redundant collision check, but when I started queuing my collisions it would double-trigger collisions and cause really terrible behavior in the game.  It was a simple fix,
(a double-for loop
for(int i = 0; i < sceneObjects.Count -1 ; i++)
{
for(int j = i+1; j < sceneObjects.Count; j++)
{
//stuff goes here }
} )

so I guess it must have been a simple oversight, unless there's some tidbit of information I'm missing.

But I'm going to go ahead and say that was just bad collision code practice and leave it at that.  Now the game is "data-driven" with the exception of win/lose screens, I believe.  All input, creations and collisions are funneled first through the InputQueue, and are processed at the end of every loop.

My unhappy moment of the day was in the collision code I changed the scene objects to be somewhat based off of unique game IDs. Which is fine for the most part, until you have to loop through your entire list to find an object of a specific ID.  (Actually, make that twice, to find the first colliding object, and then the second)

This was done because once I start having to send information between hosts/end machines I won't be able to send references, the two games will have to have some common denominators (ID numbers)
But even keeping those ID numbers synced is going to be a fun challenge in of itself.

This Saturday sucks.

The Beginning of the end (Data Driven Omega Race X)

So far today has been a smashing success.

And I mean that with the utmost sarcasm.  The task before me (Make this game multiplayer) is significantly more daunting than I first imagined.  This morning despite sickness and an overall unwillingness to do anything, anywhere, ever (it's been one of those days) I managed to at least convert the game to it's "data-driven" state.  I'm not QUITE all the way there, however, seeing as how I've only gotten player input to be "data-driven."

Up next is managing lasers, bombs and walls to all become data driven as well.  It's not so much difficult as it is tricky.  Knowing what to put where is half the battle.  Coding everything to interact cleanly is the other half.  And that's when you have to start sending things across the interewebs.  It's going to be a very long quarter, especially if I don't get any better and kick this sickness and funk.

I didn't do a whole lot in terms of making the game data-driven.  Created some specialized structs and classes and an generic input queue handler, and then hijack the player's "GetPlayer1/2Input()" functions to direct all of their input to the queue instead of the players themselves.

Now I will do the same for "fireLaser()" and "layMine" and finally in there somewhere I'll hijack the collision systems after I learn how those work so that everything in the game (minus main menu stuff, I'll worry about the lobby later) is funneled first through the queue.  There's a lot of work ahead of me yet.

I must say, I've been complaining about plug-n-play coding at DePaul for some time now, but now that I finally get a taste of some real coding challenge, I'm almost feel too lost to start.  Not much in the way of guidelines or instructions, just "go 'fer it"

Hey, at least this time around I'll be actually learning something.

-Kevin