Subsystem: Barbarians - Adam-Poppenheimer/Civ-Clone GitHub Wiki
Overview
Barbarians are treated as a civilization for in-game purposes but have special rules to make sure they stick around even when they lack cities and all their units have been destroyed. Barbarians are controlled by a dedicated Barbarian player which currently runs last in the turn order.
Barbarians are designed to spread across the map, harassing civilizations at their weak points and avoiding points of strength. They'll aggressively attempt to capture workers and settlers, which they'll send back to a nearby encampment if one exists, and will also pillage nearby improvements. If there are non-barbarian military units nearby, they're supposed to attack them if they think they're stronger, and either fortify or run away if they think they aren't.
Barbarians periodically spawn on the map through Encampments. These objects can be placed on and removed from HexCells and accrue spawn progress over time. When the progress reaches a certain level, the system attempts to spawn either a naval or a land unit on or around the encampment. Those land and naval units are currently a configurable list in BarbarianConfig from which a unit is randomly chosen. A more complete implementation would instead build from the most modern units available to the non-barbarian civilizations. The best place to make that change would probably be BarbarianAvailableUnitsLogic, which might need per-round updates for some BarbariansToSpawn list it maintains internally.
Barbarians reason about behavior at a global level and a per-unit level. For the global layer, a set of InfluenceMaps are drawn relative to the Barbarian civilization that get some sense of the strength of nearby enemies, that of nearby allies, and the value of nearby improvements. These influence maps are then passed to BarbarianUnitBrain, which handles the behavior of each barbarian unit independently of all the others. The per-unit AI consists of a number of BarbarianGoalBrains, each of which manages a single type of behavior (attack, flee, wander, guard, pillage, etc). Every goal produces both a series of IUnitCommands necessary to execute that goal and a utility value that determines how strong the brain thinks their course of action is. BarbarianUnitBrain goes through all the available goals, selects the best one, and then returns the list of commands, which BarbarianPlayerBrain executes on the given unit. This is done for every unit the barbarian has.
I chose influence maps based on my study of the inspiring game. Though I could not find detailed specs for Civilization 5's AI, I did find some behind-the-scenes information on Civilization 4. The AI in that game used a sizable number of influence maps to handle not just Barbarian AI, but also the AI for normal civilizations. This seemed like a sensible-enough strategy that I opted to copy it.
Design Goals
Behavior
- Barbarians don't need any civilization-wide planning, since they're supposed to represent a decentralized and disorganized collection of warriors. Therefore AI should be done at the level of the unit.
- The barbarian civilization should, however, work to garrison every encampment on the map, though it shouldn't redirect units from far away to do this.
- Ideally, we want barbarians to spread out across the map looking for things to fight. Clustering is acceptable but barbarian encampments should exert a relatively uniform antagonizing pressure in all directions.
- Since barbarians are looking for civilians to capture and improvements to pillage, they should actively seek out cities, but not to the exclusion of wilderness wandering.
- Barbarians should avoid attacking units stronger than them, and should in general avoid dangerous situations.
- Barbarians should actively seek out the destruction of improvements, particularly valuable ones like extractors and great person improvements (the more valuable the improvement, the greater the pull).
- Barbarians should have a very strong desire to capture/destroy civilian units.
- Barbarians might attack cities, but only when the odds are well in their favor (a much lower priority than pillaging and capturing).
- Barbarians should attempt to heal themselves, but only if there are not more tempting things to do.
Spawning
- Barbarian encampments should have a chance of spawning in cells that are not currently visible to any non-barbarian civilization.
- The game should aggressively generate some minimum number of encampments, and then will more slowly and sporadically generate encampments up to some maximum, after which it will stop.
- Nearby encampments should decrease the chances of of a cell being chosen for an encampment.
- When an encampment spawns, it should immediately create the most sophisticated melee unit available to the barbarian civ.
- Barbarian encampments should periodically spawn barbarians until they're destroyed.
- The rate at which barbarians spawn in an encampment should be controlled only by configuration. It doesn't concern itself with barbarian density, nearby civilizations, or anything else.
- Encampments that are surrounded by land should spawn a unit of a random land military type. That unit should be the most advanced unit of that type that any civ on the map can produce. Thus the units the barbarians can produce should get more advanced as players advance through the tech tree.
- Encampments near the water should also periodically spawn naval units, perhaps half the time opting for a naval type.
High-level unit goals
Guard encampment
- Heavily weighted if there's an empty encampment within some number of cells.
- Otherwise has no weight.
Wander
- Fairly static weight, perhaps reduced by the presence of a nearby city, or perhaps just set low so other strategies can easily take precedence.
- moves to a spot within movement range that has the lowest safety (i.e. a low-density region)
Capture civilian unit
- Almost overriding priority if there's an unguarded civilian unit within movement range.
- High priority if there's an unguarded civilian unit within personal vision range.
- No priority if no civilian exists, or if the civilian is guarded.
- Moves to the nearest civilian unit.
Pillage improvement
- Moderate priority for roads.
- Higher priority for finished improvements.
- Priority proportional to the yield of the improvement.
- Very high priority if the improvement is an extractor.
- Priority negated if the improvement is guarded by some unit.
- Moves to and then pillages the most valuable improvement (mitigated by distance).
- Might seek out improvements from longer than visual range.
Attack units
- No priority if no visible enemies.
- priority unaffected by distance (as long as the enemies are visible to the unit).
- Priority increased from safety and decreased from danger (as defined by influence maps).
- Takes into account defensive terrain and cities.
- Increased if unit is ranged.
- Attacks the weakest unit within range if ranged, and weakest nearby unit if melee.
Flee
- Priority increased from danger and decreased from safety (as defined by influence maps).
- Ranged units much more likely to flee if adjacent to enemy melee units (might be baked into the influence map).
- Priority increased if at low health.
- Moves to the safest cell in movement range, modified by defensiveness (might be baked into the influence map).
Wait until healed
- Priority increased if at low health, zero if health is full
- Moves to the safest cell in movement range and waits until healed (or priority chooses other tasks).
- Probably a higher priority than wandering if damaged at all.
Be Prisoners
- Reserved for civilian units, and the only goal they will perform.
- Civilian units will head towards the nearest encampment without a civilian unit if one is within a certain range. Otherwise it'll head to the nearest encampment and stay as close to it as it can.