Sunday, July 27, 2008

Ship designs and order queues

After chatting with mithro this week, I found that the ship designer in the pywx client was an old part of the code (untouched in a year), and that ship design was not considered a priority (since only MTSec supports it). What I did instead was a viewer for ship designs in the game:

The design list on the left is colour coded by player, and the information pane is currently showing etower333's scout design. Wasn't that guy in a previous post as well? How long has that game been going on anyway?

Order queue management has also been added.

After selecting an order from the queue, you can use the delete button to remove it or the edit button which will bring up the arguments window to edit the existing values. The new button also serves to create a new order after selecting from the available orders list on it's left. This change led me to venture back into the rather untidy order handling code, which I have cleaned up a little.

A minor change is that double-clicking on an object will focus and zoom in on it.

One thing I have been looking into is introducing sound and battle scenes into the client.

Battle scenes in thousand parsec are defined by a BattleXML file, which is a file format detailing how many sides there are in a battle and the makeup of the individual fleets together with a turn-by-turn breakdown of how the battle went. A sample pygame viewer as well as documentation on the format can be gained from the battleviewer git repository, although I have not run the viewer yet. One problem with BattleXML is that currently it is only supported by tpserver-py and not tpserver-cpp, which is the more popular server. Another issue is that it has to be implemented by the ruleset specifically and requires a media definition file to map 3d models to ingame objects as well as any weapon effects. Perhaps there could be a random battle generator so that support can be easily added for all rulesets?

Sound support is already available in Python-Ogre via OpenAL, a cross-platform api for 3d sound. So it's really a matter of finding the right sound effects. I've found a program called song04 which generates ambient soundscapes, it sounds quite alright and I'll be trying it out as a background soundtrack next week.

In somewhat related news, my old computer is probably on it's last legs as it frequently hangs upon startup (or the kernel starts to panic), and it has no internet access as the network adapter refuses to connect despite using the same settings which worked before. I guess it's rather fortunate that I got a new PC recently.

Sunday, July 20, 2008

This week in TP

This week, I finally figured out how to do proper camera rotation in 3d. The actual code turned out to be simple. At first, I wanted to use spherical coordinates to position the camera, as I had success with using polar coordinates for the radial menus. By storing the vertical and horizontal angles and treating radius as the zoom distance, I could convert them into 3d coordinates by applying some formulas. This worked only for rotations along the Z-axis (meaning that the world was "rolling", done by moving the mouse left and right). However, for rotations along the X-axis (pitch) it would refuse to rotate properly - upon reaching the horizon angle it would "bounce" back again.

In the end, I put the camera inside an OGRE scene node, and made it the child of another scene node which would act as the focus. Hopefully this tilted diagram isn't too confusing:

In the diagram, you can see the camera floating at a distance above the map, which contains several planets. The focus node is always level with the other map objects, while the camera node can zoom back and forth. As I mentioned, the camera node is a child of the focus node and by rotating the focus node directly, OGRE will apply any transformations to it's child nodes, causing the camera to rotate around the focus node.

Allowing the camera to look around freely posed a problem, mainly with the starry background as it was a flat field of stars. Here's a picture breaking the illusion:

Thankfully this was actually quite easy to fix. OGRE uses particle emitters, which spew out particles in various arrangements, and there was a Hollow Ellipsoid emitter which I could use to create a starfield surrounding the camera. The manual is not very clear on how to use the Hollow Ellipsoid, the inner_ parameters are actually numbers with a range from 0.0 to 1.0 specifying the percentage of inner volume which should be hollow.

There always seems to be a cluster of stars at roughly around the same location, I'm not sure why. Letting the camera roam also let a few more issues crop up, such as the planet rotation. Previously, they were facing the player who was looking from overhead, since otherwise all the player could see would be their polar caps so I had to rotate them back again. Another stickier problem is the panning of the camera. Since the camera can pan in any direction, it screws up the zoom if the player pans downwards or upwards.

Finally, the messages window layout has been changed to include a panel showing all the message headers. As I said in the previous post, the layout looks like it could do with some tweaking.
Next week, I will implement the ship design window, although I've not been able to create ship designs using the existing client yet, I should take a look at at least letting the player view the ship designs, or else he won't know how badass his fleets are. :)

Another thing will be the order queue management, which refers to deleting and editing existing orders.

There will be a turn update window, showing new events received upon a new turn.

Finally, I will create setup packages for Windows, Linux (with the help of fellow Thousand Parsec developers) and Mac (which I will be working with my mentor for - this may take longer due to issues with Python Ogre). Although not a real release yet, getting the build process done will be a load off my mind. No use working on a project if nobody can run it after all. :)

Interface comparison

This post is mostly a screenshot comparison of the two different interfaces of the original wxWidgets client (tpclient-pywx) and the OGRE client (tpclient-pyogre). Okay, maybe they are not so different... but it would be interesting to see the layouts in different environments anyway.

First off, we have the bread and butter of any 4x strategy game... the map. The pywx client shows each system and which objects are in that system, indicated by the circle surrounding it.

The pyogre client has two views: an "iconised" view when the player is zoomed out, and a 3d view when viewing objects close up.

The pywx client keeps new order parameters and the order queue within the same area:

In the pyogre client, new orders are chosen from a radial menu, which produces the new order window.
There is also a separate order queue window for manipulating the orders of the selected object (not yet, sorry :()

The pywx system viewer shows the tree of all objects in the game.

The pyogre system viewer needs some work, once the client fully makes the move to CEGUI 0.6 I'll be able to include the new tree widget in.

Information window, showing some attributes of the currently selected object. I've always thought it looked a bit like debugging output. :)

The information window for pyogre shows similar details.

The message window for pywx, which supports html and can open your browser if a message contains hyperlinks.

The message window for pyogre. It looks a bit 'chunky', maybe I should have an option to toggle the message list panel?

The design window. I have been working on this feature, but it is not complete yet as I can't seem to create new designs in MTSec, even with the pywx client.

Sunday, July 13, 2008

Animated camera

This week, added some animation to the camera movement to make it more smooth. When zooming in or out, it will move gradually instead of instant 'steps' like before. In addition, there will be animated panning when a system is double-clicked on the system list, or when pressing 'c' to center on the selected object, or when pressing "goto" in the message window. Since it will move in steps every frame, it is somewhat slow when the frame rate is low. This could be solved by having calculating the step size based on the frame rate. A harder problem is how to rotate a camera in a spherical manner around an object, which is probably a staple of most 3d games.

I also added some movement for the ships which will occur after a turn update. This allows you to roughly see where they are going, particularly for enemy fleets.

I guess this week's changes are mostly animation based, so it's a little hard to take screenshots.

Some additional minor fixes
Message window parses html messages now. This was largely thanks to Tim Ansell's suggestion to look at the htmllib and formatter library that comes with python, which saved me from having to strip out the tags manually. I still can't believe the breadth of python's built-in libraries sometimes. Batteries included indeed. One possible addition is to add additional formatting according to the html tags, right now I'm just stripping them out adding line breaks appropriately:

The keyboard shortcuts for zooming in and out (the plus and minus key next to the backspace) is fixed now. Previously, it was stuck in 'icon view' all the time.

Saturday, July 5, 2008

Some interface changes

This week, I have added some additional elements to the user interface in order to make it more user-friendly.

The first would be the turn counter in the top-left hand corner, which is handy for knowing how long the game has been progressing for someone who is joining in half-way, and for knowing the current 'phase' in rulesets like Reach for The Stars, where there are three phases and certain orders are possible depending on the phase. However, it does not actually show the phase - the user will currently have to calculate it on his own.

Another difference is the End of Turn timer in the bottom bar, showing how many seconds are left until the turn is over. The 'End' button next to it is used to tell the server that you are done with your current turn, although this step must usually be taken by the majority of players before the server actually finishes the turn.

Next, when the user hovers the mouse cursor over any object on the starmap, a popup will display with some information about that object such as their name and owner (if any). In addition for fleets, the composition of the fleet will be shown, while planets will display their resources and star systems will just show how many planets they contain. One thing I'm trying to figure out is how to dynamically resize the popup in accordance to the text contained, to prevent text overrun such as in this case:

etower333's home planet - In the minisec ruleset, the home planet of a player is defined by having "Home Planets" in their list of planetary resources.

Another change made is to tweak the icon view so that it colours the icons according to their owner:

This makes icon view a lot more useful, especially as I'm still working out how to show ownership of planets in 3d view without colouring the entire planet.

A common issue with network applications is having the server down, or providing incorrect credentials, so an error message will be displayed when this situation occurs.

I'll be looking out for more areas where I can put information or error messages, but I probably won't post about it again as it's quite minor in implementation (though important).

One suggestion was to have a way of selecting between objects that are clustered closely together when the view is zoomed out. In the wxwidgets client, clicking on a star system will cycle through all the objects in orbit around that system, so I have attempted to make something similar - when clicking multiple times on the same spot, the client will cycle through objects overlapping that area.

Issues encountered this week
A new version of python-ogre was recently released (1.2 RC2), and contains a huge amount of changes from RC1. After downloading the windows build, I found that it wraps versions of ogre that I had never even heard of! (1.7 in this case - the latest stable version is 1.4.9 and the next slated release is 1.6, codenamed Shoggoth. Talk about bleeding edge. :)) Needless to say, it brought a few interface-breaking changes with it and I was considering whether to port the project over or not. One desirable thing about RC2 is that it supports CEGUI 0.60 which comes with a brand new tree widget - something which I'm sure would be very useful. One course of action might be to compile a custom version of python-ogre with just the new stuff that I need - something quite easy to do on linux as I just have to change some version numbers in the build scripts. On the other hand, that would make it more difficult for people to just download the source and run it when they already have python-ogre installed. I think that for now, the client will continue to target the previous version of python-ogre (1.1 since 1.2 RC1 has disappeared) until I can wrap my head around all the new stuff that's just come in.

Things to come next week
I will be working on animating the camera view to make it smoother (for instance, zooming in and out should be gradual and not abrupt) while making it possible to rotate around an object.

Also, I want to revamp the messages window to implement the great suggestion of having a two-paned system, and to handle messages with html tags in them, although I'm not very sure how I'm going to do that at this point.

Thirdly, I want to squish all of the bugs I've found so far. :)