Economics: a zero sum game?
27/05/2014 Leave a comment
Recently replaying some old favourites of mine such as Mount and Blade and the Total War series, I got to thinking about one of my favourite topics at university. It came out in a number of different projects, of which the latest and most advanced of these I decided today to revisit. In it’s simplest form, it was an economic simulator set in space with multiple interstellar colonies and traders shipping goods around between the colonies while travelling faster than the speed of light. The end result had a couple of bugs (including one fairly interesting one which made it into the final submission) and the UI was fairly crude and non-functional in places.
Here is the post mortem I wrote at the time (1055 words). To summarise, I didn’t set exact goals about what I wanted to encapsulate and test in the simulator, I made an over-ambitious attempt to include facets of a previous (similar) project and had difficulties developing the UI to a satisfactory level that would display the reams of data being processed behind the scenes (also, haha, I blame the libraries for something at one point). I did end up building a very nice demonstration of node traversal although most Comp Sci grads would probably say it’s fairly simple what I chose to demonstrate. I like to think the setting more than made up for that.
The PM also lays out how the simulator actually functions, which I’ll be referencing later when I dig into some things I want to revisit with it specifically.
IND302 Space Sim – An attempt to simulate a real world economy in a fictional framework
Miles WhitickerApproaching the end of the project, I looked back over my progress to see how it compared to what I initially envisioned it to be. Although going into the start of the project I was quite sure what it would involve (if not exactly what the end result would look like), I definitely hadn’t pinned down the specifics – and an extremely enthusiastic week 3 spent designing did not help to present an achievable goal. Mentor feedback from the learning contract also reflected this, although I did not take that on board until later.
Although it’s said that proper planning is always essential to producing a good end result, I think the lack of concrete plans (while hindering me in many ways) did not ultimately prevent me from achieving the end result. The one thing I knew I wanted the simulation to have was ships carrying goods between planets, and being able to slow down and speed up to see those goods having an affect (as well as the ships zooming around). That provided a solid core around which to base my early design considerations (as I mentioned above, some of which went quite overboard). As well as this, I wanted the project to showcase my skills in developing AI and complex, realistic systems – and what better way to do that than to develop a [limited] economic simulator?
The economic simulator would be the focus. I decided that colonies (the primary ‘agents’) would require a functioning industrial backbone in order to provide the primary supply and demand. Therefore, colonies would need to be able to build factories to turn materials into goods. Like any economy though, it’s affected quite strongly by its labour force. I represented this by applying a percentage modifier to productivity for each factory that did not have full employees. Employees (through the form of colony population) were the next most complex subsystem and would need to be carefully maintained by the colony AI as well. The population of a colony required housing to grow, as well as hourly supplies of food and water (and oxygen if the atmosphere wasn’t breathable). Power would also be required to make sure everything runs, which consumes fuel. It was a delicately constructed balance– just like the real thing.
Working through development, a major pitfall was realised relatively early in the development of the UI. Due to the simulation being driven by a series of complex systems, a large amount of rapidly changing data would need to be presented to the user in several different forms. This data would come out in 17 different resource types and 18 different infrastructure, although they would be combined or used to calculate other secondary and tertiary data which was also output to the user. A mockup for the UI was developed in week 5, but it was redesigned several times over the next few weeks and each time the entire UI system had to be overhauled (see weekly reports).
Early in UI development, optimisations were taken to mass output all the primary data (and secondary / tertiary data was largely ignored). This took the form of looping over all resource/industry types and outputting them in a uniform table. The later designs were much more user-friendly, and presented secondary and tertiary data as well, but conversely took significantly longer to implement and were one of the major contributing factors to the mid-project delay.
The other notable failure of the project was to develop a realistic and complex AI for the traders. As I mentioned above, major delays came about during the middle of the project which reduced time available to work on the intermediate and later goals. In its final implementation, the trader AI was crudely represented by simply buying cheap goods, selling expensive goods and moving between random destinations. The initial concept documents called for dynamically choosing destinations based on profitability and distance, as primary factors (and various personality characteristics affecting other choices being secondary factors). As designed in previous projects, I planned to develop a complex probability system allowing for random decisions across a weighted tree of possible actions, using such concepts as Bayesian probability and fuzzy logic.
Fortunately (or not), an alternate system was discovered that was crucial for trader navigation. As the original concept called strongly for trader movement across the various ‘views’ or ‘levels’ (representing nodes across a multi-branched tree), I realised that it called for a complex tree traversal algorithm that would need to be custom tailored to this specific situation. Research into viable algorithms to base it off showed that I would need to do what is effectively an iterative reverse depth first algorithm (based off a sample implementation that I had prepared as the prototype algorithm). The specifics of the traversal were as follows:
– Starting from the destination node (a colony somewhere), loop upwards until you either find a node that has the same parent as the current location OR you reach the root node.
– For each successive iteration that does not find a matching parent, move the current location up one level.This algorithm resulted in a destination level ‘above’ or on the same level as the ship’s location (represented by moving up in scale, from planet -> star system -> stellar group, etc). Once the ship reaches that level, they travel ‘across’ the level in 2D space until they reach the destination, then travel ‘down’ the tree until they reach the destination (moving down in scale, eg from stellar group -> star system -> planet). The way I setup travelling ‘up’ and ‘down’ the nodes also made ships only go up a level when they reached the edges of the screen, and when moving down a level they ‘arrived’ at the edges of the screen, creating the effect of the ship coming in from some distant, offscreen location.
In reflection on the goals of this project, I never fully determined exactly what hypothesis I was testing, or whether I even had one to test. Ultimately, I think the interlocking systems and subsystems of the project are a goal enough to have produced, and when combined with the sum learning experience I have undergone, I believe the project more than achieved its aims.
After updating various libraries (SFML and SFGUI, two codebases I’ve been doting on for almost three years now) to more updated versions I was quickly reintroduced to the one significant bug I was unable to fix before submission – somewhere in the route planner for my traders I’d failed to catch a default case (no destination/heading/something) and as a result after a few years of simulated time they would inevitably set off to seek their fortune in a galaxy far far away, which made the app crash when their ships reached the edge of the screen on the most “zoomed out” display mode. I say this bug was fun, because at the time I was certain that if I’d had a few more days I could have cracked it. I’d quickly and clearly pinpointed the issue (and it would have been the quickest fix ever), it’s just… ah.
Putting aside that and the bugbear I had awoken while building the UI for that project, the other thing that jumped out at me was the course of development of the colonies. Although I’m fairly sure there was a bug in displaying some data for certain colonies (towards the end I was getting incredibly frustated with rebuilding the UI from scratch so many times) most colonies would eventually stabilise at a population of a few hundred people, while one or two colonies sometimes managed to overcome the initial challenge of settlement and steadily grow for as long as I ran the simulation (the lucky ones, I guess).
Going over the algorithm that decided which types of infrastructure to upgrade in the colonies, I think I’ve picked out what caused most colonies to eventually stabilise development (and thus growth). First off, all development required resources (circuitry, components, sheet metal, girders). First priority went to maintaining existing infrastructure, then whatever was left over could be used to build more. So naturally once construction resources flatlined, so did development. As a direct consequence of having no construction resources, all infrastructure built by that point would start falling to pieces because there was no resources to maintain it, which would eventually result in the death of the colony. As a safeguard to this, I introduced a control measure to ensure that the colonies would immediately build production facilities to ensure there was a minimum of the necessary resources being constantly produced (for sake of simplification the necessary raw materials were always available everywhere). The colonies that managed to thrive seemed to be the ones that upgraded their resource production facilities beyond the minimum mandatory level I had instructed all colonies to immediately upgrade to.
This is in contrast to a potential cause I had tossed over a few days ago which was that development and maintenance required employees set aside to actually happen, but I hadn’t got around to coding that in so the vital labouring crews were just pulled from the unemployed pool – which due to the job assignment and colony development AI was almost always at 0%! This turned out to not be the case, as I had actually told the colony AI to reassign the jobs of the entire population every month and 10% of the population went to the construction industry before anything else! Talk about job security.
A caveat to this situation is that my trader AI is less than perfect, but probably would have been able to offer a much more “in universe” solution – which was to ship the necessary resources from those lucky colonies that had plenty to the colonies that were struggling to produce the necessary materials to maintain their existence. It’s just that the traders were effectively “dumb” agents in that they randomly chose which planets to fly to 😦 the best part of the simulation and I was too busy programming the back end of it the entire time!
Regarding the colonies’ growth plateau, in all cases enough food and water was being produced while the power and oxygen systems were large enough capacity to cover the entire population – the thing curbing population growth was lack of housing. I mercilessly decided to simulate death of homeless people due to environmental exposure by stopping all babies being born when the colony ran out of population room. At least a regular monthly loss of 1-5% of the population due to natural causes kept things in a little bit of flux.
One of the conclusions I came to that has most stuck with me since finishing the project was the potential depth sink with simulating an economy. Dwarf Fortress is the only thing I can compare it to, in that there’s probably an infinite amount of complexity I can eventually build into the sim but each time I do I’ll need to rebalance the existing conditions to make sure the world is a) reasonably realistic and b) self sustainaning (making it a wicked problem). The name of this post (zero sum game) is a reference to the competition between the different types of buildable infrastructure for the available resources in the colony AI.
Now that I’ve updated the relevant libraries to more recent versions, I’m planning to mess around with it over the coming days or weeks and I might post a progress update if there are any interesting developments. Anyone interested in the simulation can find the code for it at https://github.com/mileswhiticker/ind302-spacesim (minor recompilation may be needed).
