May 142013

I’ve been playing Eve Online on and off since 2006. It’s a very complex game with 500000 active accounts, all playing on the same server. What this means is that it has the most interesting economy of any game out there due to the huge number of interacting players, complex supply and manufacturing chains and a complete lack of market regulation.

This makes it a great sandbox for observing economic behaviours and principles from the real world, manifesting in its virtual economy. Here I’ve picked a few interesting or important things that I’ve come across.

Opportunity Cost

This is probably the most basic and misunderstood concept in Eve, so it’s likely misunderstood in real life as well. The opportunity cost of doing something is the price of not being able to do something else instead. For example, you’ll frequently come across advice in game like “mine your own minerals to increase your profit margin on manufacturing.”

Sounds sensible, but it’s completely wrong. Mining minerals may be a worthwhile thing to do, but it doesn’t increase manufacturing profits. They are two independent activities, and should be treated as such. Profit calculations for manufacturing should use the market value of the input materials, and not how much it personally cost you to acquire them. This is because you could have sold your mining output instead of using it. The opportunity cost using your minerals is that you can’t sell them (although there are other reasons why you might want to produce your own inputs, e.g. avoiding transaction taxes, or saving time selling and transporting, or just for fun).

Here’s a real world example. Suppose you need to clean your house, but you also have the option to work some paid overtime. You may think you can save money by doing the cleaning yourself, but if the overtime pays more than the cost of a cleaner then you’re better off working and paying someone else. The opportunity cost of doing your own cleaning is that you can’t be working at the same time.

Emergent market hubs

The design of Eve includes no central trade areas. Anyone is free to sell or buy anything anywhere in the galaxy. What is interesting is that a series of market ‘hubs’ have spontaneously emerged, with one main super-hub in the solar system of Jita. Many years ago, when there were less players and no major markets, some systems with slightly better facilities and connections were more densely populated that others. This meant slightly more market activity in those systems which attracted new players looking for markets, which grew the market even more. The result is a positive feedback loop, with the end result being that if you now want to buy or sell something quickly you go to Jita (or one of the smaller ‘regional hubs’ that grew along the same principles, but to a lesser extent).

There are a few downsides of basing your Eve industrial business in or near a popular hub. One is the rental cost of corporation offices (required for efficiently managing your industrial activities), which are much higher in popular systems. Another is availability of factories – these are limited and you can wait many days for a slot around trade hubs.

There are analogous factors at work in the real world, affecting where people and businesses base themselves. There are bigger markets and trade opportunities for London-based companies, but the rents are huge. Smaller cities have reduced costs at the expense of available markets and potential workforce. Different companies weigh up these factors and choose an appropriate location.

I found some statistics about the populations of the most popular systems in Eve, so I thought I’d compare it to the sizes of the largest UK cities. The results are quite striking:

Normalised populations of the 30 most populous Eve systems and UK cities

Comparing the normalised populations of the top 30 systems and UK cities, you can see a large degree of similarity in the distribution. There is one super-system/city (Jita/London), followed by a few large ones (Amarr/Birmingham, Rens/Manchester, Dodixie/Liverpool), followed by lots of much smaller ones.

The relative proportions are very similar. This suggests that similar price/opportunity trade-offs may be being made in Eve as in the real world, leading to a similar distribution. Eve populations seems to favour the larger hubs while the UK population is spread slightly more evenly, which could be explained by there being stronger non-economic reasons for living in a certain place in the real world than in Eve.


Here’s a more technical version of the above graph – log of population against log of rank. You can see they both follow a power law (very high R² value means the linear trend line is a good fit), even though the absolute population numbers in solar systems are very small so are prone to noise (or large passing fleets). The drop off in population is indeed faster in Eve as I mentioned above. Further analysis is left as an exercise to the reader 🙂

Log(population) against Log(rank), with least-squares trend line

Price vs Convenience, and Time Is Money

There are many ways of making money in Eve, and the one thing they have in common is that they take time. Time is the limiting resource of both Eve players and real-world workers. Travel in Eve is also slow, and flying around for fifteen minutes to save a few ISK (the in-game currency) is inefficient, as you’re paying the opportunity cost of not doing something more profitable.

Similarly, coffee shops in busy station charge a huge markup compared to a café you could find ten minutes walk away. It’s inefficient to use your time to save a pound if it takes a sizeable chunk out of your working day.

This inefficiency creates market opportunities. Ammo and other consumables are generally priced much higher outside of trade hubs, leading to higher profits, in the same way as station coffee shops. (Well, actually it’s the people renting the space to the coffee shop that make the profit, but as there is no shop rent in Eve the producer can keep it.)

Profit vs Volume

In an efficient free market it’s possible to either make a large profit per item sold, or to move large volumes of items, but not both. Where large volumes are shifted (trade hubs, busy shopping streets) you will find other businesses in competition and high prices will be undercut. In the ‘convenience’ market described above (backwater systems, small village shops) less people can be bothered to fight for the meagre sales so there is less competition and prices can be higher.

One example is manufacturers who sell their own goods. It is worth putting a few items on sale at the place of production, at inflated prices, to pick up passing trade, but manufacturing ability far outstrips these sales volumes. The bulk of the items will need to be sold at trade hubs where turnover can be huge – a smaller markup per item but higher overall profits.

You can see this with farmers markets and farm shops. Volume is small, but profits per item are much higher. The excess has to be sold to bulk buyers (e.g. supermarkets), but the additional profits from direct sales provide a nice additional income.

Fluid markets from professional traders

In the real world, if you want to buy or sell shares or a commodity then it is nearly always possible to conduct the trade immediately. It doesn’t require waiting for another person who wants to buy exactly the same amount of shares that you’re selling. This is good because it enables more trades to take place quicker, which means more benefits to those trading. The market is said to be fluid.

Fluid markets are enabled by professional traders – if you go to a foreign exchange they will buy currency at slightly below the average price, and sell it at slightly above. Therefore there is always a reasonably priced seller or buyer for your currency. The same principle applies to shares, commodities and other goods. The higher the potential profit (total traded volume multiplied by markup) the more competition will be attracted, and the buy and sell prices will converge.

Professional trading can be seen in action at trade hubs on almost all of the 6000-odd different items available in Eve. You will see buy and sell orders for huge volumes of items that could never be for personal use. High value items like ships attract a lot of competition and will have margins of 5-10% between the highest buy order and the lowest sell order. This means that whenever you want to buy or sell a ship, you can do so immediately with very little financial loss – you’re effectively paying the traders for convenience.

A weakness in the market can be seen by looking at some of the less popular items, where you’ll see 100% or more markup between the buy and sell prices. The volumes just aren’t there to support more competition – bringing the buy and sell prices closer together would mean it’s not worth the bother of trading, given that there are plenty of other things to do in game.

Barrier to entry, monopolies and cartels

An important principle in economics is the barrier to entry to a market. There are two reasons why the profit margin on an item may be high, but only one means you’re being ripped off:

  1. Sales volumes are low, so high margins are required to make it a worthwhile business.
  2. There are high barriers to entry, so it’s hard to compete with existing businesses.

To tell if you’re being taken advantage of, look at how hard it is to set up a competing business. If it’s easy then you’re probably not being ripped off and it’s just hard to make a profit. There are lots of examples of barriers to entry, from government restrictions (e.g. pre-privatisation utilities), to long professional training requirements (lawyers, doctors), to prohibitive startup costs (building a supermarket).

You can see these in operation in Eve. One interesting development was the creation of OTEC – the Organisation of Technetium Exporting Corporations – founded on the same principles as the more familiar OPEC. Technetium is a vital component in the manufacturing chain of many items in Eve, and is only found in one area the galaxy under the control of a small number of corporations. The barrier to entry here is nearly absolute – getting into the market would require overwhelming military force and months of warfare. Hence it was practical to set up a price fixing cartel and reap the resulting massive profits.

Another historical example was the breaking of the monopoly on Tech2 goods (these are better ships and weapons than the standard ones). Originally, the ability to manufacture these goods was distributed via lottery to a few lucky individuals. The one I’m most familiar with is the Damage Control II component, where I made most of my ISK.

With no competition, the first of these things were selling at 200+ million ISK each.  After a couple of years a game mechanic called Invention was introduced which allowed anyone to make them,  but less efficiently and with a significant up-front investment required for tools, skills and materials (in the order of 500 million ISK, and several weeks of in game training time). When I jumped in, prices had dropped to around 2 million ISK/unit, with about 60% of that as profit.

Over the next few months the initial investment price dropped and now it’s possible to enter the market with a few tens of millions. Profits are right down to something like 300,000 ISK/unit, and it’s approaching the “worth it” line where I need to decide whether it’s worth carrying on production.

Thus enabling competition has successfully brought the cost of a good right down to theoretical minimum of the cost of production plus the minimum profit required to make people bother. Economics in action!

May 012013

The next lighting technique I want to cover is environment mapping with cube maps.

Environment mapping

Environment mapping is another form of specular lighting. When I spoke about specular lighting here, I was talking about simulating the light reflected from one bright light source. You can repeat the calculations for multiple light sources but it quickly gets expensive. For a real scene, an object will be reflecting light from every other point in the scene that is visible from it. Using the standard specular approach is obviously not feasible for this infinite number of light sources, so we can take a different approach to modelling it by using a texture. We call this environment mapping.

Cube maps

We need to use a texture to store information about all of the light hitting a point in the scene. However, textures are rectangular and can’t obviously be mapped around a sphere (which is needed to represent all the light from the front, back, sides, top, bottom etc). What we do is use six textures instead, one for each side of a cube, and we call this a cube map. When arranged in a cross shape you can see how they would fold together into a cube:

Uffizi Gallery environment map

This is a famous cube map of the Uffizi Gallery in Florence, and is a bit like a panoramic photo with six images stitched together. These six textures are actually stored separately (they’re not actually combined into one big texture), and they are labelled front, back, left, right, top and bottom as in the image.

Lighting with cube maps

Remember how the reflection vector is calculated by reflecting the view vector around the normal. This reflection vector points to what you would see if the surface was a mirror (and is therefore the direction where any specular lighting comes from). The problem is to know what light would be reflected from that direction, and that is where the cube map comes in.

An environment map is another name for a cube map that contains a full panoramic view of the world (or environment) in all directions, such as the one above. The reflection vector can be used directly to look up into the environment map. This then gives you the colour of the reflection from that point.

In a pixel shader, it’s as simple as doing a normal texture lookup apart from you use the reflection direction as the texture coordinate:

float4 reflection = reflectionTexture.Sample(sampler, reflectionDirection);

Here is an example of my test scene where the only lighting on the objects is from the nebula cube map I used here:

Only lit using an environment map

How does the GPU actually look up into the texture though? The first thing it needs to do is find which face of the cube the reflection ray is going to hit. To find this, we just need to find the longest component in the reflection vector. If the X component is longest then the vector is mainly pointing left or right (depending if it’s positive or negative) so we will use the left or right face. Similarly, if the Y component is longest then we use the top or bottom face, and if Z is longest then we use the front or back face. Let’s start with an example:

reflectionVector = { -0.84, 0.23, 0.49 }

The X component is the largest, so we want either the left or right face. It’s negative, so we want the left face.

Now the face has been determined, the vector can be used to find the actual texture coordinates in that face. In exactly the same way as a vertex is projected onto the screen, the vector is projected onto the face we’ve just found by dividing by the longest component:

{ -0.84, 0.23, 0.49 } / -0.84 = { 1.0, -0.27, -0.58 }

Take the two components that don’t point towards the face (Y and Z in this case) and map them from (-1, 1) range to (0, 1) range, as this is the range that texture coordinates are specified in:

textureCoords = { -0.27, -0.58 } * 0.5 + { 0.5, 0.5 } = { 0.37, 0.21 }

And that is what texture coordinate will be sampled from the left face in this example.

Blurry reflections

Using a cube map like this will always give very sharp, mirror-like reflections, as sharp as the texture in the cube map. Surfaces that aren’t completely smooth should have blurred reflections instead, due to the variety of surface orientations on a small area of rough material (like I talked about here). One way of doing this would be to sample the cube map multiple times in a cone around the reflection vector and average them, which would simulate the light reflected in from different parts of the world. However, this would be very slow. Instead we can make use of mipmapping.


Mipmapping is an important technique when doing any kind of graphics using textures. It involves storing a texture at multiple different sizes, so that the most appropriate size can be used when rendering. Here are the mipmaps for the left face of the texture above:

Mipmap levels for one cube face

Each successive mipmap level is half the resolution of the previous one. To make the next mipmap level, you can just average each 2×2 block of pixels from the previous level, and that gives the colour of the single pixel in the lower resolution level. What this means is that each pixel in a smaller mipmap level contains all of the colour information of all of the pixels it represents in the original image. As shown in the picture, if you blow up a smaller mipmap you get a blurry version of the original image.

Funnily enough, this is exactly what we need for blurry reflections. By changing what resolution mipmap level we sample from (and we are free to choose this in the pixel shader), we can sample from a sharp or a blurry version of the environment map. We could change this level of blurriness per-object, or even per-pixel, to get a variety of reflective surface materials.

Mipmaps in standard texturing

To finish off, I’ll give a quick explanation of why mipmapping is used with standard texturing, as I didn’t cover it earlier.

There are two main reasons why mipmaps are useful, and these are to do with aliasing and memory performance. Both of these problems are only seen if you’re drawing a textured polygon on the screen, and it’s really small. The problems in this case is that you’re only drawing a few pixels to the screen, but you’re sampling from a much larger texture.

The first problem of aliasing occurs when a sample of a texture for a pixel doesn’t include all of the colour information that should be included. For example, imagine a large black and white striped texture drawn only a few pixel wide. When sampling from the full-resolution texture each pixel must be either black or white, as those are the only colours in the texture. Each pixel should actually be drawn grey, because each pixel covers multiple texels (a texel is a pixel in a texture), which would average out to grey. Using a smaller, blurrier mipmap level would give the correct grey colour. If mipmapping isn’t used, the image will shimmer as the polygon moves (due to the where in the texture the sample happens to land).

Aliasing when a highly detailed texture is scaled down and rotated clockwise a bit

The second problem is performance. Due to the way that texture memory works, it is much more efficient to use smaller textures. Using a texture that is far too big not only looks worse due to aliasing, it’s actually a lot slower because much more memory has to be accessed to draw the polygon. Using the correct mipmap level means less memory has to be accessed so it will draw faster.

Next time I’ll conclude this part of the series by talking about basic shadowing techniques.