|
1 | | -| Game tick (0 - 199) | Function called (and key args) | |
| 1 | + |
| 2 | +### Load balancing in the core game engine |
| 3 | +In an ideal world, the game computes everything at every tick, however, this will slow the game down over time (e.g. when unit count becomes large). The game solves this by load-balancing ticks: not all actions are performed each tick, but actions are distributed across ticks. |
| 4 | + |
| 5 | +In this article, a table is presented with a summarized form of what occurs at every tick. |
| 6 | + |
| 7 | +One load-balance cycle is 200 ticks (0 - 199), after which count starts from 0 again. |
| 8 | + |
| 9 | +#### Table of always load-balanced stuff |
| 10 | +(source: `processSingleTimeTick`) |
| 11 | + |
| 12 | +| Tick (0 - 199) | Function called (and key args) | |
2 | 13 | | -------------------------------: | ---------------------------------------------------------------------------------------------------- | |
3 | | -| 10–18 | `recomputeTroopValuesForPlayer(&DAT_UnitsState, gTLB - 10)` → players 0–8 | |
4 | | -| 25 | `setTreeSpreadInterval(&DAT_LandscapeState)` | |
5 | | -| 31 | `createStatsPopUpEntities(&DAT_GameState)` | |
6 | | -| 34 | `recountTotalTroopValue(&DAT_TroopValueState)` | |
7 | | -| 40 | `moatRelatedUpdateFunction(&DAT_TileMapState)` | |
8 | | -| 60–68 | `recomputeTroopValuesForPlayer(&DAT_UnitsState, gTLB - 60)` → players 0–8 | |
9 | | -| 71–78 | `updateEnemyBuildings(&DAT_BuildingsState, gTLB - 70)` → indices 1–8 | |
10 | | -| 80 | `spawnMotherOrChild(&DAT_GameState)` | |
11 | | -| 93 | `recomputeTotalTroopValueOfTroopsNearKeep(&DAT_TroopValueState)` | |
12 | | -| 95 | `processPeasantsForBuildings(&DAT_GameState)` | |
13 | | -| 99 | `showPopAndGoldPopup(&DAT_GameState)` | |
14 | | -| 101–108 | `recomputeTroopValuesForPlayer(&DAT_UnitsState, gTLB - 100)` → players 1–8 | |
15 | | -| 110–149 | `updateWildlifeGrid(&DAT_WildlifeState, gTLB - 110)` → grid slice 0–39 | |
16 | | -| 150 | `updateWildlife(&DAT_WildlifeState)` | |
17 | | -| 151 | `updateSection1034Info(&DAT_WildlifeState)` | |
18 | | -| 152 | `updateNofFpoints(&DAT_WildlifeState)` | |
19 | | -| 160–168 | `recomputeTroopValuesForPlayer(&DAT_UnitsState, gTLB - 160)` → players 0–8 | |
20 | | -| 180 | `spawnChicken(&DAT_GameState)` | |
21 | | -| 190 | `recountStablesAndHorses(&DAT_GameState)` | |
| 14 | +|0|In multiplayer, check resync by computing hashes of game data| |
| 15 | +|0|Update greatest lord, but not in the first cycle of load-balancing of a match| |
| 16 | +|0|Recompute sync hashes| |
| 17 | +| 10–18 | `recomputeTroopValuesForPlayer` → players 0–8 | |
| 18 | +| 25 | `setTreeSpreadInterval` | |
| 19 | +| 31 | `createStatsPopUpEntities` | |
| 20 | +| 34 | `recountTotalTroopValue` | |
| 21 | +| 40 | `moatRelatedUpdateFunction` | |
| 22 | +| 60–68 | `recomputeTroopValuesForPlayer` → players 0–8 | |
| 23 | +| 71–78 | `updateEnemyBuildings` → indices 1–8 | |
| 24 | +| 80 | `spawnMotherOrChild` | |
| 25 | +| 93 | `recomputeTotalTroopValueOfTroopsNearKeep` | |
| 26 | +| 95 | `processPeasantsForBuildings` | |
| 27 | +| 99 | `showPopAndGoldPopup` | |
| 28 | +| 101–108 | `recomputeTroopValuesForPlayer` → players 1–8 | |
| 29 | +| 110–149 | `updateWildlifeGrid` → grid slice 0–39 | |
| 30 | +| 150 | `updateWildlife` | |
| 31 | +| 151 | `updateSection1034Info` | |
| 32 | +| 152 | `updateNofFpoints` | |
| 33 | +| 160–168 | `recomputeTroopValuesForPlayer` → players 0–8 | |
| 34 | +| 180 | `spawnChicken` | |
| 35 | +| 190 | `recountStablesAndHorses` | |
| 36 | + |
| 37 | +##### Things that are not load-balanced: |
| 38 | +- Checking game sync status as this is performed by the host at the game time we know hashes for |
| 39 | + |
| 40 | + |
| 41 | +#### Load-balancing in calendar modes |
| 42 | + |
| 43 | +##### Time in the game |
| 44 | +One load-balance cycle corresponds to a week in game time. After 200 ticks (0 - 199), the cycle is started from 0 again. |
| 45 | + |
| 46 | +|What|Ticks|Day|Week|Month|Year| |
| 47 | +|----|-----|-----|-----|-----|-----| |
| 48 | +|Day|50|1|1/4|1/16|1/192| |
| 49 | +|Week|200|4|1|1/4|1/48| |
| 50 | +|Month|800|16|1/4|1|1/12| |
| 51 | +|Year|9600|192|48|12|1| |
| 52 | +|**Load-balance cycle**|200|4|1|1/4|1/48| |
| 53 | + |
| 54 | +Note: In EDITOR mode and SIEGE THAT mode, there is no concept of time. In the other game modes, time works like in the table. |
| 55 | + |
| 56 | +Note 2: While the on-screen instruction to place keep and/or granary is showing, then weeks, months, and years are not counted yet. |
| 57 | + |
| 58 | +##### Table of calendar-based balancing |
| 59 | + |
| 60 | +| Tick (0 - 199) | Function called (and key args) | |
| 61 | +|--:|:--| |
| 62 | +|0|updateCrowding| |
| 63 | +|0|updateTrader| |
| 64 | +|0|updateTaxing| |
| 65 | +|0|updateAleRate| |
| 66 | +|0|recomputeAllFearFactors| |
| 67 | +|0|updateFearFactorProductivity| |
| 68 | +|0|updateReligionBonuses| |
| 69 | +|0|updatePopularity| |
| 70 | +|0-199|(de)spawn peasants (tick the campfire clock)| |
| 71 | +||| |
| 72 | + |
| 73 | +### More game ticks |
| 74 | +source: `processGameTick` |
| 75 | + |
| 76 | +With the calendar-based ticks out of the way, the game also balances several other computations. |
| 77 | + |
| 78 | +|Tick|What| |
| 79 | +|--:|:--| |
| 80 | +|0-199|updateWind (a wind cycle is 32 ticks)| |
| 81 | +|0-199|updateClimbData (a wind cycle is 32 ticks)| |
| 82 | +|0-199|updateBuildings (a wind cycle is 32 ticks)| |
| 83 | +|(tick % 10) == 5|recount amount of buildings| |
| 84 | +|0-199|updateBuildings| |
| 85 | +|(tick % 20) == 5|apply damage to burning buildings| |
| 86 | +|(tick % 20) == 3|recount amount of pitch ditches| |
| 87 | +|0-199|updatePitchDitches| |
| 88 | +|(tick % 10) == 8|recount amount of trees| |
| 89 | +|(tick % 8) == 4|random tree (growth?)| |
| 90 | +|0-199|update trees| |
| 91 | +|0-199|single player events| |
| 92 | +|every day|"Once more unto the breach"| |
| 93 | +|every month|recompute resources in stock| |
| 94 | +|every day's 10th tick|make Outpost tribes attack| |
| 95 | +|day tick == ai player id|recruit units, buy and sell goods, raid| |
| 96 | +|week tick == ai player id|recruit oil duty, update tribe locations, update AI state, update taxes and rations, set food buy plan| |
| 97 | +|week tick == ai player and month tick != ai player|reconsider strength/weak in Extreme trail| |
| 98 | +|month tick == ai player|moat instructions, sortie units, reconsider strength/weak, destroy buildings, recruit raiding units preferably, select attack target, update recruit gold threshold status | |
| 99 | +|every week| update path linkage layer, update heatmap, disappear units that can't reach the keep | |
| 100 | +|day tick == ai player|decide on new ai buildings, snooze buildings, buying plan for low resources| |
| 101 | +|day tick == 8|propagate building sleep to all buildings of that type| |
| 102 | +|month tick == 10|recompute heat maps| |
| 103 | +|every 64 ticks|set troop value of player to 0 and recompute it| |
| 104 | +|every tick| update units | |
| 105 | +|every 64 ticks|assign citizen name to unit| |
| 106 | +|unit dependent notice frequency|notice enemy units| |
| 107 | +|every tick|update entities| |
| 108 | +|every tick|remove unit chaining on same tiles| |
| 109 | +|every tick|update food| |
| 110 | +|every month|give food warning| |
| 111 | +|every day|update population growth| |
| 112 | +|every month|moving average of population| |
| 113 | +|every tick|update tribe unit assignments| |
| 114 | +|(tick % 32) == (tribe id % 32)|compute tribe percentage| |
| 115 | +|every tick|update tribe behavior| |
| 116 | +|every tick|recompute army size limit based on alive player count| |
0 commit comments