Alastair Callum Unity Developer

CREST API Regions & Solar Systems

Shoot for the moon!

Part of the goal for the EVE Online CREST API challenge was to visualse the chosen trade route. To do this I've made use of both the CREST API and Static Data Export (SDE) to populate a series of uGUI buttons for each region.

undefined

There's not a whole lot of reasons to use the CREST API to poll static data such as regions, but it shows that I know how to use it. The next task is to show the constellations - which are collections of solar systems.

This was a little harder to pin down on a usability level, as you cannot reasonably show all 8035 solar systems without hitting performance issues but what I came up with appears to work well. When a region is clicked, it will make a request to the CREST API for that region (giving us a list of constellation IDs), which is then used to poll all solar systems in each constellation. A random colour is added at each constellation iteration.

WWW _www = new WWW("https://public-crest.eveonline.com/regions/" + _regionID + "/");

while (!_www.isDone) {
    yield return null;
}
    
Region _region = new Region();
_region = JsonUtility.FromJson<Region>(_www.text);

undefined

So there we have it. Visualisation of New Eden in Unity, making use of the CREST API and Static Data Export. The zoom was handled by simply scaling the ScrollView's content transform with the scroll wheel value, and inverting the scale on all child objects.

_obj.transform.localScale = (Vector3.one / _zoomTarget.localScale.x);

Where the _zoomTarget is the transform scaled by the scroll wheel.

Links in this post

 -

EVE SSO Oauth

With an understanding of how to retrieve data from the public CREST API endpoints, I want to get down the autentication side of things before I get into the fun stuff.

Third party applications for EVE Online can now make use of the Single Sign On (SSO) userflow, allowing users to authenticate the application via the EVE login servers. This is great for web based applications but causes a bit of hassle for non-web applications. I'll try and explain, this is a succesful use case for a the third party web application:

  1. The user goes to a third party web application and clicks a "Sign in with EVE" button
  2. The user is directed to the EVE Login and logs in
  3. The user is shown what permissions the application requires and agrees
  4. The user is redirected back to the third party web application with an authorisation token in the URL
  5. The the third party web application grabs the token and exchanges it for an access token
  6. The the third party web application can now make authenticated requests on the users behalf

Now, most of these steps are similar for a non-web application except the nice bit at step 5. where the web application grabs the auth token discretely from the url. In order to get on with the challenge and not get bogged down in a nice solution for non-web, I've basically set up a php page that the SSO workflow uses as the redirect:

http://www.alastaircallum.com/w/eve-markettrader/auth.php?code=myExampleToken

This just grabs the authorisation token (the property following ?code= in the URL) with the following php:

<?php echo $_GET['code']; ?>

The authorisation code can now be copy and pasted by the user into the application, which will then exchange it for an access token. This is done with a simple HTTP POST like so:

_www = new WWW("https://login.eveonline.com/oauth/token", _data, _headers);

The _data member represents the authorisation token received by the user, and the _headers member contains a 64bit encrypted application ID and secret key to validate the request for an access token.

Links in this post

EVE Single Sign On - The EVE Sign In user flow used for third party applications

Stop calling them scripts

Or don't, I'm not a cop!

Ok, this is more a personal habit but a sensible one - hear me out. The most commonly referenced thing in unity is the idea of a Script, Unity even uses it in its context menus when creating new C# Scripts. This idea is a remnant from the days when programming in Unity was made to look approachable by non-technical game developers and frustratingly stuck around.

However it makes more sense to look at a Script as just a Class that extends MonoBehaviour. It might not seem like much but this distinction can help structure your games in Unity. Take a look at the hierarchy below, this is from Flocks Sake.

undefined

I use two distinct terms to organise my code, Behaviours and Classes, a folder called Scripts is nowhere to be found.

  • Behaviours - Classes that extend the Monobehaviour base class and execute the Monobehaviour methods
  • Classes - Standalone classes that might extend other classes but do not act as Monobehaviour instances in the game

This keeps all of your Monobehaviours away from Editor code, keeps game data classes away from your game controllers. So don't make that Scripts folder in your next Unity project and do it properly. It's always a great idea to have project hierarchy style just like you have a programming style.

Oh and on a final note be sure you are using the reserved folder names correctly, putting all your models in the Resources folder might seem like a good idea but could impact negatively on your project.

Links in this post

Meta data

Let's have some fun!

With the data in and stored in sensible C# classes, we can start to have some fun - I've added in some meta data about the current search item. By checking the lastest history item with the latest but, comparisons can be made about their differences. in this case, the change in price and percentage change.

double _latest = hist.items[hist.items.Count - 1].avgPrice;
double _latestButOne = hist.items[hist.items.Count - 2].avgPrice;

double _change = (_latest - _latestButOne);
double _percentChange = (_change / _latestButOne);

DateTime _latestDate = DateTime.Parse(hist.items[hist.items.Count - 1].date);
TimeSpan _outofDate = (DateTime.Now - _latestDate);

The TimeSpan class is great for this as it can be calculated with a the DateTime class.

We can also display when the latest history was updated - this is where buy/sell order wil come into their own as it is updated much more often than market history.

undefined

Links in this post

You are not a web designer

You are a game developer!

Excuse me while I jump on my high horse for this one. Personal portfolio websites are a great way of cataloging your games and projects but be careful about how much time you put into creating your website over the projects you want to show.

I've been guilty of this before - spending weekend are weekend finding and customising the perfect WordPress template to show off all my work.. only to be left with something that looks nothing like the original and completely distracts visitors from what I wanted to show them. Now this isn't a dig at WordPress - it's a great framework, I once built a Unity project entirely around it's API to upload and post community driven content.

But you must keep in mind if people are interested in giving you a job making games, it's going to be unlikely they will care that you've got a responsive layout and a jQuery driven image gallery.

It's a little difficult to preach about this when my portfolio pages aren't exactly the picture of perfection - but I'm trying, and so should you. My advice is stay away from flashy javascript animations, carousels, and responsive layouts. Keep things simple, a couple of images with a video, and a short paragraph or bullet list of the skills used is more than enough. Provide a download link if necessary but do not expect all visitors to bother with it. It might be worth looking at a different framework, there are a handful from Mashable and WebHostingSearch.

I'm not saying don't take pride showcasing your work - just be honest to yourself about your skill set and where your time is best placed.

Links in this post

Search period

One of the main features of the EVE Online Market view is filtering history by a date range, allowing the player to see trends over 1 year, 6 months, 3 months, and the last 7 days.

Luckily all entries in the history come with a date time string, which can be parsed directly to a .NET DateTime object. Compare this with a date from six months ago and we can filter the results.

DateTime cutOffDate = DateTime.Today.AddMonths(-6);

foreach (Item _item in hist.items) {

    // Grab the date from the history entry and compare against the cutoff date
    DateTime _date = DateTime.Parse(_item.date);
 
    if (_date >= cutOffDate) {
        // Add the history
    }
}

Making use of the new Dropdown UI element in Unity 5.3, the date range can be set directly from the UI event callback.

undefined

It is important to remember each entry in the history is a daily average, high, and low price of the specified item. In time, data about current buy/sell orders will be polled. It is this data that should benefit from the CREST API.

Links in this post

  • MSDN DateTime - Represents an instant in time, typically expressed as a date and time of day
Home ← Older posts