In the first dev blog post of Polis we went through the first two weeks of the project where our focus was mainly on getting the hexagon grid working, generating the terrain and mountains procedurally and splitting the generation on various factories, each responsible for part of the generation (grid, tile, terrain, vegetation, etc). The next two weeks were spent mostly on figuring out some core gameplay mechanics while implementing some necessary subsystems.
In general, the flow of the game will be like this: You select a tile, you see what resources it has and construct a building to exploit some of them. All these resources will end up in your city tile through some kind of a transportation system. You can then use them to sustain, grow and keep your population happy or construct more buildings to exploit and discover other resources.
At this point we won’t care much about defining all the mechanics down to every little detail, but mostly about laying out some ideas in general and defining relationships between things. In my experience, gameplay is an iterative process: you start with simple things, prototype a few mechanics seeing what works and what not, you keep iterating and refining them until you are happy (or run out of money).
Resources, Buildings and Production
So what do resources mean for the game’s world and the player? What do we define as a resource and what’s the relationship between various resources? To answer all these questions I took a look at good old Wikipedia  and some similar games of course.
In Polis we’ll split resources in three broad categories: Natural resources, food and building materials. Natural resources can be found on tiles and can be renewable or non-renewable. Food and building materials are secondary resources and will usually be derived from natural resources through some natural or human process.
Let’s use an example to make things clearer. In Image 1 we’ve got a tree which is a natural resource found on forest tiles. The tree has no knowledge that it can produce wood. However the tree knows that in its life-cycle it will produce seeds as the seeds will eventually produce trees. This is the natural process that we will use to produce trees in our world. In order to get wood from the tree though, a human process needs to be involved: We’ll need to build a logging camp, assign some workers to go there, chop the tree down (sorry tree) and “transform” it into wood, which we can then use for other things (heat, building material, etc).
Buildings are a crucial part of the gameplay. The logging camp we mentioned above is a production building and production buildings will map a relationship between some input resources and workers’ actions to some output resources. Other production buildings we’ll have are the stone quarry where we can mine stone from rock, farms which given fertile ground (top soil) and some seed can produce various types of food and pastures that help raise animals and produce meat. Finally we’ll have housing and storage buildings that will help expand the city’s population and storage capacity allowing us to produce more.
Separating the data from the behavior
Now that we have a better idea of what we’re doing we need to be able to define our resources, buildings and other items in the game, refer to them in gameplay code or display some information on the UI. Ideally we want to separate the data that define an item from the item’s behavior.
Let’s say for example that we have a resource called wood. We want to be able to refer to this in the logging camp to map the relationship between tree and wood. We also want to display some information and icons on the UI when we’re in the inventory screen and click on the wood item. Wood is also a building resource so we also want to refer to it from various other buildings. Maybe in the future we’ll decide that we want to use wood as fuel, store an energy value in it and use it in some system to generate heat using it as fuel.
In Unity we can use a ScriptableObject  to store data as an asset which is really convenient as we can go to our asset directory, create our item, configure it and then drag and drop it anywhere we want. Our system architecture is quite simple: we have a base class, called Commodity, deriving from a ScriptableObject to represent the item’s data and another asset called CommodityCatalog, which basically stores a list of all the available item data. We have an editor script, the CommodityEditor, which allows us to export all the commodity assets from a directory to the CommodityCatalog while generating a unique ID for each. We can then use the CommodityCatalog asset anywhere in our code to find a commodity using that unique ID and do what we need to do with it. Ideally we’d like to assign the unique ID of the commodity instead of a reference and then use the catalog to get the item data, but that’s a problem for another day.
Having defined the data of the resources and buildings we want to be able to present this information to the player on the UI to help drive their decisions. A tile has a number of resources and these resources will define what buildings we can construct on that tile, therefore we need a UI control to show the selected tile’s information and another control which shows the possible buildings we can construct. Both these controls will need to populate lists with some data. The building control will also need to keep track of the currently selected building so when we hit “Build” it can place a request in the construction system.
So it was quite clear that the first UI controls we needed were lists: horizontal, vertical, selectable and scrollable. Fortunately Unity’s new UI is extremely powerful, easy to use and gives you all the tools you need to easily create UI elements without having to write too much code. From all the various UI solutions I’ve used in games (professionally and not) I can say that so far I like Unity’s the most.
After experimenting a few days with the various UI elements (common controls, Layouts, Canvas, etc) I ended up with a generic list control and some prefabs that we can use to make lists (see Image 3a). In Images 3b and 3c you can see the list in action displaying buildings and available resources on tiles.
- Construction system: Now that we know what buildings we can construct on a tile we need a system to take care of the construction process. We need to be able to request construction of a building on a tile, cancel the construction and get regular updates of the stage it is in.
- Production buildings behavior: We have defined our buildings so we need to implement their behavior, taking the inputs and producing outputs as defined in each building’s commodity.
- Transportation system: Production buildings will store the outputs on a local storage. We need a transportation system to move the goods from the production buildings to the city tile. The same transportation system can also be used to transport workers to construction sites or production buildings.