Skip to content

Commit 05a0ec7

Browse files
author
sourcehold
committed
docs: add load balancing wiki page
1 parent 9109c38 commit 05a0ec7

File tree

2 files changed

+116
-22
lines changed

2 files changed

+116
-22
lines changed

docs/wiki.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ Welcome to the OpenSHC Wiki!
66

77
Here you'll find detailed documentation about:
88

9-
- Load balancing of the core game engine
10-
:doc:`wiki/load-balancing-table`
9+
- :doc:`Load balancing of the core game engine <wiki/load-balancing-table>`
1110
- Game Mechanics
1211
- AI Behavior
1312
- Graphics and Sound Systems

docs/wiki/load-balancing-table.md

Lines changed: 115 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,116 @@
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) |
213
| -------------------------------: | ---------------------------------------------------------------------------------------------------- |
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

Comments
 (0)