Advertisement

City building game inner workings

Started by February 18, 2018 11:04 AM
4 comments, last by suliman 6 years, 9 months ago

Hello,

without going into any details I am looking for any articles or blogs or advice about city building and RTS games in general. I tried to search for these on my own, but would like to see your input also. I want to make a very simple version of a game like Banished or Kingdoms and Castles,  where I would be able to place like two types of buildings, make farms and cut trees for resources while controlling a single worker. I have some problem understanding how these games works in the back-end: how various data can be stored about the map and objects, how grids works, implementing work system (like a little cube (human) walks to a tree and cuts it) and so on. I am also pretty confident in my programming capabilities for such a game. Sorry if I make any mistakes, English is not my native language.

Thank you in advance.

If I get this right, you're struggling with the algorithmic part of making the 'workers' which are essentially simple AI-controlled characters that obey relatively complex instructions originating from the player?

Making a worker that works fine is not terribly challenging, however, making one that remains workable as your game development progresses (and complexifies) requires some preparation work and a good idea of where you're going.

 

Advertisement

There are quite a few methods to approach this but the most simplistic one is usually based on the idea of breaking everything in the world into actions which produce state changes.  Banished is probably the most simplistic of the games until you get into the market and home management portions of things so I'll use that as an example.  If you ignore everything except one building, things become simple though you have to think of the solution in a kind of odd manner.  Let's take the fishery as an example.  The fishery is placed near water and it contains one action from then on: "create a fish".  Since in Banished you assign workers to buildings (well you set the number and the game selects the specific entities) the first step is pretty easy, on every game update the workers check their assigned building for an action if they don't have one already.  Since the fishery always contains "create a fish" as an action the worker will always have one copy of that action in their queue.  We'll ignore the other items such as get warm, go eat, sleep etc but they are also in the queue and that's where the priority portion comes in later.

Every action has a required state, what it 'does' code and a final state change to make on completion.  The required state for create a fish is 'in the building', it's 'does' code is simply wait 'x' seconds and the resulting state change is '+1 fish to inventory'.  So, the entity tries to run the 'does' code but finds that the requirement 'in the building' is not satisfied.  The entity looks in a table of actions for one which has a result of 'in a building', it should find a 'path to building' action with the desired result.  So, the entity code moves the "create a fish" action to be a child of a new copy of "path to building" and starts running that action.  "Path to building" has a required state: "has path to building", it searches the actions and finds "create path", pushes "path to building" to a child of a new copy of that and starts running it.  "Create path" has no requirements and results in either success, which sets the path on the entity workspace, or fails and takes all it's children with it potentially telling the user or the building about the failure.  Assuming there is a path though, it assigns it to the entity workspace as the state change portion of the action and then replaces itself in the queue with it's child "path to building" which can now start running, as such the entity starts following the path.  Each update the "in building" check is updated and when it changes, pop "path to building" off and replace it with "create a fish" which now starts running.  "Create a fish" simply puts the entity to sleep for 'x' seconds and when complete it performs "+1 fish" state change.  Bingo, a chain of events broken into fairly simple concepts which can be explained to the entity with a fairly trivial algorithm.

That's the very "basics" of how you can solve the "do things" portion of the problem.  It is actually fairly simple though some of the code is not trivial.  Where things start getting more complicated, and as Orymus3 said, how to make it work through out the game evolution, is when you start adding multiple competing needs to the entities.  In Banished again, each entity has competing needs such as: stock my houses inventory, eat, sleep, procreate, get warm, get healthy, etc.  At this point you start assigning priorities to the actions in each entity and as such your balancing nightmare commences.  You need to start considering things like action velocity (i.e. I've started this action so it should get a boost to priority for a while before other things interrupt it), absolute interrupts such as hey that's a fricken tornado I should run away, etc.

In more complicated games, Kingdom's and Castles I'm not sure of, you have multi-step production chains and things get *really* damned complicated.  For instance in an older game I can't remember the name of, you had fields of wheat which you harvested, wheat was then used in a mill to produce flour, which was then taken to a bakery, which when combined with entities and other ingredients could produce different types of food.  That game left a lot of the priority setting to the player and it was really difficult to get things working smoothly because the AI didn't consider time spent pathing, waiting for the mill to not be in use, etc very well when considering which actions were most efficient.  Lately I believe a modified Monte Carlo Tree Search could be modified to handle such things but that's getting pretty advanced and you should probably stick to the Banished like simple model till you get a handle on some of the trickier bits.

Hope I didn't trivialize this too much to make sense.  If I did though and you need further expansion on bits and pieces, let me know.

2 hours ago, All8Up said:

Hope I didn't trivialize this too much to make sense.  If I did though and you need further expansion on bits and pieces, let me know.

No, you didn't. It was really interesting read and I am saving it for later, thank you!

You might refer to the game "Stronghold". Awesome game. Also i dont think Kingdoms and Castles needs less advanced AI  that Kingdoms and Castles, that game is pretty basic.

I use a finite-state machine. So a worker has only one state at each moment:

1. Go to workplace
2. Work
3. Drop-off goods (at stockpile)

So depending on the current state, different code is run for the worker. If its in state "Go to workplace" it will find a good path to the workplace (and once done) actually move towards it. If it's close enough to its workplace it will change the state to "work". Then different code will be excecuted instead.

You can add more states and control how they change between each other. If the worker needs to get food for it's house (as in banished) you can add:

4. Refill food stocks

This will be jumped to (from any state) if the stock in the house is close to zero. Change the state and remember what state the worker was on. When it has refilled the house, change back to the state it was on (or possibly "go to workplace" if needed).

This topic is closed to new replies.

Advertisement