Friday, July 20, 2007

Networking

I've started to look into the networking code for Dune. While I'm currently still in a phase of trying things out in a sandbox environment, I will work on the networking code from now on. Once that's in, I will add the other missing features in Dune.

I initially read a few articles on other (commercial) RTS games and how they did their networking. For instance, Age Of Empires used a Peer-to-peer setup to communicate with all the other players. The game was a perfect simulation on each client. They accomplished this by make the game 'turn-based'. The player input would be registered, packed up and send to all clients. Each action would be executed in a turn, and when the data was send out to all the other clients, it used current turn + 2. So, when the current turn was 1000, and the player wanted a villager to go and chop down a tree, the actual ordering would happen in turn 1002. Since turns only lasted 200ms each, the player wouldn't even notice the delay between clicking and seeing the action.

However, in such systems, it's problematic when lag is 500ms: A packet send with orders scheduled for turn 1002 would arrive during turn 1003. AOE would adopt to this by either halt the game(In severe cases), or stretch up the time needed for each turn. In the case of 500ms lag, it would increase the turn time to 250 or 275ms, giving each packet more time to arrive.

This seemed to work well(I tried AOE2 to test it out) and it ran like a charm. So, I wanted to implement a similar to that of AOE2. However, setting up a P2P network between clients is a pain in the ass. Esp. when you take NAT into consideration. The system would have to work like this:
- Each client connects to host
- On start game, the host opens a series of new ports, one for each client.
- Each client connects to this port and disconnects directly
For each client:
- The host sends all other clients to which other client they should connect by handing out the IP and port number.
- The clients connect to the other player since the NAT port is now opened up

- Host is done when all players are connected to eachother.

It's quite complex, and I'm not sure if it would even work. Perhaps I should give it another shot and try to set it up. Once it works, it should work like a charm.

Saturday, July 14, 2007

Bugtracker update #2

It's been a while since I updated... I've been really busy. Since the summer vacation begun, I found myself a summer job. Right now I'm a system administrator at a large company. My job is to check out how Windows Vista will fit in the existing environment and how the group policies behave in them, since Vista doesn't eat the older formats. I also have to take over the responsibilities of the other system administrator when he's off on vacation.

I just continued with experimenting with bug trackers. I tried to install Trac, and failed. The reason: It seems it can create an sqlite database, but no matter where I try to create it, it just fails. If I create it in the root of the C drive, it fails with the error Access Denied, and if I use an existing directory, it screams that I can't create a new directory(Well duh!). So I gave up.

One of the biggest downsides of Trac is that it requires quite a lot of external dependencies. In order to run, you either need a running Apache configuration with CGI / FastCGI / mod_python installed. You need sqlite(Since MySQL is very experimental. And to be honest, I don't like to run experimental stuff on my development environment).

So: Bugzilla is left. I've decided not to install / try any paid trackers, since those are outside my budget anyway.

One a sidenote: I did have some more time with Mantis this week. Even tho it lacks SVN integration, it's still a pretty nice system. I like it, and if Bugzilla doesn't behave better, I'll go with Mantis and setup a SVN integration system. I can't remember the name right now, but it's capable of glueing Mantis / Bugzilla to SVN.

Tuesday, July 10, 2007

Bugtracker update #1

I haven't done a whole lot of research on bugtrackers in the past days, but that's because I've been doing some other things aswell(Like snowboarding the entire day. Yes, in the middle of the summer.). However, I can do some reporting on things I've done.

First of all, I installed Mantis. Since I already had an instance of Apache running, I could just install PHP for it, install MySQL and voila, done. After that I added a few bugs to the system to see how it works and looks.

A few downsides of Mantis:
  • Documentation on the site is lacking
  • The My View is kinda cluttered
  • Not possible to assign a bug directly to a developer while reporting it(Actually, you can, but you need an advanced report for that)

But, it also has a few nice features:

  • Easy to install(Just open the index page)
  • Detailed report information
  • Multiple projects in 1 database
  • Projects can be made (in)visible to certain users, users can have roles in projects

So far, I like Mantis. But, I still have to look into a glue system to glue it into SVN(Which is out there), since it's pretty nice to be able to link repos updates directly to bugs.

I also made a start with installing Trac, but that requires quite some more work...

Saturday, July 07, 2007

Counting the credits

I implemented the credits counter today. It's a simple little UI component that I managed to whip up in about 1.5 hours, including sexy 'animation'. After setting the credits, it compares the amount with the visible credits. In then calculates the difference between the 2 and divides that by 2(seconds). During each frame update, it multiplies the pre-calculated value with the deltatime and voila, you get to see an update animation.

It's not exactly like the original, that seemed to rotate around, but that's too much work to implement for now.

The credits counter in the top right

I'm also looking into using a bugtracker. Right now I'm using the SVN commit logs to document bugs, but that's not the most efficient way. So using a bugtracker might help with bugs that I intend to fix on a later date. As for now, I keep forgetting to document all the bugs, remember them AFTER the commit and write them down. And then lose the note with the bugs.

So, I'm looking at Mantis and a few others, and I'll make my decision soon(probably tomorrow). After I fixed my server... Yes, fixed... I decided to remove a bunch of server roles which I installed for testing purposes. However, after I removed the Terminal Server role it had to reboot. After the reboot I could no longer login remotely, so I'm trying to fix that now.

Thursday, July 05, 2007

Carry-alls and harvesters... An excellent combination

Today I added in all the goodness for carry-alls to pickup harvesters and deliver them into the refinery. It was quite some work to get that working, since I had to code in a few extra special cases(is this a harvester, does it have clearance for the refinery, is the landing area actually the refinery, etc.). But, now harvesters DO get picked up by a carry-all, if around, and they'll fly em into the refinery. And flying is SO much faster than driving :).

Carry-all just picked up harvester enroute to spice field.

Also, a newly built refinery now will receive a free harvester, which is dropped off in style by a carry-all, which will depart immediatly after dropping off the harvester. After the carry-all leaves the onscreen boundaries, it will delete itself.

Fully loaded harvester being returned to refinery

The carry-all which delivers the reinforcements into the field is a little special carry-all, namely a ReinforcementCarryall. I wrote a special class for it, since I didn't want to implement the code for leaving the field in the regular carry-all. That would really pollute the code. Also, this new Carry-all makes it possible to have regular reinforcement drops too, which is pretty sweet. Including stuffing 20 units into it.

But, there's a little issue with the carry-alls right now: When a tile is used, it won't be able to drop off it's payload, and just keeps hanging there, until the tile becomes free. So, that's what I'm going to solve next: find a free tile and unload there.

I already wrote a similar thing for the harvester to find spice tiles, so I'm considering to make it a general helper class and use a generic Comparable kind of thing. It's code that won't be called too often so speed isn't a really big issue here. And added goodness is that I can 'smear' out the search over multiple frames. In the case of finding a spice field which needs 200 steps to be found, it will cause severe lag. Being able to do this is say, 40 frames, it will only be 5 steps per frame, and therefor no big deal.

After this works, I'm going to fix a little bug with the selection rendering, constructing and then finally implement the credit counter control.

Monday, July 02, 2007

Spice must flow!

And flow it will! I spent the weekend implementing harvesters and refineries. Right now, a harvester is capable to driving to a spice field, happily seperate the spice from the sand, find a refinery, drive back and enter the refinery. Once in, the refinery will empty the harvester, provide credits to the player and when the harvester is empty, it will deploy it.

Our initial state: Idle harvester and refinery

Most of the harvesting code is still the same as it was before, but I also changed quite a lot. Most of the changes are in the refinery, which now has a 'landing zone', the area where the harvester has to land in order for the spice to flow. Initially it used the building coordinates to find it's way into the refinery, but this meant the harvester would drive to the center of the building. Also, I updated the images concering the harvester and the animation, so they use up less VRAM(Altho it came with a dirty hack: I have to figure out in which directions to displace the animation, otherwise it looks dislocated)

The harvester is collecting spice

When a harvester is full, it will request a list of all known refineries. It will traverse this list and attempt to find the most suitable refinery. That is, with the shortest queue or no queue at all. When it comes by an idle refinery, it will stop searching. When it has found a refinery, it will inform the refinery that it's enroute, lay out a path and start it's dangerous journey back home(Esp. when no carry-alls are around). The refinery will now start 'blinking' it's landing zone(when idle), or otherwise just queue up the harvester.

Harvester returning to the refinery, which has a blinking landing pad

When the harvester has reached the refinery, it will wait for clearance. The clearance means the refinery is ready to receive the harvester and refine whatever goodness it brings. When the harvester receives it's clearance, it will roll onto the landing zone and remove itself from the scene. This is important, because it will otherwise keep rendering itself, which will look weird: A harvester ontop of a refinery with a harvester in it. The refinery stores the harvester internally, so when the refinery is destroyed, it will automatically destroy the harvester aswell.

Refinery processing a harvester

It takes 35 seconds for a fully loaded harvester to unload(20 credits per second). When done, a harvester will ALWAYS be deployed, even when a carry-all is signaled to pick it up. This is done because it might take a while before the carry-all arrives, and when deployed, it gives other harvesters the chance to enter the refinery. This was something that annoyed me in the original game: When a harvester was waiting for a carry-all to arrive, it took a while, so other harvesters had to wait, while I was already low on cash.

To do:
- Have harvesters return back to the spice field
- Limit the number of tiles searched for new spice
- Harvester spice dunes first, then normal spice
- Fix bug related to tiles not being free'd
- Have a carry-all unload the harvester into the refinery
- Have carry-alls bring a harvester to a newly placed refinery