Sunday, March 29, 2009

Dune II allowed as college project!

After much deliberation at my college, I managed to get it accepted as a project that will provide me with some grades that I need. There are 336 hours scheduled for Dune(Which comes down to 42 full days, or 1.5 month of work fulltime).

This should give me plenty of time to actually get anything done on the project. However, after reviewing the old code and an attempt to get it to compile again under Visual Studio 2008 on Windows 7, I have decided that certain parts of the game are utterly useless. Managed DirectX support appears to be dropped by Microsoft, and is replaced with XNA.

Because of this, and the insane difficulty I had with integrating a network component into the game, I've decided that I'm going to partially re-write Dune. I will completely replace the rendering layer with XNA, and I will start bottom up this time. Instead of working on the game logic at first, I will start out with the networking engine, and build a game on top of that. This allows me to focus on writing a solid network component first, and then slowly integrate parts from the game into the simulation.

However, since I spoke of a partial re-write, you might wonder what I will re-use. Well, I will re-use all the logic components I've written till so far. I will still use many of the components from the original engine(Such as the manager for gamestates, tasks) and try to port as many things over to XNA. One of the first things on the list is the Window Manager because I'm going to need it on short term.

I started testing out some code on networking and NAT punchthrough last monday using the latest Lidgren Network Library, and I must say, it's great! I wrote a little test application that creates a P2P network with 1 host and 2 clients, and I was able to generate a solid, working p2p network. They all saw each other, and it could connect over a home router and a corporate firewall(Microsoft ISA). The codebase I know have, is derived from that, and has a working lobby that recognizes new players, sends game settings around and at the moment, I'm working on setting up an actual simulation, that will start out by running a few rounds, and the host sending 1 to 2 orders around to all clients, have the clients execute these and then have them send the results back.

I'll report back later. I hope to have some screenshots by then too.

Friday, June 06, 2008

Synchronisation bug in the server...

Well well, what a surprise! More updates on Dune :).

I've coded a bit on Dune in the past few days. Not an awful lot, because I had other things aswell, but I managed to code up a few bits on the train while traveling to/from college.

Units are moving again

Yes, first thing I did was re-enable the controls to move units and scroll around the map. Sure, they don't actually send stuff over the network, but units are moving, and I found a few bugs in there related to the MCV(ie, MCV can attack, but isn't supposed to). I intend to fix this first, before actually buffering the calls to order units around.

I also need to build the turn-system for the packets. I guess I should buffer up the commands first, and then actually start working on the system that collects the packets from other sources and hands down the orders to the correct player.

DebugConsole is now a real UI object

I updated the DebugConsole, because it didn't quite behave like I wanted it to behave. It was the first 'UI' control I built, and wasn't based on the later written UI system. In other words, it was a dirty hack that rendered itself to a texture and constantly drew the texture when needed. Obviously, that was faster than the current approach, but made it more difficult to make the console support features like real UI objects, such as resizes and adding of sub-controls.

I think the next iteration of the console replaces the current code with a Textfield / Textbox in which I draw the text, and a 2nd textfield / textbox to type in. That would make it much easier to add in support for scrollbars, and other various snazzy features. But, that doesn't have an awful lot of priority at the moment.

Synchronisation bug!

And of course the bug I mentioned in the title. I have a really weird bug in the Server code related to loading. It's a few days old, and I've been trying several times to patch this up, but it didn't quite work.

The problem is as follows: When I enter the NetworkPlayState, this will create a new state called NetworkLoadingState which is responsible for loading all assets and synchronising all the clients with each other so that each game starts around the same time. However, when the server is behind on loading than the client(On my machine that is. The game having the focus will load slightly faster than the background window), it will be done loading by the time all the clients are done loading too. It will see that everyone is done, and trigger the OnStartGame event, which in that case, will report that the server hasn't completed loading yet. This will mean the client will push a new NetworkLoadingState onto the stack and voila, the game will start throwing exceptions.

I have no idea yet on how I'm going to solve this. I'm considering the just ditch the current asynch approach, get rid of the events of the events and start using blocking functions instead, to make sure things will run in proper order. Alternatively, I might just build in a 1 second delay on the server side to prevent this from happening, but that would be a dirty hack I rather avoid. First step is to figure out where it actually goes wrong, and then find a way to solve the issue neatly, without fudging up my code too much.

Monday, June 02, 2008

Unexpected progress!

Some people probably gave up on me(or Dune or both), but don't worry, I haven't given up yet. It's just that I've been way too busy with other things in my life(Which got twisted upside. But I didn't move in with my auntie and uncle in Bel Air).

Last friday, I had my laptop with me and I was like, what if I open up Dune and start coding for a bit again? And so it happened. I coded, and debugged the code I had written, and debugged more, and yelled at my laptop. I really had to look back at older code to see how far I was, and how I solved certain issues. And to be honest, I solved quite a lot of things in a clever way.

Last weekend, I managed to finish up the lobby / loading / synchronizing part. It now successfully manages to synchronize all the data between the lobby/clients, and then starts the game, including units. Each player gets an auto-assigned starting location when they connect(At the moment, since I haven't added in start points to the maps yet). After the game is done loading, it shows everything like a regular single-player game, except the controls are currently disabled.
Lobby-server awaiting another player to join. Player numbers are currently fixed.

Minor bug with the sidebar during loading. Still need to fix that, but it's not too important at the moment.

And we're live! This shows up on both sides.

Next step is to re-enable the player controls. But instead of immediatly executing all the actions, I need to buffer them, send them to the server and have the server distribute this to all clients again. I already isolated the calls which I need to buffer, so I only need to build the mechanism to actually buffer them, broadcast them around and execute them when needed. Still need to figure out how I'm going to do that.

Wednesday, January 02, 2008

Happy new year! (And progress updates)

Happy new year! May 2008 be a good year!

As in updates: I've managed to complete the loading of all assets and the game actually ends up being started. So, the next step is to place some units on the map and start building the turn system.

I'm not entirely sure on how I'm going to implement the turn-system yet. I intended to send a StartTurn to all clients, which then starts each turn. But, as lag increases, the game would hang for a short period of time with this system(Perhaps not even noticeable). So I could send them out sooner, but that would mean I could miss packets with commands in them. Not sending StartTurn packets is even worse, as the game would continue to run(And go out of synch) when the connection is temporarily congested. Not a good thing either.

I think I need to experiment with this a bit, and when I have a good working alpha test release, do some real testing with 2 or 3 people to see how it works out.

Monday, December 17, 2007

I hate coursework...

There's a small delay in finishing up all the Game handshaking and getting the initial scene up. I'm currently occupied with a load of coursework which I have to finish because I screwed over a bunch of courses last year and the year before.

Really stupid, but if I want to start my graduation by the end of the college year, I better get all these courses patched up. And because of that, I have less time to work on Dune.

But, I found out I also have to re-do Network Programming(Why I failed that course is still a complete mystery to me), so I'm going to attempt to convince the professor to allow me to submit the network code of Dune. Mainly because it's more cooler than writing lame ass chat server(Using UDP and RMI), but also because it gives him a really cool example to show during classes.

So, I need to finish 1 more assignment for data structures / algorithms(Write an AVL Tree), and then I can submit all the code. One down so to say.

Wednesday, December 12, 2007

I need to re-think my class structure a bit...

I was reviewing my network code in the train on my way home today, and I came to the conclusion that I should think it over a little bit before I start expanding the code.

At the moment, on both the hosting and the connecting side, I have either a Server or Client as Task. The task is placed into the TaskManager and therefor updated each frame. Both the Server and the Client implement various properties via an interface(INetworkConnection). This is the connection status, connected players, etc. This is fine.

However, I also need to receive information back FROM the Task, such as when a new client connects, or when the user interface needs to update information. For this, the INetworkConnection is insufficient, because I need various events which come either from the lobby or the game. Such as PlayerConnect, PlayerForfeit, etc. It's a really bad idea to go from lobby -> Server/Client -> LobbyState. Messages would be re-routed via the INetworkConnection, which would slow things down AND clutter the INetworkConnection interface with too much useless crap.

I intend to counter this by creating ILobby and IGame interfaces, which the LobbyServer/LobbyClient and GameServer/GameClient would implement. These interfaces could then contain the function specific things for the lobby/game(such as a joining player for the lobby, and a forfeiting player for the game).

Using this system would probably be more efficient in terms of code maintenance than cramming it all into 1 gigantic interface. It would also prevent the Server/Client task from having to add GameStates, which keeps the seperation of UI / Logic intact.

I should have some in-screen screenshots soon, altho I probably need at least till sunday to buffer up all the player interaction with the game and send these commands over the network to the server. I need to change quite some code in the PlayerInput.cs file(Which basically contains all the code related to interaction from player to game).

Friday, December 07, 2007

Background loading of assets

Before I wanted to start out with the actual networking part, I wanted a way to load the assets from disk in the background, and before the game was actually running. This to prevent slowdowns in the network simulation when a new building/unit was constructed and the asset had to be loaded from disk.

In order to do this, I wanted a nice front-end(A progressbar to display the loading progress) and a back-end: A background thread which did the loading and put each asset into the TextureManager.

I started out with the ProgressBar, as the asset pre-loader was half done. It just needed to be modified to be able to work in a thread.

The progressbar is just another Control for my game. It basically draws it's outline, and based on a Value it shows a nice (blue) bar. I initially had a problem with the outlines not showing up. But, this is related to the way how D3DSprite and D3DXLine render. I solved the issue by doing a Sprite.End() RenderLine Sprite.Begin(), but that cuts down on performance, so I need a better way. I reported it as a 'tweak' in mantis, so I don't forget about it.

Loading, please wait...

The background asset loader was also heavily modified. I initially wanted to try and run it while performing my normal gamestate functionality, but I found out it's way too slow for that. The change was that when I constructed the Preloader, it would parse the list of assets to load and store these, and then with a call to LoadNext() it would take the next asset from the list and load it. So, I shoved that into my BackgroundLoader class, and all was done. The BackgroundLoader is a thread that keeps running until all loading is done, and once it loads the next asset, it will increase a counter, so I can poll how many assets are done and then update the progress bar.

However, I was quite shocked when I tested out the background loading process. It's slow as hell! It took 94 seconds in debug build and 87 seconds in release build to load all 58 assets in just 2 colors. Image how long it'll take when you're playing with 6 friends...

Slowpoke is slow :(

So yea, background loading is in, except it's terribly slow. In fact, it's so slow, it's unusable to develop the network play with, because having to wait ~1.5 minute before being able to test something out is too much for me.

For the coming tests(The actual network gameplay), I'll be testing with a reduced preload set, just a handfull of units / buildings.