Tuesday, December 30, 2014

Microservice Architecture

Microactions, Parent Actions, Faction Actions, Family Actions

Microservices? Hah, just kidding. This isn't some web service SOA game. Because screw micropayment games. We're here to talk about the amazing and fascinating world of actions; the state machines that get your units doing the things you told them to do. In Cultura, it happens in a hierarchial manner: faction, family, unit. The short version is that when you queue up a big faction-wide action it then doles out unit actions to individual units. Some automated actions, like finding food for the family, are family actions which doles out actions to individual units within a family.

As it turns out, debugging this is super hard. A unit has a stack of actions to track what it should be doing, as each action finishes it pops and the next action in the stack is worked on. Every action has a simple shared interface so that the unit can processTick just by calling doAction on generic actions. Underneath, each action is a child class of UnitAction which has its own various states. But, big actions are complex. Something as simple as "harvest node" turns into a confusing mess of state transitions (what if my inventory is full? resource node is exhausted? I'm under attack? drop off location disappeared or is full?).

So, we go into refactoring code. The current round of refactoring involves devolving each action into "microactions". An action is now defined by three simple concepts: Exit Conditions, Stacking Conditions and the Action. A microaction is an action without Stacking Conditions.

Exit Conditions

In order to keep things simple, an action has clear exit conditions. By breaking things down to microactions, the exit conditions become very simple. Move action? If I'm there then exit. Build action? Apply enough labour and then exit. Drop off action? Drop off what I can and then exit. The larger actions usually wait until a microaction is finished for some its exit conditions and merely tracks the number of microactions successfully completed.

This requires a bit of paradigm shift within the code. Actions don't get wiped off the stack. There's a few edge cases where things get tricky (making sure that we keep track of resources used in the construction of an object don't get lost if a unit dies but they do get lost if the building they're in is destroyed/looted). Secondly, player initiated actions can get replaced or wiped but they need to only be of certain types of actions so that they don't hit those edge cases.

Stacking Conditions

For more complex actions, they are built using a variety of microactions. A single harvest action involves move actions, pick up actions, drop off actions and the actual harvesting itself. The core of a harvest action can be thought of as the "harvest" action. Everything else is a condition where we bump out of the action and do something else. In the case of microactions, we only ever exit; we never do any other action and therefore are atomic actions. In bigger actions, they may need to use a microaction to complete a task. By never wiping the stack, we can rely on the fact that no matter what happens between one action and the next, an action can be completed to the right conditions and we can safely pop.

A stack condition is something that is checked and if needed, a new action is stacked on the unit. For a harvest action, this may mean that a move action is triggered if the unit isn't close enough to a desired location. We can safely assume when this action completes we are at the right location. This is key. All actions can have any number of things happen before they actually complete. A move can be interrupted by another move, by a flee action or anything else but when the stack pops and goes back to the same move action, it does what we want it to do and when it is done we are assured we are in the right condition. And even if we are not, it'd hit the same stacking condition in the parent action.

As an example, say we are harvesting. We try to harvest but we hit "are we close enough" stacking condition. We aren't! So a move action is stacked. When that completes, we are at the node and can then do the harvest.

A more complex example: we are harvesting. We try to harvest but aren't close enough so we stack a move action. But then the player selects the unit to go chop a tree. Later when the tree has finished chopping, the unit is somewhere else entirely but it pops back to the original stacked move action. It then tries to move to the node before harvesting.

Action

Most of the actions involve some core action that it does. This is "harvest" or "drop off". However, some actions are merely just a collection of Exit Conditions and Stacking Conditions. Refactoring everything into simple if statements leaves the core of any action to be an incredibly simple and small amount of code. This is what makes the debugging super easy. State transitions are clearly defined.

The Future

At more well funded studios (ones with more than zero dollars) the state transitions and actions are usually data-driven. The engine defines a bunch of atomic actions and a whack of possible enter/exit conditions and/or triggers. Eventually, I would like to get Cultura to that point but the microaction refactoring is the first step. It makes a clear way for me to go ahead with the data-driven model. For instance, every "if statement" could instead be codified in a class with an interface that has a single bool function shouldContinue and the c++ code encompasses what it means but the data-driven part just uses labels like "check if inventory full/empty". Then actions are built dynamically on load time with arrays of exit and stacking conditions.

Huzzah.

Tuesday, December 9, 2014

Building Skynet

Artificial Intelligence

So, after the Alpha there's going to be some thought about how to build the opponents in the game: the AI. Most games are built using scripted AI and some limited heuristics in order for the player to compete against some rudimentary opponents. In games such as Civilization it's a make or break scenario; bad AI translates to a truly awful game experience. For most big budget games, ironically there's zero time/money for developing good AI, whereas for indie developed games, there's a lot more room for it. It's mostly because AI is about the most unreliable (timeline wise) aspect of a game to work on.

Cultura is going to use pre-trained AI. How much heuristics depends on how well the training goes but let's talk about the idealized world of having an AI trained from nothing!

The Metrics

The Cultura AI is going to be looked at from three different angles:

  • Data: What metrics is the AI going to rely upon and measure?
  • Score: This is a continuous game, so rather than a concept of winning/losing which the AI can train upon, it continuously checks itself against a score to see whether it is doing well
  • Actions: What is it that the AI actually has control over in order to attempt maximizing the Score?

The exact method used to maximize score could vary: using a perceptron or perhaps a multi-layer neural net or something more sophisticated would be the obvious choices. These can lead to different output values for types of actions and what to act upon. A highly scripted AI would be built similarly except that the metric -> action translation would be built by hand. In the case of a trained AI, it would rely on the Data and then produce an choice about which action to take.

Data

The data is one of the most important aspects of the AI. Choosing insufficient or irrelevant metrics will mean that the AI is not paying attention to the right things to make its actions. Some of the data is simple. It should know what land it owns, what resources are on that land at any given moment and the number of people. It might also try to track buildings, industrial buildings of different types, tools, weapons and military power. And finally, the more difficult to track is the relationship with each faction it knows about.

  • Non-renewable Resources: It should know about the current maximum draw rate and the current actual draw rate.
  • Renewable Resources: It should know about the current amount left, the rate of growth and the current draw rate.
  • People: It should know about the number of people, it might split them apart by labour skill
  • Buildings: It should know about number of buildings, industrial buildings
  • Goods: It should track number of tools and weapons available, by type and have more points for superior tools/weapons in a particular category
  • Military Power: It should track how powerful it's currently active military is

How might we track a relationship with someone? The issue is that an AI should be able to care that it has hostile neighbours. But how to do that?

  • Relationship Score
  • Military Power
  • Distance

We could track those two metrics for each known neighbour, have some interesting way of calculating distance (perhaps the closest distance between two land areas of the two factions) and then worry about the military power. Then, we could lump all this together for a total relationship score that is used for calculations... or we could leave it separate. Lumping it together makes it a bit easier for the "national AI" to make overall decisions. One hopes through training it figures out that highly hostile military powers near it means that it needs to defend itself against the enemy.

Score

Ultimately, any AI needs some kind of objective function or else it doesn't train against much. In the case of Cultura there is no winning or losing. It is a continuous game that you continue to play FOREVER. So, how might we picture this? I figure the simplest way is to see the game as a race with positions and you always want to be number one. So, how well an AI thinks it is doing depends on how well others are doing. This could make the AI pretty hard to train (though, another thought is to have opponents who are fake but always improving at a constant rate and try to train AI against this).

This means that we have a way of calculating score and then all the AI is trying to do is get one more point compared to the highest score.

The score is likely to be a function that is something like Total = Population * Happiness * Health + Wealth + Buildings + Land. Another option is to try to track population, health, happiness and wealth separately and have the AI try to be first place in each category.

Actions

And what is an AI without the ability to do anything? The main picture of the world to the AI is Labour Distribution. Oh ho ho, how communist! But more seriously, this is where the AI tries to decide economic activity to the best of its ability in order to cope with the world and become number one. Also, for those that might actually be concerned about a fully communist AI-run society, the future of Cultura involves a concept known as administrative cost which limits the amount the government can do (because any action it takes administration points thus it might be superior to leave some things to private hands).

Okay so one type of action is changing the amount of labour in a particular industry at the margin. Doing it at the margin is important because we don't want an AI that makes crazy decisions, we want one that edges a society toward the optimal solution in a finite amount of time. Another type of decision would be to expand or upgrade the industrial structures related to a particular industry. In a similar vein, it might decide to increase the number of tools being made for a particular industry to increase production.

But, the more difficult decisions comes from foreign interaction. Okay, so it's pretty easy to say "Gee my happiness is low, build some kind of luxury". Then it's more difficult to say what kind of good. But even if you were to decide that when would you figure out "Gee let's instead trade ivory figurines for wooden furniture because the comparative advantage makes this a superior choice than forming a domestic industry to do this?" One choice is to say that a generic action is "increase production of x" and then a subsequent sub-choice to that is "how to increase production of x" where "trade" is an action and then the sub-choice there is "what do I trade off and to who for this good?"

And then of course, there's raiding, war and peace. How to train an AI to be able to figure out when it should make these types of decisions? "Relationship metric is very low, attempt to fix this is triggered, peace is less costly than war" OR "Wealth Score needs to be improved, weak nation nearby, crush nation and take goods"

Conclusion

This is a pretty good start to the AI question. In the end, the most important thing is there to be an awesome AI that is interesting to play against and is highly intelligent. This is one of the few games where an AI who is really awesome at managing a society is totally okay. Striving for Nintendo Hard here.

Thursday, October 16, 2014

Industrial Design

There hasn't been an awful lot of work done on Cultura in the past few weeks due to other concerns (like my job :D ) but in any case, some progress was made. The calculation for placing down buildings was revamped and by revamped I mean it now works properly.

Industry

Other than that, some thought was put into how industry works. Right now it's pretty basic. You collect some resources and it becomes a good.

  • Grains -> Beer
  • Grains -> Flour -> Bread

But, what exact structure do I want out of Cultura? So I compiled my thoughts into a convenient list:

  • Each land region only has a set of resources. Each land region has a type that determines how much of each type it contains (Dry areas have more grass and animals, wet areas have more trees).
  • Each society will focus on making only a subset of the types of goods. This is determined by the Culture Tree they pursue. Someone rich in wood would choose more wood-based goods. Someone rich in earth would choose more earth-base goods.
  • For each society to develop uniquely and have access to a balanced number of goods, each resource type leads to exactly three types of goods, one type of intermediate good and is assisted by one type of tool and one type of factory.

The point of this design is that each society can have 6-7 goods they produce, easily understood by a player and encourage trade to benefit both societies. Or raiding, up to you. This lets you focus a society to produce specific goods, have clear-cut industries you work on and have trade routes that are obvious (I produce Red Clay Pottery and I trade with Oglandia for Blue Flower Potpourri). For the lithic ages, this mimics the kind of trading that would mostly occur: goods for different goods. In later editions of Cultura, the concept of comparative advantage would be more well developed (that's not to say it doesn't already occur in this game but concepts such as labour specialization, labour skill, industrial infrastructure heavily affect comparative advantage and encourage trade of similar goods).

So the concept is meant to be simple. While it seems wordy here, the player is simply presented with a set of goods that are available from their land. Based on that they would choose to invest Culture points into "buying" goods that they can definitely produce. Then they build up those industries like in any other game (Anno, Caesar, Children of the Nile)... as in they would expand resource collection, make more tools, build up workshops all to increase productivity. After that they can choose to overproduce in order to trade the excess to other societies.

Tools and Factories

Now onto productivity. Okay, so there's another list of ideas:

  • Tools
  • Workshop/factory

After a lot of thought and debate in my head, I've settled on something as simple as possible. Tools boost productivity. There'll be a tool per super type of good. What do I mean by super type? A super type would be something like "pottery", which might start off as "clayware" which becomes "pottery" which becomes "glazed pottery" and then becomes "lacquerware" and so on. All of these can be improved by the same type of tool. Your tech level determines the level of tool you produce. In my opinion, the "confusion" that arises from having lots of different kinds of tools comes from the UI. In my planned UI (which has yet to occur) is to have the industry management group goods and their respective tool together when doing labour assignment. This way you can quickly balance the number of tool makers to goods makers and have the correct flow of tools immediately.

I use the term factory loosely. I just mean a building that helps produce a particular good faster. It does it in one big way: it skips steps. For the cost of fuel you can skip a bunch of steps. So normally a production chain is like "Grain -> Flour -> Bread". Then a second tier good would be "Grain -> Flour -> Bread -> Fruitbread" (look, you try to come up with more advanced bread). So, Grain is harvested from grain fields. Flour is made from Grain using labour. Bread is made from Flour using labour. Fruitbread is made from Bread using labour and Fruit. But, what if you had the awesome technology of... Fire Pit? Well then, now you can skip steps! Fruitbread can alternatively be made from Flour and Fruit and Labour and Lithic Fuel. So you've skipped the step of making Bread and instead directly make Fruitbread. Imagine the labour savings!

As the game designer this means I need to balance the cost of Lithic Fuel against the time saving you earn from not making bread (if it takes a really long time to make Lithic Fuel then I need to make the Fire Pit more productive to make up for it).

For the first iteration of Cultura this doesn't seem like much. But imagine later down the line when it is something like "Metal -> Metal Bar -> Bronze Bar -> Steel Bar -> Fine Steel Bar -> Perfect Steel Bar", then something like the "Fan-blown Blast Furnace" which gives you "Metal + Coal-Fuel -> Perfect Steel Bar" would mean that a single unit of coal-fuel just skipped four steps which could mean enormous labour savings (5x less assuming each step costs the same). It's really about game balance.

Ecosystem

How about the ecosystem? Most games are designed after "keep building forever". Cultura is designed a bit differently. This is meant to be a game where you play a society from ground up. And when I say from ground up, I mean eeeeeeeverything. The ecosystem matters. Forests grow. Animals give birth. If I were simulating water sources in the first iteration, there'd even be rainfall. I try to keep it simple though. The number of plants and animals determines their growth rate. In real life, their interaction determines the growth rate. But all I'm trying to simulate is a carrying capacity.

How many resources you draw from the ecosystem is limited by your land and your technology. Better land or better technology lets you draw more from the land. You can choose to underdraw to keep the ecosystem healthy or you could choose to overdraw for some purpose of prestige or fighting hostile societies, as a temporary measure. Or you might sacrifice the ecosystem of some land regions because you're not going to farm there anyway due to urbanization. It's up to the player to decide how to best utilize the land but the land will matter in this game.

Sunday, August 24, 2014

My A-Star is Too Slow, Now With Jump Point Search

As is the case in game programming, my first performance roadblock that is really hurting the Alpha is the pathfinding. It uses A* and it is slow once you get to 40+ square length paths. By slow I mean you can see it takes on the order of 100s of ms for just a few units.

That's bad.

So I went ahead and added Jump Point Search, JPS, but interestingly it made my pathfinding EVEN SLOWER! The issue is that JPS is only superior to super vanilla blind implementation of A* without even, I guess, a heap to store the open list?

Jump Point Pain

Okay, JPS isn't just awesome by blindly implementing the algorithm as pointed out by Harabor (here's the white paper). But it does add value, if we can figure out what is slowing everything down then we can get what it promises: less nodes to check in the open list which is an O(logn) insert.

First, why is A* faster than A* + vanilla JPS? The issue comes down to how the open list is processed. A* with a simple heuristic ( c^2 = a^2 + b^2 ) gives us a very accurate way of determining the next path to analyze without over-estimation. Additionally, the modified A* in Cultura "prefers" to check paths of longer length between two equal cost (known + estimated cost) paths. This means it will traverse down something that is likely to hit the goal node first and end the search. In practice, this means racing down the correct path almost immediately and finding the goal node. So the costs are a bunch of O(logn) inserts and O(1) pops to get the head.

This is quick but the inserts eventually slow down the pathfinding to a very mediocre speed by even a 40-length path.

Thus begins our quest to optimize the shit out of pathfinding.

Cost Estimation Heuristic

The first and simplest optimization was to improve the cost estimation. Originally it was using the "squared" straight line distance to avoid performing a square root. This avoids the computationally expensive square root in the hopes that it doesn't damage performance.

Unfortunately, that just wasn't true. The more accurate straight line distance versus the square straight line distance was pretty much a different in runtime complexity on path lengths over a 10-step length. This was due to the poor "next node" selection in the A* open list. Doing the full calculation allowed A* to correctly choose the next node without trouble and thus be nearly linear in all typical use cases in Cultura.

These days you can use really awesome square root calculators that make it painless. Here are two things: the ole quick square root popularized by Carmack and the much newer asm_sqrt instruction. My box is a quad-core 3.6 Ghz i8 processor for reference.

Just so you know, here's fast inverse square root:

float CJumpPointSearch::Q_rsqrt( float number )
{
 long i;
 float x2, y;
 const float threehalfs = 1.5F;
 
 x2 = number * 0.5F;
 y  = number;
 i  = * ( long * ) &y;                       // evil floating point bit level hacking
 i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
 y  = * ( float * ) &i;
 y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//      y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
 
 return y;
}
Method Time
Quick Square Root ~25 000 000/s
asm_sqrt ~30 000 000/s

I can do thirty million sqrts a second. Or I can choose the wrong node eighty times and spend countless milliseconds hitting the A* open list. HMM!

JPS: Straight Line Jumps

A straight line is pretty simple. The JPS algorithm basically says keep going forward unless there are obstructions. Then you stop. Seems simple right? Well actually there's a lot of checks per square you need to do before you "jump" to the next square. Is the next square an obstruction or within the map? Is the next square the goal node? Are there any "forced neighbours"? Okay, NOW you jump. The number of checks is very significant.

That's not the worst part though. An unstated problem in JPS is that the jumping doesn't stop.

It doesn't look so bad here. We checked seven squares and then determined that this has no jump point successors. Therefore nothing gets added to the A* open list. Fantastic right? Except that in non-vanilla A* with a reasonable heuristic, I would have never checked all but one of those nodes. So what would have been the cost? Nearly nothing. But, with vanilla JPS, I've run through a "jump" check for all seven nodes. And it gets worse with map size. Cultura has very large maps but even something like a 90x90 test map, I'm nearly running 60-square checks for every straight line jump.

These checks can't be skiped. In order to preserve correctness we must do every square. However, you may not need to perform a full jump.

JPS: Diagonal Line Jumps

In JPS, a diagonal line jump is the most frequent kind of jump you want to do because very rarely do you have a straight path to your goal node. However, the JPS algorithm does an extra step to ensure correctness/optimality for diagonal jumps. Every square you jump forward you must also check the straight line jumps that come out of it.

These straight line jumps have all the performance issues as a normal straight line jump because they're the same thing. And notice they can't be skipped otherwise you might miss an optimal path. So for every square a diagonal jump can go we add two straight line jumps. The number of checks grows very rapidly. For a map such as 90x90, each straight line jump can be 50-60 iterations of the jump function each one consisting of 3-5 checks. Now imagine a reasonable map in Cultura, like a 500x500 map or a very large one like 2500x2500, a straight line jump can be 10000s of checks. So a diagonal line ends up being hundreds of thousands to millions of checks versus just a few in A* with a heap sorted open list. JPS becomes insanely slower.

Jump Point Optimizations

What do?

Order of Operation

Let's consider a few situations:

We could have a goal node accessible through a straight line path. We could have one accessible through a diagonal path. And we could have one accessible by neither.

The first step in JPS is to "prune neighbours" before deciding to figure out the jump point successors. That means we're trying to figure out, from the current node that we just pulled from the A* open list, which directions we should attempt to jump. We can immediately identify that if we're in a straight line path (the x or y value is the same as the current node) then we should see if a straight line jump works. Therefore we should prefer to check the straight line first. Otherwise, let's do the diagonal first because the straight line can't possibly hit the goal node; only a diagonal can. Obstructions can change this but the algorithm already accounts for this.

In practice this means using a deque to store the "pruned neighbours". We push front for the jumps we want to check first, push back to those we want to check second. We are preferring to look at jumps that have a chance of hitting the goal node first.

Of course this is only useful with an early exit. If we find a path that hits the goal node we are using the properties of A* and JPS to exit early from the jumping. We have found a path to the goal. Exit now and let the A* handle whether that is optimal or not. If not? It won't be analyzed again. If it is, we found a path and we can return it immediately. Due to the properties of A*, any other goal path can only at best be of equal length.

Delayed Diagonal Checks

A diagonal path needs to make a straight line check every step of the way. But, if the diagonal path can just simply take you to the goal node (because there were no obstructions), the question is: who gives a shit? The answer is nobody. You got an optimal path, you have an optimal path. Use it!

Rather than make a straight line check every step of the way, as stated in the original vanilla JPS algorithm, just delay those checks only when the diagonal path fails to yield a path.

Overrunning the Goal and A*

When you're using a heap for the A* open list, an insert is O(logn) and popping is O(1). Is that expensive? No! But it is more expensive if you didn't have to do it. JPS is meant to reduce the number of open list checks but that's not useful if the "jump" function takes so ****ing long that the heap inserts and pops were cheaper. What's the answer? Leverage both.

Whenever a jump overruns the goal node, just exit out and return that as a jump point successor. Let the A* algorithm figure out whether it should bother to keep going. The cost is cheap. Imagine a 2500x2500 map. You could do a million checks before realizing this jump is not useful. But A* would have known that far earlier, skipping so many checks that it was much much cheaper to have just simply inserted this into the open list. It's a heap, big deal. It'd have to grow to enormous sizes in order to be a problem.

Have a Path, Use the Path

Whenever we find that we have a path with a goal node, we immediately exit out of finding further jump point successors. The properties of A* will guarantee that we won't use this path if it is not optimal. But we can't tell if it is optimal without going to A*'s algorithm. This avoids the need in JPS to do pointless diagonal or straight line jumps, which again, have a significant cost to them. Inserting a potential goal node into A*'s open list and immediately checking its validity saves significant computation time (a single logn insert versus potentially 1000s of jump checks on various squares).

What's Next

Right now we're running at around 120 solutions for ~60 length paths in a 90x90 map per second. For the pathological case of thousands of units operating at the same time attempting to do pathfinding we would want something around 500-600 solutions per second. We can pursue a few other options: precomputation, caching calculating paths, using greedy whenever possible, reducing function calls and other super-optimization of code (right now the code is very pretty and laid out in OO manner).

I'll be taking a two week break from coding this so that is where I leave the pathfinding state in right now. This is a working real world example of using A* and JPS. I'll likely post up the code (as useful as that may be for people making games with completely different data structures, passability rules and so on), when I'm at the efficiency I'd like to be at for the pathfinder.

Sunday, August 10, 2014

It's a Bug Hunt also Everything is a Strawberry

Much like the Colonial Marines, sometimes you just got to go on a bug hunt. Cultura is at an alpha stage. You can do things and these things probably have bugs or crashes. I'm here to get rid of those bugs using the power of my pulse rifle.

Right now, there's one glaring issue that will slowly get worked out with some placeholder graphics and dummy test values for growth/resource count; everything is a ****ing strawberry. Why? I don't have the graphics for 99% of the resources in the game and also they don't have their values properly set yet. So most of the resources look like strawberries and I'll have to slowly replace everything to get it to a reasonable test state (and then later replace those graphics).

Anyway, the easiest way to talk about what's going on is a changelog:

  • Added a cost to a cave so that it is a buildable structure
  • Placing buildings respects territory ownership
  • Create open area at start location for a starting cave
  • Added a cave
  • Harvest node or animal respects territory when deciding drop off point outside of a storage building
  • Removed silverleaf and replaced with darkwood
  • Added graphics and basic resource information for all eight types of wood, at least wood will stop looking like strawberries
  • Fixed resource node generation, was only making the last item type of each resource node type
  • Fixed resource node generation which put nodes on top of each other, passability map wasn't being updated properly
  • Added Jump Point Search to help with pathfinding performance
  • Fixed world generation of animals, unit ids weren't added to nature faction

Lingering issue: Pathfinding is toooooooo slow.

Another lingering issue: Everything looks like a strawberry. Hard to tell things weren't strawberries. People starved to death due to this.

Here's a screenshot of the current state. Some test graphics and also test graphics for the border.

Sunday, July 27, 2014

Create Me A World

Random world generation is in. The architecture is built. Test functions thrown out. Hostages rescued.

Right now the "random" world is a gigantic flat plain of grass. Faction starting points and animals have been thrown in but overall there isn't much to see. Everything needs balancing. Resource nodes have to be added. Starting caves have to be thrown in. Maybe I might add some starting resources, not sure about that yet.

Figure 1. Invisible everything.

The main point here is that since the world can be generated, it's a matter of filling it in. There's some algorithms I might explore. I'll explain in more detail once I put some real maff into the code. Maths are good.

Wednesday, July 16, 2014

Red Pottery or Orange Pottery or Slightly Reddish Orange Pottery?

Items

A big part of Cultura is about the consumption of goods: property, consumables, food. Then there are tools and military items. With many planned items with variants, how to turn this into something that's understandable for a player? So let's start from the beginning. What do you consume in Cultura? You've got people and every day that passes they eat consumable goods and food. At the same time they enjoy bonuses from property they own in their homes.

Excellent. Materialism is complete. Or is it? Let's say you got an item like pottery. This takes an item called "earth" to make. So far so good. You mine some earth. Put it in a workshop. Workers and slaves poop out some pottery. You put the pottery in a home. Then you enjoy that pottery. But, earth has several variants. Maybe you're getting feldspar, or maybe you're getting red ochre. Those are two planned types of "earth". Although, I will admit, using red ochre to make pottery is going to be tough. In any case, what if you used red ochre instead of feldspar? Then you have a red ochre pot. If you use feldspar then you have a feldspar pot. Are these different?

In Cultura, yes they are! You get bonus from every unique type of item. Pottery made from different materials are considered different. What happens if you have same pottery? If a person has two red ochre pottery then she only gets full bonus from the first. Any subsequent one only gives half the bonus. That's simple and encourages variety.

Okay what about tools and military weapons? That's a bit different from luxury goods. Sure it might be cool to have oak furniture and then also have pine furniture in another room. It completes that missing part in my soul where I yearn to have every kind of wood in my house. That is a thing. But when it comes to military weapons what you care about are RPG stats. How much DPS, eh?

In this case, they take a different approach. Tools and weapons instead can use any number of materials but have no "base material" after it is constructed. Whether you use flint or chert to make your stone chopper, it doesn't create a different item. Instead, the more types of material you use then the higher the level of the item produced. So if you use only flint, then you have a level one stone chopper. If you use flint AND chert, then you have a level two stone chopper. Pretty simple and works well with tools, armour and weapons.

The level of complexity here is somewhat inbetween Dwarf Fortress (any item can be made out of any material or in fact a bunch of alloys and that affects its quality) and Anno (all items can only be made in one way thus there is no way to differentiate them). This "variation" allows for trade between societies making the same item but it's not so significant that close neighbours might not be producing exactly the same good. In that case, they're more likely to trade completely different items (I give you oak furniture for deer leather clothing).

Saturday, June 28, 2014

Productivity

Buildings and Tools

As part of the game design process there's some decisions to be made about industrial structures and tools that help your people make more stuff so that they can consume more stuff in their evil capitalist materialist consumerist lifestyle of reckless abandon.

Tools

Tools cost a certain amount of resources to make, they last a certain amount of uses. This means it's more efficient to use them in conjunction with an industrial building. Then they break and must be replaced. This helps speed labour and of course the bonus must be balanced against the cost of the tool. By reducing labour time this frees up food (because labour time could be calculated in terms of the food that was eaten).

Their bonus is simple. Tool increases production speed and reduces labour time required.

Industrial Buildings

An industrial building takes up space and requires fuel. The kind of fuel changes with technology. This cost is balanced against the reduction in consumption of inputs and an increase in the amount of outputs. The building lasts forever but has high sunk costs.

First, it improves the ratio of input to output. Say you want to make pottery. If you have no building it costs 100 slip to make 1 pottery. If you have a firing pit it takes 180 slip and 10 lithic fuel to make 2 pottery. That's a better ratio. It takes the same amount of time but since you get twice the output, really your productivity has doubled.

Fuel

I've been wrestling with how to make fuel "simple". One issue is that you can effin burn anything. Let's power your evil firing pit with everything from orange peels to old people! Okay, maybe not orange peels. In any case, since so many things can be "fuel", how do I want to define it in game? My current design idea is something like this: there's a good you can make called "lithic fuel", this is the simplest fuel you can make. However, you can make the generic lithic fuel out of many different inputs. So you can select which items are allowed to be used in your lithic fuel industry and then your assigned workers automatically choose the "cheapest" (which would probably be interpreted as the "most abundant") input possible and then create lithic fuel from that. So lithic fuel could use "wood" or "filler" or "bones" or whatever.

However, perhaps the better industrial buildings then require something like "coal fuel". This has stricter input requirements. Now you can only use "wood" or "coal" (which sadly isn't in the game right now, but perhaps a future iteration!). As a side note, the early steampunk tech route is likely to just mirror China because their ancient technology is pretty much steampunk (they had blast furnaces for thousands of years before Europe). That or Greeks if they hadn't wasted all their technology as toys while using mass slave labour.

So the main issue here is that it makes the coding a bit tricky. While most of my goods have only one possible kind of input, fuel has several kinds of possible input. But, I've introduced a concept called "item super id", in addition to an "item id". So what I can do is have 3 or 4 different item ids that say "lithic fuel" and to the player they'll see they have several kinds of lithic fuel. They'll understand why they're in different bundles because it'll say something like Lithic Fuel (switchgrass) and another will say Lithic Fuel (oak). That's understandable. They can then have matching super ids, so that the "firing pit" will require the super id of "lithic fuel super category" which all of those different item ids fit in. Voila! Solved my code problem. With more ids.

Occupancy

Another aspect is how many people can live in the same structure? Originally I was going to do a flat "2 people per room". But then I thought "hmm maybe a bedroom can fit more than say a storage vault". So I'm introducing the concept of occupancy rate per room. It's pretty simple. Go beyond the rate then the family suffers some penalty.

One of the estates that a family owns is considered the primary residence. They get a base health/happiness bonus. If the family exceeds the occupancy rate of this estate then they suffer a penalty for every person beyond that to their health and happiness. Very simple.

Animal Growth

Trying to keep this one simple as well. Animals are born during their birthing season. The rate depends on the herd size. Outside of the birthing season, their numbers decrease to the maximum. The maximum herd size is determined by how many plants (if herbivores) there are in the land region or animals (if carnivores). Best to slaughter animals beyond the max herd size just as it leaves birthing season.

Friday, June 27, 2014

Alpha Time

As Cultura head towards a playable Alpha it's time to lock down some of the game design decisions. What has been influencing the entire process has been a focus on:

  • Simplicity: Can the user understand what is happening at a glance?
  • Simulation: Is this a reasonable simplification of real life?
  • Longevity: What is the future path of this game element and is it fun to keep pursuing it?

That's a sort of rough list of what the factors are in saying whether a game element stays, is changed or is dropped.

UI: I'm leaning towards a "total" rather than location UI. It shows you what you have in total in the top right (just a few of the relevant resources or maybe I can splay the 15 resources across the top). Commands you give are carried out by government employed workers (eventually in a sequel there'll be private market). There may be a secondary advanced layer, which requires one additional click, for tweaking at the building or individual citizen level.

Buildings: There'll be probably just a simple set of five main buildings for residential purposes that allows the consumption of goods (consumable and property). They revolve around how to improve health and happiness. Then there are infrastructure buildings like work sites, roads, irrigation and walls. And then there are industrial buildings like mines and farms (maybe JUST mines and farms). These would pop up in a radial menu... probably by pressing "b" for basic buildings, "v" for industrial buildings, "x" for infrastructure buildings. Then perhaps a hideable bar for the same buttons at the bottom of the screen.

Additionally, buildings are built room by room. Doors are the connection points. You mush rooms together to form larger buildings. Each building can only be owned by one family. Ownership (for now) will be automatic. In the future, I'd like there to be an advanced assignment UI (especially if you are an evil dictator trying to form different classes of citizens, some should get better housing than others).

Goods consumption is facing a few changes at this point. There was the concept of consumable and property, where they were equal in health/happiness benefit. I'm going to change it such that property lasts longer, costs less resources over the long run but has high initial costs. That way consumables and property represent a trade off between short term gain and long term gain.

The environment will be separate from artificial structures (though not entirely realistic). This means there can be wild trees, plants and grasses and they grow, you can harvest them and they will regenerate. Same with animals (they'll run around and you can hunt them). Farms and pastures on the other hand require input (labour, maybe water, perhaps some other stuff) but are upgradeable to produce at a higher rate than nature (thus increasing per tile food productivity).

Consumption is automatic. You give orders to produce goods per industry, work orders for a specific amount of a particular good. This UI would be simplified so that you just give one general order for your whole society. I'd like it to be more advanced but that may make the UI too cluttered and I don't have a good solution to that yet.

The world will be designed such that each season represents a consumption of different resources so that there's always something interesting to do (especially during the stone age). As you shift into agrarian (in some future version of this game) it'll change into a more planting/do nothing/harvest rotation and you choose what you might want to do in the "do nothing" phase (like wage war as if you were the Romans).

Interesting diplomatic relations. This is a lot more about making believable AI and on top of that they would give you verbal cues to the rationale behind their actions. That way if they were to do something stupid on purpose, they inform you of this, so that you know. In this way it prevents the "do not dumb here, not dumb area" feeling. Hopefully. Needs some playtesting.

Tuesday, June 10, 2014

Spreading the Resource Butter

As the game gets inexorably closer to the stage wherein one collects raw resources, converts them into finished goods and then eats them in order to feed a hungry faceless mass of labourers whose only purpose is to reproduce in competition to other faceless masses of labourers, we get closer to thoughts on the world generation. For a game like Cultura one expects procedurally generated worlds (ie. random). That leads to a lot of questions about how to place resources, initially seeding the starting points of different peoples and how might biomes/climates work.

The general status of the game is that the consumption of food, consumable goods and property items is in! Seeing as how those are fairly complicated state machines, there's a lot of testing that needs to be done (and then bug fixing anything wrong that is found). There's also the delicate issue of balance but that comes later. It's an exciting time. The general idea is that food is pretty obvious (make food, eat food) but there will be a balance between consumable goods (consumed once, get a bonus) and property items (needs repair over time but get a better long term bonus for the cost). So your society's economy is a balance between short-term and long-term gain.

But, let's get back to world generation. In the world of Cultura it is powered by the "This Makes No Sense" resource engine. Essentially, the resource system boils down to fifteen different raw resources: wood, stone, earth, grain, meat... etc. For each type of resource there are eight different types of materials for it. As an example, wood could be pine or oak or ironwood. This allows you to create the same product between two different societies but use different materials and you can then trade these different goods. Bonuses are based on the consumption of a variety of materials (every material type consumed for a good it's a multiplier bonus). So an oak chair gives you +10 happiness. But an oak and pine chair would give you +20 happiness. I know that when I go home to my table made out of six different kinds of stone I get six times the happiness from it. Don't you?

The placement of each type of material is what matters most. So for the most simplistic version of a world generator, firstly it would build out where land exists. Everything in Cultura right now is flat (there are mountains but basically they're just rocky obstacle walls). Then the world is divided down into eight regions (or four regions). Each region is then claimed by a single material type (or two, if there are four regions). The selection is random. One part might be pine and then another might be oak. This process is repeated for the fifteen different types of resources each with differently shaped regions and so the overlap of resources varies. Some areas might have pine and unicorns, another might have silverwood and deer. It's random.

Now of course this isn't a super realistic resource placement but alas one developer can only do so much in order to actually finish a game within his/her lifetime.

You: Why is there pine near the equator? Shouldn't it be in the colder regions of the planet?

(ノಥ益ಥ)ノ ┻━┻
Me: Why is your table flipped?!

You: :(

There's a very large wish list of my own that I would like to eventually include in Cultura but all in due time! For now, I'll just discuss what I think is minimally necessary for the game to be fun and realistic enough. The main point is that different regions have access to different resources so that trading in the initial era (the lithic ages) is predicated on the exchange of different goods. As societies advance (and sequels to the game are made), they'll be based more on comparative advantage due to labour skill, non-residential capital investment (it'll be more fun doing in the game than what that sounds like) and education opportunities. For now, just an even spraying of resources across the world shall suffice. As a side bonus, it makes balancing a lot easier.

Sunday, June 1, 2014

Four Focuses

Work has been done, the latest aspect is property items. These kinds of items are stuff you stick into slots in a family's home and then they enjoy health/happiness bonus from it (spread evenly to every member in the family). That's on-going. Another on-going aspect is the graphics engine. Needless to say, a game needs a good graphics engine to be graphically nice. There's some technical thoughts on that but until it comes to fruition, it will be written about in later posts.

But, what of Cultura as a game? The total game design is coming along and let me take you along that journey. For a game as broad as Cultura, one problem is trying to bring it back together into a neat little box of designed fun. You want the game to be wide open, sandboxy and capable of creating unexpected situations. The emergent aspects. On the other hand you want it to be understandable at a glance, to have a low barrier to playing it so that you can say, I'm going to play for an hour and I can just dive right back into the game.

The whole of Cultura has been split into four neatly laid out focuses in the game that explore the whole of the setting that is displayed to you in all its glory.

Ecology and nature is the most apparent. You start off in an open world with different trees, plants and animals out there. Some you can eat, others you use for producing luxury goods. One of the big concerns in Cultura is the "carrying capacity" of the land. Trees grow, animals are born but at a rate determined by different factors. For Cultura, these factors are simplified. Until there's a "realistic mode", the simulation model is fairly simple so that a player can understand it quickly and adjust to meet social needs for short and long term goals. Forests grow based on the number of still standing trees. Most plants grow just the same, based on the number that exist. Animals grow based on the number of animals but the herd starts starving if it runs low on the number of plants in the wild. So maybe you think you're harvesting "glowing nettle" and it's fine, until you realise you're starving out the local deer of their food source and the herd dies out.

It'll be prominent and direct. The interface will show you each land region. Each land region lists the resources available in it. It shows you the rate at which they grow and what affects the growth rates. Then it's up to the player to decide how to handle that.

As the name would imply, Cultura revolves around culture and that's the biggest core focus as you play. Technology and cultural traits are thrown together like a bunch of miniature skill trees for you to pick and choose to develop the aesthetic feel of your society and also the play style. Most of the technology revolves around improving your industry (industrial buildings, tools, lifting resource extraction limitations), expanding your repertoire of goods you can manufacture (choosing between goods built from each kind of resource, or different high level goods, to build a particular aesthetic feel to the kind of luxuries your society makes), expanding your ability to consume (more or better structures to build), government policies (different ways of performing taxation and also ruling over a larger empire). Cultural traits revolve around social values to adhere to a particular play style. Choosing values that favour war and military, being able to hold Roman-style triumphs, would benefit an aggressive player who wants to gain happiness bonuses from going to war. Or you can choose a pacifist route where you can agree to unfavourable peace treaties yet still gain happiness in your society because your people abhor war so much.

Technology is very specific and the cultural traits you choose are very specific. They allow you to shape your society however you see fit. A militant raider society that produces wood carvings and yarn dolls. A trading society that produces stone axe heads and stone-tipped arrows. It's really what Cultura is all about.

Then there is industry. Handling your resource extraction and manufacturing. The focus is on how much resources you consume, how many goods you produce and whether your goods production matches your population's consumption. You can shore up missing goods through trade. You can over-produce specifically to sell the goods to others. The focus is on setting up new industries, expanding current ones and managing labour distribution. You can have seasonal industries (hunting after an animal herd's growth period). For the first iteration of Cultura, it's about making things for your people and trading the excess to others for things you don't have.

Finally there is diplomacy. This is the most emergent aspect of the game. Are you surrounded by aggressive barbarians? Is there perhaps a trading empire close by? Maybe there's a lot of weaker societies but each of them are more adept than yours at producing particular sets of goods. You interact with them for trade, treaties or war. Trading and raiding are the two most important interactions with other societies to gain goods you cannot produce or do not have enough of, and your choices depend on the total interaction within the world.

Diplomacy and trade are combined and they occur along trade routes. Convoys move back and forth between societies to deliver diplomatic messages, treaty proposals, trade agreements or just the goods you already agreed to trade. But, of course, you can always choose to forgo such polite diplomacy and opt for raiding and as your society becomes more advanced, waging war!

This is a lot more focused version of what Cultura will be about and it gives players a more clear-minded way to approach the game. It leaves the sandbox nature there (you can choose to interact with nature and people however you wish) but displayed in a clear way. Imagine, you have a land rich in iron but low in wood. A neighbour is rich in forests. Do you raid them for their wood using your superior metal-based weapons? But then others might see you as aggressive and refuse to trade with you and you haven't the military to attack them all. They provide valuable goods like wine and fruit juices to maintain your empire's health. You make your choices and live with the consequences.

Tuesday, April 29, 2014

Eating Ochre Dye and Too Much Pottery

Consumption Type

Ever fathom the consumption type of a good? Cultura has! Bread? That's food. Ochre dye? That's a consumable good. Pottery? That's a property good. Polished gold rocks? That's super property. And it just so happens it finally made its way into the code base. The consumption type that is. No more eating ochre dye or smashing pottery into faces for good fun. That might look a little wrong to the player so it was decided by the Design Gods that it should be changed.

Food is eaten to prevent starvation and food must be eaten each day. The bonuses gained from food (usually health) last for seven days because that's the arbitrary length of time that was decided. Eating the same kind of food confers no additional bonus. Consumable goods when consumed confer a bonus and immediately disappear. The bonus lasts seven days. Property goods are placed into slots in a family's home. A home is comprised of different rooms, and so buildings are built room by room by the player. More slots means more property items that can be enjoyed at the same time. Once a slot is filled it spreads its bonus evenly across the people in the family. Property requires repair over time. Probably every seven days.

Collecting Goods

Once a day each person queues up actions to eat food, collect consumables and another to collect property goods. The one issue has been the hierarchy of the actions. If placed at the individual level, the actions of eat food and collect consumables works out fairly okay. Everybody needs to eat and everybody would like to consume as many goods as possible. But for property, you only need to fill the slots or repair damaged property. So if every person queued up such actions you'd end up with too much pottery. Too much pottery is a problem that exists in Cultura.

One solution is to have an action queued up at the family level (similar to faction level actions) so that the family needs it completed but it doesn't really care who in the family does so. That way it only doles out enough actions to individuals to meet the exact demands. It's possible to also shift collecting consumables up to this level. This is useful for maintaining a family budget when private markets are introduced into Cultura. At the very least, the code needs to be able to handle it if not do so currently.

So, hopefully in the next update you will hear how pottery has been enjoyed by the residents of Cultura. In fact you might consider that since they no longer consume pottery (presumably by smashing it into their faces and then laughing) and instead enjoy pottery in their homes what has been done is aesthetic pleasure has been hardcoded into the minds of Culturans.

Saturday, April 19, 2014

Importing Minor Annoyance, Exporting Death

Diplomacy

One of the more fascinating properties of economic games are emergent properties. Think Dwarf Fortress and it's physics system. So with Cultura, where does that come from? It's the AI factions. So here are some thoughts surrounding the diplomatic angle of the game.

At the very beginning there's few options. Nobody can speak with each other and there's no common language (or much of a language at all). It's all zug zugs and dabus. But the diplomacy will be styled after three factors: Prestige, Reputation and Relationship. And from that comes different kinds of relationships that work on two principles: type of time frame and type of exchange.

Prestige, Reputation and Relationship

Prestige represents the power of your society as perceived by others. Reputation represents trustworthiness. Relationship represents the summation of interactions, positive and negative, between each society. Prestige and Reputation is global. You will seem just as powerful to everyone according to your prestige rating and much the same, your reputation is global. Break a treaty with anybody, everyone sees you are a treaty breaker. Relationship however is between each nation and so while you can be seen as weak or untrustworthy by someone, they may still be your good friend because their relationship score is high.

Reputation is the primary vehicle that promotes the honouring of treaties and oaths. Breaking an oath damages reputation and causes global damage to your ability to craft future deals. Your friends will still like you but those who know you less only have your reputation to go by and thus will discount your offerings to them. It's very much like losing face in life. You can only lose face, you can't gain it. So damage to your reputation cannot be fixed by anything other than waiting it out for people to forget and see that your newer dealings are trustworthy.

Types of Treaties

However, the more interesting part is the kinds of treaties you can make. There'll be the usual neutral ones of "don't breach my territory" and also "territorial claims" (which are less neutral). But for the ones that define the relationship with another society, these go down different paths with increasingly more powerful treaties much like leveling your relationships. Maybe you want to seek a deep friendship, perhaps you want to be the most powerful badass barbarian horde or you want to be the imperialist dynastical China. I'm quite sure dynastical is a word. Don't look it up, just use your gut feeling.

The way the relationships are organised is based on type of time frame and type of exchange. For time: An exchange of presented goods OR an exchange of future goods OR a contractual renewable agreement. So for instance, if your emissary takes 300 watermelons to the neighbouring Boogaloo tribe, then they can only trade the 300 watermelons for whatever the Boogaloo have. A future exchange is to promise to send what you did not present. A contractual agreement is the ability to continue to trade without having to again speak with the neighbouring tribe.

For the type of exchange, goods have roughly been divided into three categories. Tangible goods are objects such as food, consumables, property or super property. Tangible social goods are objects such as military recruits, slaves or labourers. Finally, intangible goods are prestige, reputation and relationship.

The paths roughly go down that of War, Power and Peace. I may add a fourth, which is a different way to pursue peace (seeking alliances versus seeking amalgamation). So as examples of types of relationships: Within War you could choose Subjugation where the defeated party agrees to a supply of tangible goods, or there is Conscription where the defeated party agrees to supply tangible social goods. Or you could seek a route within Peace: representation relationship, an exchange of intangible goods for tangible social goods. The main design will be a relationship that starts off simple but expands in options (a wider range of goods and social goods you can offer for a wider range of goods/social goods in return).

Thus allows the diabolical machinations of the evilest players. Or AI.

Thursday, April 17, 2014

Spawning the Trees

Tree Seeds and Simulation

In the real world a tree grows new saplings in a number of ways: seeds carried off by wind, dropping seeds nearby, birds eating seeds and dropping them elsewhere or fruit eaten by animals and pooped somewhere else. Poop is really really important. In fact, human caused extinction of megafauna has caused serious ecological problems due to lack of pooping by the big animals. Anyway, rather than a full simulation in Cultura (although one day I hope that there is a checkbox in the game to have it run in full simulation mode versus game simulation mode), it has a very simple heat map to decide where the next tree grows.

But wait! How do we decide when something grows in the first place? Well, we head off into XML land where all the resources are defined. A particular material such as Pine has stats that say "you grow during winter, at a rate of 100 wood per season and start off with 200 wood". Then when the game is in winter, every Pine tree grows at 100 wood up to 200 wood. That's for level one pine trees. Resource nodes can be upgraded if you get the right technology thereby increasing the ecosystems carrying capacity for your society's greater consumption at its later stages. So then when a Pine tree reaches its maximum capacity for wood, it then adds any additional growth to a tracked spillover variable. When the spillover goes over a certain threshold a new tree is born!

Okay so where to put the tree? Well here's the simplest way. We put the tree at any square with the highest number of similar neighbouring resource nodes. We'll want to track the objects via what is basically a priority queue, with the most important queue being the list of locations with the highest number of neighbouring resource nodes.

  std::unordered_map<std::pair<int,int>, std::unordered_map<int,int>, hash_int_pair> m_heatMapByLocation; //location to (material id to neighbour node count)
  std::vector<std::unordered_map<int, std::unordered_set<std::pair<int,int>, hash_int_pair> > > m_heatMap; // neighbour node count to (material id to location)

And it's very simple, we just choose the first location with the highest number of neighbours because "good enough". Really, it's just a matter of whether it looks right to the player and only in full simulation mode (which probably won't be coded for a long time) will the game care about doing it how it is done in real life.

std::pair<int,int> CLandRegion::getFirstHottestSquare(CGameState* gameState, int materialId)
{
 for (int i = m_heatMap.size() - 1; i >= 0; i--)
 {
  if (m_heatMap[i].count(materialId) < 1 || m_heatMap[i][materialId].size() < 1)
  {
   continue;
  }
  else
  {
   for (std::unordered_set<std::pair<int,int>, hash_int_pair>::iterator iter = m_heatMap[i][materialId].begin(); iter != m_heatMap[i][materialId].end(); iter++)
   {
    //todo: different passability for special resource nodes, such as in rock or in water or shallow water
    if (false == gameState->isPassable(*iter))
    {
     continue;
    }

    return *iter;
   }   
  }
 }

 return std::pair<int,int>(-1,-1);
}

Tuesday, April 8, 2014

Eating Goods and Enjoying Food

Joys of Consumption

The ways of Cultura is to be materialist and be satisfied on consumption! In that vein, Goods Consumption has been added to the game. During day time the people work all live long day. When evening hits, they throw down their hammer stones and antler scythes (hmm... antler scythe is too advanced) and enjoy a rousing session of smashing ochre dyes onto their faces. This gives +5 happiness.

Consume Goods is a horrific state machine, as is Eat Food, both of which are foisted onto a unit once evening rolls around. Eat Food lasts forever (if they can find something to eat, they try to eat it but if they find nothing the action ends and they starve), but if the next evening hits the starvation counter increases (in case they are somehow capable of finding and eating food but it took them so long that a day passed before they reached it and ate it). For Consume Goods, they attempt to consume as many goods as possible during the evening. Once the next day rolls around, they stop and go back to working.

Where is sleep you ask? For now, Consume Goods doubles as sleep because you can't tell them what to do during this time period (although I may consider the idea of cutting into luxury time to produce just a bit more at the cost of happiness).

Each good or food has a bonus associated with it. For instance, ochre dye gives +5 happiness. Bread gives +5 health. This bonus is per material that the good was constructed with. For instance, bread made with wheat gives +5 health. Bread made with wheat and oats gives +10 happiness (+5 x 2). The number of materials you can put into a good is limited by your technology. And, everything a person consumes lasts seven days. So if you eat bread with wheat, you get +5 health and that lasts for 7 days. Although with food you have to keep eating or you starve, whereas with goods you can enjoy yourself a nice rock of handful ochre dye and not need to play with a handful again for another seven days. Amazing!

Monday, March 31, 2014

Tasks!

There's been progress on having people consume goods in Cultura. So far there's eating and starvation. Next there will be consuming goods. There's three kinds of goods in the game: consumable, property and super property. Consumable goods disappear upon consumption. Property requires repair over time. Super property requires no repairs. The exact balance hasn't quite been determined yet. It'll all be about timing it so that it feels right. Whatever "right" means.

The people spend most of their time doing their jobs. These are the tasks you assign them through a labour management system or you click on them and tell them to do things and then they do it. They follow your command because it is the paleolithic age and you're the guiding spirit. In later stages of the game they do it because you're the voice of big government micromanaging their lives to the last detail. But during this time period, they essentially do things that you want. Once day time is over, it becomes evening time, and they do things for themselves. While I haven't decided whether you can interrupt happy time (to get an extra bit of work out of them), this is when they eat, when they enjoy life and consume goods.

During evening, the eat food action is put on top and then followed by the consume goods action. Individuals do not need to do anything to enjoy their property or super property but they do need to actually spend time to enjoy consumable goods (and later iterations will have mass goods such as visiting a museum). So in essence, during the evening, eating food and consuming goods takes precedence over user commands. Is that good? Waits to be seen. This forces the player to either give them goods to enjoy to boost health and happiness, or suffer the penalty of idling people.

On a small note, I've changed the way a suitable square is detected for placing a resource pile. This prevents them from being placed within other buildings. That was a problem.

Monday, March 24, 2014

Walking and Pathfinding in Cultura

Passability Map

It's a common problem in gaming and thus a wheel that has already been invented. How to figure out where you can walk on a map when some squares are impassable? Well, here's how Cultura does it and it's nothing fancy.

For each tile in the game there is an associated 32-bit integer which describes the passability. How to read this integer? It's a bit map. We can set various values. In general 0 means nothing is there and thus is definitely passable. We could set the first bit meaning there is water there... only units that can pass through water may go through it. And so each type of terrain can have an associated passability flag.

In Cultura, this passability map is only updated when you construct buildings (which likewise use the map to figure out if your placement is valid). Many parts of a building are passable (for example, a floor!) and some are not (for example a wall). Then there are doors.

The main rule is nothing can be smaller than 1x1. In that way there's no walls or doors smaller than 1x1 the pathfinding algorithm can simply look at a tile and state whether or not a unit can walk on it. Very simple.

So now all buildings are 4x4 structures, the outer is a wall, there's a door and the inner 2x2 area is walkable floor area. Hooray!

Saturday, March 1, 2014

How babby is formed

Food, Health and Reproduction

In the world of Cultura, the healthier your family then the faster you get more children. Healthiness is based on the food/goods consumed by a person. So far food consumption has been coded and health is properly added to a unit. At the end of each day (for debug purposes it was shortened to a matter of seconds), excess health is added to a family's birth progress meter. Once it fills up, a person is born and the meter resets!

Children are born with the characteristics of their parents, randomly chosen. The sex is also randomly chosen. For now it is using C++'s rand. Not exactly random but close enough for now. So this means if parents are an ogre and an elf, you might get an ogre or you might get an elf. If one is purple and the other is green, you might get purple or you might get green. I don't do anything complicated such as recessive/dominant genes and mixed alleles and whatnot. The purpose of this game isn't biology, it's culture! However, if the parents are from mixed cultures I am currently unsure what to do but for now the child will randomly pick one culture. That's for the purpose of ethnically discriminatory policies that societies might engage in... when I code that in.

The next step in the game is figure out how children break off from families and form new families (and whether to track the parent family). This might become important if I wanted to code in family dynasties. For example, a Roman Equites would care a lot about his/her children and parental relationship is through the son/husband. Or Chinese families would create estates in a similar manner with related families allowed to be in the same estate and utilize the industrial facilities there to earn money. But for now, we'll just worry about family creation with children.

Starvation is tracked and while there is no ill side effects coded, eventually it'll be decreasing health until death for each day without food. It's important to have both good feedback to the user about how much starvation, who is starving and how close someone is to death.

Bigger Buildings

Buildings in the world of Cultura are component based, meaning you build rooms and attach them to each other and that creates a singular building. I haven't put in rotating buildings and what not but the idea is that if you rotate a building so that it lines up with another building that determines whether it connects to it or not. In addition, all buildings are now 2x2 in size. I don't think there'll be anything in the early stone age portion of the game with different sizes but certainly when building more fantastic stuff (literally or figuratively) the sizes might be different.

For now we can behold a "den", which is a building component that is equivalent to a bedroom:

Infrastructure

I had to switch off the Greedy pathfinding in the game because people kept getting stuck like dumbasses and then filled themselves in with their own filthy poop. Well actually I haven't coded poop yet so the latter part isn't possible. Yet. In any case, it is now entirely A* pathfinding but obviously with just a naive implementation the performance demands much. So I may have to turn my efforts to some performance tweaking at some point in the near future. There are two general ideas: first is to make the A* faster (as I've done before but the code gets quite ugly) and the second is to use memory to decrease the number of times I recalculate paths via A*.

Units now have graphic variant ids. These ids match across the "races". So right now there are Humans, Elves and Ogres. A graphic variant ID of 1 is the same "type" of human, elf or ogre. This means that if "1" maps to a purple-skinned male in Human, it also maps to a purple-skinned male in Elf. This was to make the reproduction algorithm simpler; I could just take the graphic variant of one of the parents and voila I got matching skin colour.

Placing structures now respect previously placed structures, construction sites, rocks, resource nodes and everything else in the way. No more magical slamming crap on top of other crap and then you can only click one of them.

Whew

With the ability to put 2x2 buildings, I've laid the ground work for developing an industry chain. You can already hunt, gather and craft. I'd like to be able to allow the user now to automate an industry chain and then subsequently consume those goods for happiness and health. That'll make the first true building block of Cultura.

Saturday, February 22, 2014

Foooooooood

Eat Food Action

The basic coding for the eat food action has been completed. The scenarios involve eating food from home, eating food from a public building and starving. Of course the easiest to test is starving and that looks to be correct. As well, the family birth progress is up and running, so any health gained from eating food will add up to a child birth.

There is an open design question that remains: should there be penalties as well as bonuses? Currently the game works on trying to continuously increase bonuses but as population size grows you require more and more bonus to accomplish the same goals (in this case, get a new child in society). Penalties implies that you could potentially lose progress, or the minimum could be zero, but there would be situations that you have to actively avoid. This might come about if I were to introduce sanitation. On the other hand, I could also introduce sanitation when the population in a land region is above x amount and then bump up the health requirements. In that case, sanitation is a bonus you have to get in order to achieve a health score high enough for a good birth rate.

Art versus Graphics Engine

I generally believe that artwork can make a big difference while an amazing graphics engine is just an interest to technical experts. In that vein, it would mean that special effects and a fantastic engine don't translate to a good game. Instead, what players expect is just a fast FPS and the rest is just the actual artwork. What matters to players is that the artwork looks good; if it's good then it's good. They don't mind that there aren't amazing graphical effects going on.

In that vein I've been experiment with various graphics and colour schemes. Here's an example below. Please note that when the game is release that the artwork will be totally redone, so this is just for example purposes:

So I'll focus on this style of artwork and also I plan to add 2-3 frame style animation for resource collection, fighting and so on.

Saturday, January 25, 2014

Cornucopia of Consumption

Food

Let's talk about food! In Cultura, one of the big aspects is the economy: collecting resources, building goods and then consuming those goods. One of the biggest and earliest ones you have access to is food and its primary benefit is health. There are two big ratings, health and happiness. Health affects reproduction rate and also prevents sickness. Happiness affects emigration and rebellions. So how does food work?

A person consumes food once a day (rather than three meals a day plus snacks like real life). Based on their previous number of meals they get a health bonus. This is calculated at the end of each day. This goes toward reproduction if the person is a parent in a family with at least one male and one female parent. If not, then it does nothing other than add to the health score of a land region.

The health score of a land region is important because a low score below the required amount can result in sickness or worse an outbreak of plague. You don't want plague.

So what kind of food and what kind of bonus?

The health bonus is based on the total number of material types eaten. There are three item types available in Cultura during the paleolithic age: grain, fruit/vegetable and meat. Each item type has eight material types. Therefore the maximum paleolithic bonus is twenty four. The number of meals tracked is seven. Therefore a person must eat foods that contain more than three types of materials each to get the full bonus.

For example, a person eats wheat bread for six days and then eats a berry pie (blackberry and strawberry). This person ate wheat, blackberry and strawberry in the past seven days. The total bonus is three health.

How to Code

So how do we record the information in the code? Right now a Unit class contains no information about what the unit ate in the past number of days.

Let's start with this:

  • Let d be the number of days to track
  • Let m be the number of materials across all item types
  • Let n be the population

Circular Array

Blogs aren't exactly the best place to display this kind of analysis but let's run with it for now. What if we tracked what a person ate with a circular array?

Complexity

  • Add: O(d * m)
  • Check Score: O(1)
  • Memory: O(d * sizeof(Item))

During add we put in an Item into the circular array. We then have to run through all previous items to see if the item contains materials that do not exist and thus adds health. If we overwrite a previous entry, then we must do the same. We check the materials of the overwritten item, run through all items and see if it is still satisfied otherwise reduce the running count of health bonuses.

Memory usage is the size of the circular array with pointers to Item objects.

Hashmap of Counters

Alternatively we can use a simple hashmap of counters which allows us to use the readily available std::unordered_map where the key is the material id and the value is a counter. Each day the health score is checked the counter is decremented. Upon reaching zero the entry is removed.

  • Add: O(m)
  • Check Score: O(m)
  • Memory: O(d * sizeof(int))

We can see that for add, every material that exists in the food being eaten will then reset the counter in the hashmap. During check score, we must run through the whole hash map and decrement counters and count. The memory usage is a hash map of counters which are integers.

Analysis

Add: Well we do the same amount of add as check score per unit; once a day in the game. If we set d = 7 and m = 24 then Circular Array has roughly 168 operations in worst case scenario while Hashmap has 24 operations in worst case scenario.

Check Score: For circular array it keeps a running count of health bonus so it has 1 operation in worst case scenario. For hashmap, it must go through the whole hash map and thus is 24 operations.

Memory: For circular array we have to keep the Item objects around because we have to keep track of what the person ate. An Item object is far larger than an integer. With d = 7, we have 7 Item objects for a circular array. With the Hashmap we have, with m = 24, 24 integers and then the cost of a hashmap. Assuming that an Item is larger than 3 integers, it's likely the circular array takes up more memory. An Item object is most definitely larger than 3 integers if you were wondering.

Given this analysis I think I will go with a hashmap. It is quicker to implement and I'm not seeing much gain from the circular array (except that it's cool).

Sunday, January 19, 2014

Cutting the World

Land Regions

Land regions have been coded! What does this mean? The world is cut into a fabric of different land regions. The intent is for landlocked regions, mountainous regions, coastline regions, fully ocean regions (which will have no ownership possible) and more! Each land region has its own kind of resources (trees, grasses, bushes, minerals, animals). For now, animals will stay in their own land region but some future iteration may introduce migratory patterns.

Families

Families have been introduced, tracked at the faction level, but remain untested. They allow a set of parents, adult children and children. Currently, children don't exist so any new children are instantly adults (and also, there's no pregnancy so they just fire out adults from the uterus). There are some open design issues. A progress bar to the next birth is tracked at the family level but what happens if...

  • A female parent leaves? Does she take some of the progress with her to her new family?
  • A female parent dies? Does the progress bar get reset?
  • The above two questions but with polygamy (specifically, multiple female parents)

And actually historically speaking, the usual family unit was the extended family. Grandparents, parents and children. Homosexual adults were suspected to have played the role of additional parents in a family during the early stone age (ie. helping to raise the children of their siblings). Sigh!

Pathfinding Issues

I've made terrain passible or impassible. This introduced the new problem of the greedy pathfinding algorithm no longer being 100% successful. Poop! People would dance about walls as if I coded in special spells that would allow them to pass through mountain blocks. They were wrong and they dance forever. So I introduced a basic A* pathfinding algorithm for short distance (below 5 grid spaces). Is that good enough? I don't know!

For one, the A* I coded is terribly unoptimized. You can get pretty close to linear runtime complexity (for those of you who know what that means) through a few tricks (because real world use of A* is usually not that complicated). I also chose 5 grid spaces because I intend for buildings to be about 3x3 in size. However, they'll be irregularly shaped and so I may have to increase use of A* to longer distances... which implies I may need to optimize. I'll cross that bridge when I get there.

Continuing Graphical Plague

Imagine a world where things appear partially submerged in rock or soil when they should not. I have had a few graphical glitches that continue to harass me unto the night where "blocking" is not working. A mountain square from further away appearing above a mountain square closer. Items that don't appear on top of the floor but submerged in them. I've been working through these but because the game has not been feature complete I have not put them high on the list of to do. When it comes time to showcase this game to people, these will have to be fixed. Of course so would the horrible horrible UI.

Next Stuff

I'm going to add a game clock. This tells you what year the game is. And the day. Oh and the season. It'll be useful for tracking reproduction and ecological changes (trees growing, animals pooping babies). It also means I don't need to go into debug mode to figure out what day it is in my game.

Consumption of goods and a health/happiness indicator. This is the core of the game afterall. You collect poop. You punch the poop into various shapes. You consume the poop. Then because you are materialistic, fully rational, capitalist monster this makes you both happier and healthier. It ties into everything. Healthier people get faster progress on their next birth. Happier people don't stab each other.

Monday, January 6, 2014

Build All The Techs

Last caturday I managed to complete two pieces so that I can move onto my next features (stuff listed last post such as the constitutionally appropriate family class). These two things were the tech tree UI and getting the build menu to be data driven.

Tech Tree

Cultura will include technology and for the first iteration of the game it'll cover the paleolithic and neolithic age (needless to say I have a lot of work ahead of me). The general idea of technology is that each one has an id and a level. Complex technologies have prerequisites not just of particular technologies but their level as well. This allows me to make the tool technology more interesting and have it lead off to other industries slowly. For instance, you might start with the "hammer stone" and you upgrade up to level 5 before you can move onto the "biface stone", the improved stone tool. The "biface stone", upon reaching level 1, will open up several industries. This gives a way for a smoothish transition between tools.

What I'd like is for a hammerstone to provide 20% production bonus (just an example) and then 100% bonus at level 5. Then the first level of biface stone immediately gives 100% bonus and each point gives 40% bonus instead of 20%. Given that situation, I'm leaning toward putting "maximum" levels for some technologies.

There are a few caveats I encountered while making the simplistic developer friendly UI. The CEGUI VerticalLayoutContainer and similarly the HorizontalLayoutContainer have two methods that are of interest when sizing them out. There is setMinSize and then setMaxSize. It turns out that if you don't setMaxSize on a container it has a default max size and will cut off items within it! So I had to do something silly like


container->setMaxSize(CEGUI::UVector2(CEGUI::UDim(10.0f,0), CEGUI::UDim(10.0f,0)))

Build Menu

The build menu was reduced to a single menu. Bringing up the context menu will show the buttons Build/Demolish/Management. I'm still working on whether that's a good idea but UI improvements are put on hold until all game features are done. I'll start doing the UI in beta development. Anyway, when clicking on build it brings up all the buildings that I've put into the xml file. It then checks whether the player has the proper technology. Then you can build away!

Other Stuff

One interesting thing I ran into on Sunday, the day after Caturday, was trying to get my work environment set up on another laptop. It turns out that if you do not have the DirectX SDK installed on your machine (if you encounter s1023 error upon installation it means you have a VC++ dist installed and must uninstall it to allow the SDK to install it again) you get the curious error of "RenderSystem_Direct3D9_d.dll not found". The error is a bit misleading. It's right there. The problem is that it can't find something else upon loading it and one possible cause is that you don't have the DirectX SDK. Only really relevant in the debug case.

Despair at the developer friendly graphics

Wednesday, January 1, 2014

Design All The Things

Cultura is entering into an alpha state where it'll be playable on a test map. There are a few things I want to get it going:

  • Families - Children and Marriage
  • Households - Wealth tracking, management and consumption
  • Ecology - Renewable resource growth, non-renewable resource mining limitations, climate requirements for plants/animals
  • Land Regions - Splitting the map into irregular shapes

Families

Everyone in the game will belong to a family. It's defined as a set of parents, unmarried children and children not of age. It's used to track children and births.

Births are fairly simple. For Cultura, it's a compromise with a game world to give a player more direct input into affecting how fast they can get more children. A family has a single progress bar. When it fills up, the mother becomes pregnant. Then after a set amount of time a new child is born and the progress bar is reset to zero. In order to fill the progress bar, the family must be healthy. The higher the health, the faster the progress bar fills up (excess health fills into the progress bar).

Children stay children for a set amount of time. Then they become unmarried adults. I plan to have a relationship progress for these people and when they achieve it they then marry with someone else who has also filled their relationship bar. This allows the player to have direct impact on the speed of marriage. For instance, holding more festivals and events fills the progress bar faster. For now, once someone is an adult then they will immediately attempt to form a new family with another adult. These two adults are removed from their original families to form a new family as the parents.

In the future I will probably put in a baby time period where the people can do nothing. Then a child time period where they can go to school, play games or sports or apprentice and earn skills and do some amount of labour. And then finally they enter an adult period where they have full labour capacity and end their education and so on.

For now, complicated issues like divorce will not exist. Widows can remarry (they'll count as an unmarried adult).

In code, what will be done is adding a vector of family objects to a faction. Each family object tracks a vector of people for the parent(s), a vector for the unmarried children and a vector for the children. Homosexual families, polygamous families, adoption etc occur through other algorithms. The family class itself will be structured to handle it all in the future. For now though there'll just be vanilla marriage and family fission/fusion (mother/father plus the children). During update tick it would track excess health of the family and put it into the progress bar for next birth. The number of children determines the amount required for the next pregnancy. Homosexual parents would obviously just have zero progress for pregnancy. There is also intended to be future technology (likely medieval age) for contraceptives that would also stall progress. This may be useful if resources become tight.

Households

Separate from families are households. A household is defined as everyone living at the same household. There can potentially be multiple families living in the same household. Each person tracks their living space separately.

Households are important in several ways. A person who crafts any item will do so at their household and thus utilize the industrial improvement of that house. They will also store goods at their house. They also receive benefits from the housing but split across the number of people living there.

I intend to track wealth by household rather than by family. I will have to see whether that makes sense in the future.

People consume goods individually and thus acquire their health and happiness bonus from goods consumption separately.

In code, this means that each person has a reference to a building id which represents their home. When conducting unit actions, such as harvesting or item crafting, they first refer to this building id as their drop off point. If none is available or it is not suitable then they look to public buildings that are nearby.

Ecology

The game currently doesn't replenish resources which is bad news if you actually wanted to play. The update tick functionality needs to take in a game clock of some sort to determine the time of year (and thus the season). As well, plants and animals need requirements such as season of growth or climate required. Animals may have additional requirements. I haven't yet decided whether those requirements should be set in stone (a deer always require pine trees) or have them procedurally generated as the game map is formed (a deer that spawns in a land region with oak trees will have oak trees as a requirement, whereas a deer that spawns in a land region with maple trees has maple trees as a requirement).

During a growth season, a land region tracks the number of plants of a particular type, their growth rate and then adds a certain value back to the land during each update tick. This way if the player changes the number of plants then they also affect the total growth rate. For grasses and bushes (such as wheat or strawberries) each plant can regrow on its own because they are never cut down. Trees on the other hand regrow base on the number of trees still standing and then new saplings only spring up after the existing trees have all grown back to their full amount.

Non-renewable resources don't regrow and their limitation is based on the amount that can be drawn from it at any given time. For instance a single stone deposit may only have 100 stone drawn from it per hour. This can be improved with technology (such as building an open pit mine on the deposit).

Animals have requirements based on the vegetation or animals that exist in a land region. So if a deer requires 5 pine trees, there are 100 pine trees in a land region, then there can be 20 deer. Then additionally, deer are born slowly based on this amount. If you increase the number of pine trees then you also increase the number of deer. The vice versa also applies. This means that deforesting an area also impacts animal numbers.

The UI hasn't been built yet but the land management screen should be colourful and clear about the ecological implications of a player's actions. They need to know the growth rates and animal birth limits, as well as what affects them. After that the game has no restrictions. You can ecologically destroy the world if you want.

In code, the update tick needs an optional parameter for the terrain manager to take in the game clock. Well, the game also needs a game clock! While it has a clock in general it doesn't track the time of year and reset to zero each new year.

Land Regions

Land regions define an irregular shape of land for several in-game purposes. The first is the plants and animals. Each land region has its own set of plants and animals. One land region might be pine and deer. Another might be pine and rabbits. Taking different land regions means gaining access to different types of plants and animals. However, the game is designed so that you can play with an incomplete set of resources and simply trade with other players for what you don't have.

Second is that these help to define interesting borders. When you take a land region you own that area and others may not enter without eliciting some political consequences.

Third are roads. I intend to make pre-set roads between neighbouring land regions. These roads can eventually be improved with technology. They start as nothing but are coded into the game so that when people want to travel to another region or deliver goods somewhere, they take that path and not a random path.

Fourth is climate. A land region can have a custom climate. I won't make it too complicated at first. Maybe just cold, temperate and hot. Plants and animals will have climate requirements and if they are in a land region that has the wrong climate they won't grow or grow at a penalty.

In code, I will probably have the terrain manager keep track of these land regions. Being irregularly shapes makes their definition difficult. My current compromise is for a land region to be comprised of a set of rectangles. In order to test if a particular square in the game exists in a land region, it is tested against that set of rectangles. That is a relatively quick test that may take upwards to 5-10 such checks. It depends on how crazily shaped I want land regions. The rest of the data that may exist are perhaps a set of "roads" (set paths in the game for units to take), the climate and also the plants/animals that exist. I may even shove some graphic variables in there (the static geometry of the trees and so on) since I don't currently have a graphics module in my engine (woe is me).