Developer Diary #26: Population and Market Operations for Mods

In short: We tested MKA Engine’s shared population, market and production operations for mods—extensions that add game rules or content. The first large-scale run used 2 million population groups, 30,000 locations and 512 markets; measured steps took 170–251 ms with a mod running directly in the engine and 206.7–254.8 ms in portable-plugin form. This was a deliberately heavy mod scenario, not a full game day or a measure of later improvements.
What was the problem?
A game chooses population growth and migration rates, the buying and selling curves for goods, and production priorities. The engine does not choose those game rules; its job is to run shared calculations using the inputs supplied by the mod. Here, a mod is an extension that adds rules or content to a game.
Operations such as counting or moving population groups, finding market prices and distributing limited production capacity became available for mods to use. The important question was what this flexibility would do to daily work in a large world. In particular, we needed to see how the interface and engine handled a mod that touched every population group each day.
How did we solve it?
We gave mods shared operations for grouping populations by common traits, calculating population moves, clearing trades and solving prices, allocating production capacity, and estimating a producer’s possible profit. These operations do not replace game content: growth rates, available goods, supply and demand curves, trade and production priorities belong to the game. The engine calculates from the data it receives.
For the large-scale run, we separately measured two mod forms: one running directly with the engine and one packaged as a portable plugin that can run across different systems. The test world contained 2 million population groups, 30,000 locations and 512 markets, each with one good. Every day the mod processed all population groups, grouped them by location, and cleared and solved every market. This was a deliberately heavy scenario, not typical of a game that only updates groups when needed.

What did we see?
After one warm-up day, we averaged three measured game days. The runs took place on a Linux machine while the system-load indicator—a rough measure of work running or waiting—was between 6.3 and 7.0. Worker count tells us how many workers shared the work at the same time.
| Mod runtime | Workers | Measured step | Population operations |
|---|---|---|---|
| Runs directly in engine | 1 | 251.0 ms | 167.5 ms |
| Runs directly in engine | 8 | 170.0 ms | 149.3 ms |
| Portable plugin | 1 | 254.8 ms | 175.1 ms |
| Portable plugin | 8 | 206.7 ms | 181.2 ms |
The world-state summary matched across all four configurations. This measurement assigned a working allowance of 10 ms to the 1-worker setup and 5 ms to the 8-worker setup, with a 5% measurement tolerance. All four results exceeded that allowance. These figures belong only to this measurement; they are not a game-wide goal or a ceiling for a complete game day. The largest measured part was the mod operation that changed every population group each day: 149–181 ms. The remaining time, between 0.7 and 75 ms depending on the configuration, was not broken down into smaller parts, so we do not attribute the entire difference to one operation. With 8 workers in the portable-plugin run, total time fell from 254.8 ms to 206.7 ms, while the market calculation rose from 3.6 ms to 18.9 ms. Total time and individual tasks can move in different directions under the same load, so worker count alone does not tell the whole story.
The scenario was deliberately heavy because it processed every group every day; a game that processes only groups whose changes are due could behave differently. The first measurement appears in the record dated October 29, 2026. Population and parallel-work paths were improved afterward, but the same large-scale run had not been repeated as of October 30. The first table therefore does not show the result after those improvements or current general performance.

Why did we choose this approach?
This was a deliberately heavy first test of how much work the mod interface could carry, not a success claim. It showed that population operations took a large share, but it did not tell us whether changing every group daily makes sense for a game. Reporting the result plainly and avoiding a “finished” claim until the improvements are measured under the same load is the more accurate choice.
What does it cost?
Shared population and economy calculations do not move game rules into the engine; each game still chooses its rates and content. These timings apply to the heavy mod scenario that processed every population group each day.
What comes next?
We need to rerun the same large-scale scenario with the later mod execution setup, then separately measure game behavior that uses the accumulate-and-threshold approach. Only after those two conditions have been measured can we judge which workloads are acceptable.
Frequently asked questions
Do these measurements show a full game day?
No. They measure a mod scenario that processes 2 million groups every day; they do not represent a game’s entire daily simulation.
Does the engine choose population rates or market prices?
No. Rates, goods, buying and selling behavior, and production priorities belong to the game. The engine calculates using rules supplied by the game and its mod.
Did later improvements change this result?
The table shows only the first measurement; there is no later full-scale result to compare.
Did more workers change the portable-plugin result?
Total measured time fell from 254.8 ms to 206.7 ms, but the market calculation rose from 3.6 ms to 18.9 ms. Looking only at the total or one task is not enough; this result applies only to this test setup.
For background on mod support, see Developer Diary #8. You can also visit MKA Engine, the developer diaries and contact.