Darkcanuck/RRServer/Design

From Robowiki
< Darkcanuck‎ | RRServer
Revision as of 08:20, 5 October 2008 by Darkcanuck (talk | contribs) (battle results table change notes)
Jump to navigation Jump to search

Navigation: About | Updates | Ratings | Query API | Roadmap | Design | Develop | Known Issues


This is where I ramble about how the server is put together...

Data Tables

The whole system is backed by a MySQL database (version 5.x) with a handful of tables used for results storage, scoring and rankings.

bot_data

This table contains a list of all bots used in any of the rumbles, past or present. It's basically a lookup table so that all the others can simply store a bot ID value and the name and author information are stored here.

battle_results

This is the archive of all uploaded battle results. Whenever a client uploads a new battle result it gets stored here in practically the same format as it arrived (with the exception of the bot names being replaced by their unique IDs).

Actually, two records are stored per battle, one for each bot. I plan to cut this down to one in the future, but this shortcut saved me significant implementation time and less opportunity for bugs. Now only saves one record per battle!

I may also extract the user data (username, IP, client version) and save them separately similar to the 'bot_data' table to cut down on storage requirements. Similar to bot names, user data is now saved in a separate table. This saves considerable space and has the added bonus of making the battle results table have a fixed row length.

There is also a flag for each battle result, which is initially off and will be set later once this result has been scored.

game_pairings

I tried to think of ways around having this table, but couldn't find anything more elegant. It basically summarizes the battle results for each pairing in every game, including average score and number of wins (for PL scoring, coming soon).

Like the battle results table, there is a duplicate of each pairing (one for each bot) which will eventually be cut down to one. There is also an update flag but its currently unused since pairings are updated as soon as new results arrive.

participants

This table stores the participant list for each game, their current status (active/retired) and their latest scores. It's your one-stop-shop for rumble updates and is a very popular table indeed.

Bots get added here as soon as their first rumble result (in a particular game) has been received. But scores don't get updated until the periodic scoring process has completed, so there could be a lag between appearance and first scores.

properties

Storage for flags and values that may change (without requiring source file changes). For example, the scoring update interval and size, or the server maintenance flag.

Client Interaction

Everything on the server is done using PHP. I picked it because I know it well, it's designed for web applications and it's ubiquitous. No language flame wars please.

Downloading ratings files

When the client starts up, one of its first tasks is to get the current server rankings. A simple query on the 'participants' table serves up the rankings with minimal fuss.

Removing old participants

If the rankings contain bots that aren't on the participants list, the client will send a request to remove those participants. This is done by setting all battle results and pairings involving that bot to an 'R' status (retired), which excludes them from future queries. The same is done for the participants list.

Note that this means ratings won't change once a bot is removed. APS will eventually change, but only once each bot has a new pairing score update.

If a participant is reactivated, it will return to the rumble with all of its old scores intact. Other bots' APS will adjust to include it on the next scoring update.

Uploading battle results

When a client uploads a new battle result, it passes through a series of checks before it can be stored in the system. Two new records are inserted into the results table. As well, the pairing records (if they exist) are updated to include the new scores.

This process adds new entries to the 'bot_data', 'game_pairings' and 'participants' tables as needed. Also, if a retired bot's results are uploaded, that will cause the bot to be reactivated in the system (see above).

Displaying rankings

All of the display pages are fairly simple, getting their data from the 'participants' list and possibly the 'game_pairings' or 'battle_results' tables.

Scoring updates

This is the ugly routine because it contains all of the really slow queries. It will be initiated by any of the above if enough time has passed since the last update.

All "new" battle results (up to a maximum size, oldest first) will be read and grouped by bot. Then for each bot with new results, new rating scores will be calculated. New pairings results (ie. all pairings for that bot) will also be calculated. The new scores will then be saved to the participants list. Once all bots are done, the "new" battle results will be marked "rated".

One of the slowest queries is the pairing update which is why I put it here instead of during an upload. Obviously this is an area where I need to do some more work...

Areas for Improvement

Scoring updates

This is my biggest headache at the moment. The current scheme is a bit odd, and slow to catch up during a rebuild. But it does support rebuilding, which is nice.

Other options:

  1. Incremental updates: easiest to implement, just update the scores & ratings as new results are uploaded. Benefit of always being up to date. Downside is that it duplicates some queries (eg. the same bot may have other results recently uploaded so re-scoring the pairings will be multiple times in succession) and doesn't support in-sequence rebuilding.
  2. Incremental ratings + periodic pairings: combining the current method with the incremental one, ratings would be done incrementally and pairings (APS) would be done on a periodic basis. Best of both worlds? Rebuilding ratings would be done out-of-order though.