Article Image
read

EVE Online is a Massively Multiplayer Online Game based in a future where humanity has gone interstellar, cut off from Earth after passing through a collapsing wormhole. Most of the content in the game is player-driven, leaving room for massive groups and intricate communities.

Two of these communities - Warp to Me and The Valhalla Project - hold public fleets to destroy sets of randomly generated sites called "Incursions" that have very high in-game cash payouts. There are around thirty people in the fleet at any given time, which runs nearly 24/7. Approximately 5-6 pilots will be waiting to join the fleet at a time, so a waitlist webapp is used as a queue and as a way for leadership to filter out bad ship fittings before accepting them into the fleet.

The existing implementation was ancient and left a lot to be desired, so I decided to use some existing code I had written for real-time tracking of characters using POST polling (server sees client information, updates database, informs other clients of the update in real-time) to write a new one.

The System

I wanted to quickly protoype this app, and I needed a system where I could easily do realtime publish/subscribe style data synchronization, as well as live DOM updates. For this reason I picked Meteor as my core framework for this project. It supports effortless MongoDB style live data updates and synchronization, as well as reactive templating, out of the box. Plus, with a few pull requests of my own, I was able to make the parts of it I used completely compatible with the comparatively ancient EVE Online IGB.

As the javascript API did not provide any return values, all information comes through the clunky path of HTTP headers. This is typically used for standard archaic websites, where to refresh information, a page load would be required. In this case, I abuse the system by sending an empty HTTP request every 2 seconds including an additional header called hostHash, which corresponds to a server-supplied random string given to the IGB like a token, to associate the DDP websocket with incoming HTTP background updates.

{
   "host":"192.168.1.46:3000",
   "connection":"keep-alive",
   "user-agent":"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.27 Safari/532.0 EVE-IGB",
   "referer":"http://192.168.1.46:3000/",
   "eve_shipname":"He Dead :(",
   "eve_stationid":"60007417",
   "eve_solarsystemid":"30003387",
   "eve_constellationid":"20000494",
   "eve_shipid":"1016625940844",
   "eve_constellationname":"Ankard",
   "eve_corpname":"Swag Incorperated Industries",
   "eve_charid":"90720899",
   "eve_shiptypename":"Scimitar",
   "eve_shiptypeid":"11978",
   "eve_corpid":"98358686",
   "ident":"hLG84RqXy8MnweJC9",
   "eve_solarsystemname":"Jondik",
   "eve_regionname":"Metropolis",
   "eve_regionid":"10000042",
   "eve_trusted":"Yes",
   "eve_serverip":"87.237.38.200:26000",
   "eve_charname":"Morpheus Deathbrew",
   "eve_stationname":"Jondik VI - Joint Harvesting Mineral Reserve",
   "accept":"*/*",
   "accept-encoding":"gzip,deflate",
   "accept-language":"en-us,en",
   "accept-charset":"iso-8859-1,*,utf-8",
   "x-forwarded-for":"192.168.1.81",
   "x-forwarded-port":"3000",
   "x-forwarded-proto":"http"
}

Every time the HTTP request comes in, the server calculates differences between the current and previous character object, and records them accordingly in the database. Meteor then transmits the change to the clients over the websocket connection, if they have a relevant subscription to see the data.

{
   "_id":"90720899",
   "active":false,
   "allianceid":null,
   "alliancename":null,
   "corpid":98358686,
   "corpname":"Swag Incorperated Industries",
   "corproles":null,
   "fits":[
      {
         "dna":":11978:31366;1:1447;4:2281;1:2032;1:31378;1:2103;2:3608;4:12058;1:2488;8:29001;2:28999;4::",
         "shipid":11978,
         "fid":"xyC33pWJfjA6s5E4a",
         "primary":true
      }
   ],
   "hostid":"hLG84RqXy8MnweJC9",
   "lastActiveTime":1417379363392,
   "name":"Morpheus Deathbrew",
   "regionid":10000042,
   "regionname":"Metropolis",
   "roles":[
      "events",
      "admin",
      "command",
      "booster",
      "manager"
   ],
   "shipid":1016625940844,
   "shipname":"He Dead :(",
   "shiptype":"Scimitar",
   "shiptypeid":11978,
   "stationid":60007417,
   "stationname":"Jondik VI - Joint Harvesting Mineral Reserve",
   "system":"Jondik",
   "systemid":30003387,
   "waitlist":null
}

Thus, I could achieve realtime sync of IGB character data despite lack of an API for retreiving the information. It's a bit hacky - the server is telling the client what the client really ought to already know, but it's convenient in other ways I will detail later on.

The User Interface

The standard view of a pilot sitting in the waitlist is a fit list, and a summary of how many characters with each shiptype there are in the waitlist. I made the UI as simple as possible. The character name at the top right is the character using the app, the Fleet Commander (FC) is displayed prominantly on the left side, and every EVE related object (like the commander's name) is clickable.

There are no page reloads as all of the page changes are handled by changing a reactive session variable and rendering the correct template in the primary center space. There is no URL manipulation as this is very buggy and limited in the EVE IGB. I wrote my own routing system for this app, which allows me to specify the title of the page, the template to render, and any data subscriptions required when loading the partial.

The fit list is synchronized with the server and stored in the database, so future visits to the page will display the same fits as before. Joining the waitlist is a single click.

The fleet commander interface allows the commander to easily pick from online boosters (pilots who sit in space idle providing global bonuses to the entire fleet), managers (players who also have access to the command page to accept or decline members from the fleet) and to accept/decline fleet members.

The accept button automatically tells the EVE Online client to send a fleet invite to the character. The two decline buttons, decline without further action, and decline with an EVEMail, both have their own in-game actions as well.

If a member is set as the manager, they can view the fleet command interface (without the "close waitlist", "Set to X" controls).

The admin panel allows administrators to set the current incursion system, as well as force close the current waitlist. All of the characters are listed. Note that all of the data on this page and on every other page is realtime, meaning if one of these characters changes corporation, ship, or location it will be immediately reflected anywhere where it is mentioned no matter now minor. Clicking these links opens the in-game UI for the items.

The character profile UI is designed to allow administrators to quickly ban/unban characters and to see all relevant information about the character in the UI. All of this data is reactive as well, including the fits - when a character changes his fits in the UI, it updates in the admin and waitlist interfaces as well.

I wrote a roles system to simplify allocating roles to different users. An interesting thing here is that the visibility of some pages (and their tabs in the navbar) are reactively linked to roles on the character. If I add the "Fleet Commander" role to a character, the player will have the tab appear instantly. These are all artifacts of how Meteor works - if I place data somewhere, it's guerenteed to be up to date at all times.

Timeline displays real-time events as the character object is updated. This is just an easy way of keeping track of the internals of the system.

Conclusion

This project was a fun one for working with Meteor once again. Meteor has matured a lot recently and with the ability to remove core features and implement your own database driver, for example, I believe it could work with larger scale projects. For now, though, I would only use it for something small like this.

Thanks for reading!

Blog Logo

Christian Stewart


Published

comments powered by Disqus
Image

Christian Stewart

Also known as Quantum and Paralin.

Back to Overview