Meidum — A Royal Necropolis
- Mission
- 12 of 38 — alternative to Serabit Khadim (chosen after Saqqara)
- Era
- Old Kingdom · ~2613 BC · Pharaoh Huni
- Classical name
- Meidum (Lower Egypt, edge of the Faiyum)
- Starting funds
-
Very Easy 20 000 Db Easy 13 300 Db Normal 10 000 Db (pak) Hard 6 700 Db Very Hard 5 300 Db
- Debt interest
-
Very Easy 4% Easy 6% Normal 8% (pak) Hard 10% Very Hard 12%
- Deities
- Osiris · Ptah · Ra
- Trade
- Abu (sea) · Behdet (sea) · Nekhen (sea) · Saqqara (land) · Serabit Khadim (land) — all start closed; Men-nefer is a display-only Pharaoh route (no goods)
- Previous mission
- Saqqara — The First Pyramid
- Next mission
- Player's choice: Buhen or South Dahshur
- Status
- Implemented
Briefing
The mission opens with the history panel (message_history_meidum) and the mission briefing popup (message_mission_meidum):
Pharaoh Huni wishes to spend everlasting eternity in a stepped pyramid, like that of Djoser before him. He wishes to be surrounded by the tombs of his nobles, and has chosen Meidum, in Lower Egypt, as the site for this royal necropolis.
As a symbol of thanks for the many generations of faithful service provided by your house, Huni has also consented to allow you to be interred at Meidum, in your own tomb. In doing this, he has also conferred great honor upon your family.
To ensure that the wisdom and learning of Egypt is preserved through the ages, Pharaoh Huni also urges the construction of royal libraries. Once filled with scrolls of papyrus, these will provide higher education to the upper classes.
Pharaoh has sent another of his faithful courtiers on an expedition to Serabit Khadim, in the harsh land of Sinai, to acquire turquoise gemstones. If this expedition is a success, you may look forward to importing gemstones from there. Jewelers can use these to fashion jewelry, a valuable luxury good, for the people of your city.
The once-thriving city of Behdet has begun to decline, and no longer exports many of the commodities they were once known for.
Meidum lies on the desert edge of Lower Egypt near the Faiyum. The historical pyramid of Meidum — begun as a step pyramid for Huni and later converted by Snofru into the first attempt at a true pyramid — partially collapsed in antiquity, leaving the strange three-stepped tower that stands today. In the campaign this is the necropolis-building alternative to the Serabit Khadim mining expedition: the first mission where monument construction, libraries, and higher-class housing all come together.
Objectives
- Population 3 000 citizens
- Culture rating 25
- Prosperity rating 25
- Monument rating 76 — complete both the small stepped pyramid and the stepped pyramid complex
- Kingdom rating 40
- Housing level 11
Population, culture, prosperity, kingdom, and housing match mission1.pak scenario 12. The monument rating uses the reimplementation additive scale: original pak goal was 39, which is incompatible with the additive formula — see the deviation note.
2.25·Σ+4.5 (clamped to 100) and weights small=8 / on-land complex=24, finished both yield 76. Weight 44 would saturate the 100-cap from the complex alone. Causeway water-gate (Slice A) is enforced; temples/full W=44 still open. Pak-39 needs a pak-compatible formula fork.
Scripted events
Full empire redefine + event schedule verified against pak scenario 12 (2026-07-25 dump). Empire id 1. Scenario enemy is Hyksos (ENEMY_5_HYKSOS) — not Libyan. Favour-KR Pharaoh army size 25, chaining to a second wave of 60 if unresolved. Timed raids and favour are proxied in JS until B2-migrate.
Strategy
Meidum is the first full monument economy: two stepped pyramids demand a steady flow of plain stone, work camps, and all three construction guilds, while the culture goal requires libraries and a broad service net. Papyrus is the main export income.
Phase 1 — Food and papyrus
Floodplain grain and fig farms feed the city; reed gatherers in the marshes supply the Papyrus Workshop. Papyrus does double duty — it is a trade export once Abu, Nekhen, or Saqqara are opened, and it stocks the libraries needed for the culture rating. Beware the hippos in the marshland when routing gatherers.
Phase 2 — The necropolis
Lay out the small stepped pyramid and the stepped pyramid complex early — they take years to finish. Stone Quarries plus a Work Camp and the Stonemasons' Guild drive construction; the Carpenters' and Bricklayers' Guilds are needed for the early phases. Keep a dedicated Storage Yard for plain stone next to the sites. Mastabas for the nobles can be added alongside — they contribute a little to the monument rating but are not required for the goal. The complex needs a clear causeway path to water (temples not built yet).
Phase 3 — Defense against the Hyksos
Starting around year 7, Hyksos raiders (not Libyans) land near the pak invasion point at roughly tile [114, 79] and return each year once the previous force is cleared. Build a Recruiter and Weaponsmith in advance and keep one company of infantry and one of archers ready; a Transport Wharf and warships help intercept along the river. Pharaoh's favour can also drop a Pharaoh-aligned army of 25 (chaining to 60) if the kingdom rating collapses, so a healthy KR is part of your defense plan too.
Phase 4 — Culture and prosperity
Culture 25 needs schools, libraries, temples, and entertainment coverage; prosperity 25 needs housing beyond the basic levels — import gems from Serabit Khadim, craft jewelry, and let the luxury goods raise home values. Hold festivals for Osiris and Ptah to keep the gods content while the pyramids consume the city's labor.
Tips
- Start both the small pyramid and the complex as soon as the stone chain works — the monument rating only reaches the goal when both are fully complete.
- Wood is requested in year 3 and is also needed by the Shipwright — keep the Wood Cutters running even after the request is filled.
- Libraries consume papyrus; budget production above the export quota or the culture rating will stall.
- All five trading partners start closed — Saqqara (200 Db) and Serabit Khadim (350 Db) are the cheapest land routes to open early; Abu, Behdet, and Nekhen are sea routes and cost more (650–1050 Db).
- Most Pharaoh requests raise kingdom rating by 8 on completion and cost 5 on refusal (the shared KR leaves) toward the goal of 40 — but the year 3 timber request and the timber demand chain are the exception, only costing 2 on refusal.
Available buildings
All buildings are available from mission start — there are no progressive unlocks in this mission:
| Category | Buildings |
|---|---|
| Housing & roads | Vacant Lot · Clear Land · Road · Road Block · Low Bridge · Ferry |
| Municipal | Firehouse · Architect's Post · Police Station · Village Palace · Personal Mansion · Tax Collector · Courthouse |
| Health | Water Supply · Apothecary · Physician · Mortuary |
| Food & farming | Grain Farm · Figs Farm · Hunting Lodge · Water Lift · Irrigation Ditch · Bazaar · Granary · Storage Yard |
| Raw materials | Stone Quarry · Clay Pit · Reed Gatherer · Wood Cutters |
| Industry | Bricks · Pottery · Brewery · Papyrus · Weaver · Jewels Workshops · Work Camp |
| Monuments | Small Stepped Pyramid · Stepped Pyramid Complex · Small Mastaba · Medium Mastaba |
| Guilds | Stonemasons' · Carpenters' · Bricklayers' |
| Military | Recruiter · Weaponsmith · Infantry / Archers / Charioteers Fort · Warship Wharf · Transport Wharf · Shipwright |
| Religion | Temples & Shrines of Osiris, Ptah, Ra · Festival Square |
| Education | Scribal School · Library |
| Entertainment | Booth · Juggler School · Bandstand · Conservatory · Pavilion · Dance School |
| Beautification | Small / Medium / Large Statue · Gardens · Plaza |
Developer reference
Collapsed sections below show exactly where each part of this mission lives in the source tree. All paths are relative to the repository root.
Mission script — src/scripts/mission/m_012_meidum.js
The entire mission — configuration block, variables, and all event handlers — lives in one file:
src/scripts/mission/m_012_meidum.js
This file is imported by src/scripts/missions.js. The mission12 { … } block at the top is the static configuration parsed at startup:
// m_012_meidum.js — full empire redefine, verified vs mission1.pak scenario 12 (2026-07-25)
mission12 {
map_file : "data/maps/m_012_meidum.map"
start_message : "message_mission_meidum"
player_rank : 4
choice [ // post-victory: Buhen (13) / Dahshur (14)
{ name : "Buhen", id : 13 }
{ name : "Dahshur", id : 14 }
]
initial_funds [20000, 13300, 10000, 6700, 5300]
debt_interest [4, 6, 8, 10, 12]
// Monuments goal 76 = trunc(2.25*(8+24)+4.5); pak was 39.
win_criteria {
population { enabled : true, goal : 3000 }
culture { enabled : true, goal : 25 }
prosperity { enabled : true, goal : 25 }
monuments { enabled : true, goal : 76 }
kingdom { enabled : true, goal : 40 }
housing_level { enabled : true, goal : 11 }
}
invasion_points_land [ [114, 79] ]
invasion_points_sea [ [31, 7] ]
// empire id=1; hide_pak_* + cities/routes/ornaments/texts (Abu/Behdet/Nekhen sea,
// Saqqara/Serabit Khadim land, Men-nefer display-only Pharaoh route)
hide_pak_cities : true
}
The monument goal of 76 is the rating from small (8) + on-land complex (24) → trunc(2.25 × 32 + 4.5) = 76 (see src/scripts/city/monuments.js). Pak original was 39; restoring it needs a pak-compatible formula fork. Causeway placement for the complex is still open. All other goals (pop 3000, culture 25, prosperity 25, kingdom 40, housing level 11) and the funds/debt-interest ladders match pak exactly. Trade: Abu / Behdet / Nekhen (sea, 650–1050 Db), Saqqara / Serabit Khadim (land, 200–350 Db) — all start closed. Men-nefer is a display-only Pharaoh route (no goods). Display: Byblos, Kerma, Kyrene, Selima Oasis.
Event handlers — all functions in m_012_meidum.js
Handlers fire only while mission=mission12 is active. Raids use the JS API city.start_foreign_army_invasion with ENEMY_5_HYKSOS; native EVENT_TYPE_INVASION awaits B2 / B2-migrate. Every pak event index (i=0…70) that isn't skipped junk gets its own event_advance_month handler, gated by a once-flag or a per-year "last fired" guard for recurring roots — rather than list all ~40 of them individually, they group into:
-
event_mission_start
Start message;
empire.set_id(1);city.set_scenario_enemy_id(ENEMY_5_HYKSOS); advisors; wires every dormant chain leaf up front. mission12_on_start -
Shared helper builders
Create the dormant
ONLY_VIA_EVENTchain leaves reused across most requests: the four shared KR leaves (+8 / −5 / +2 / −2), plus the clay, timber, grain, and papyrus resource chains, plus the gift chains (luxury/oil). mission12_ensure_*_leaves - Once calendar roots Fire a single request or state change the first time the game clock passes their pak year/month: timber y3m4, wage decrease y5m3, reeds y5m7, papyrus y12m11 / y15m10 / y63m2, stone y13m3 / y29m8, pottery y13m8 (bare, no KR chain) / y23m4 / y39m5 / y62m8, grain y18m3, failed floods y16m9 / y33m8, price changes y72m8 / y74m7, clay y74m7, and the stone→luxury gift root y69m7. mission12_event_i<n>_*
-
Recurring calendar roots
Re-fire yearly once their gate year is reached, guarded via
mission_recurring_request_may_fireso overlapping pottery/grain/timber requests never stack: pottery y8m1+ (clay chain) / y11m9+ / y40m4+ / y52m4+, grain y13m5+ / y23m4+ / y38m3+ / y41m11+ (grain chain) / y44m3+ / y56m11+ (grain chain) / y60m9+ (gift chain), timber y16m7+ (timber chain) / y59m1+ / y82m1+, stone y95m7+ (gift chain), plus price/wage swings, clay-pit floods, and the sea-trade problem (y61m5+). mission12_event_i<n>_*_recurring -
Hyksos raid + Pharaoh favour
Recurring size-17 Hyksos raid from y7m6+, gated on
city.num_enemy_formations == 0so it re-arms once the map is clear; a monthly favour tick drops a size-25 Pharaoh army when kingdom rating bottoms out, chaining to a size-60 second wave. mission12_event_i70_hyksos_invasion_recurring / mission12_pharaoh_favour_invasion
Dump helper: src/js/js_test_mission_pak_dump.cpp (__test_mission_pak_dump / GamestateIO::load_mission_pak_raw; ad-hoc tests/99_tmp_mission12_dump.js).
Game messages — src/scripts/game_messages_en.js
Popup dialogs and the opening history panel are defined in src/scripts/game_messages_en.js. To edit text, find the entry by key and change the text: field inside its content { … } block.
| Key | ID | Line | When shown |
|---|---|---|---|
message_history_meidum |
212 | 2621 | History briefing shown before mission starts (narrator text — "A Royal Necropolis") |
message_mission_meidum |
412 | 4882 | start_message — first popup on mission load |
Briefing and victory narration audio: Voice/Mission/212_mission.mp3 and Voice/Mission/212_victory.mp3 (configured in the sounds block of the mission config).
Known deviations from the original (tracked)
- Monument goal: original pak is 39 (small + stepped pyramid complex). Reimpl uses the additive formula → goal 76 (
trunc(2.25·(8+24)+4.5)); on-land complex weight=24 (same as large) because rating is clamped to 100 and weight 44 would saturate alone. Causeway open. Pak-39 needs a pak-compatible formula fork. - Invasions and Pharaoh's favour are proxied in JS (
city.start_foreign_army_invasion,mission_pharaoh_favour_invasion_tick) rather than the nativeEVENT_TYPE_INVASION— same pattern as Saqqara and Serabit Khadim, pending the B2-migrate step. Favour drops a Pharaoh-aligned army of 25, chaining to a second wave of 60 if the kingdom rating stays low. - Skipped pak junk: empire route 47 (orphan, no city references it) and map object index 7 (an empty stub at position 0,0) are omitted. Pak events with
years_since_start >= 98(a failed flood, a reeds request, a wage change, and a papyrus request with its gift chain) are dead data past any realistic playthrough length and are not wired. - Orphan chain-only leaves with no inbound reference (pak i=46 KR+7, i=58 papyrus price-decrease) are left out of the script — nothing in the fired schedule ever routes to them.
Save file and map data
The map layout, terrain, marshland island, and the kingdom road entry point come from the original Pharaoh campaign pack:
mission1.pak (scenario offset for id 12 — see GamestateIO::get_campaign_scenario_offset, src/io/gamestate/boilerplate.cpp:120)
The binary map is loaded by the engine before the JS script runs. The scripting system is loaded from src/scripts/missions.js, which imports mission/m_012_meidum.js by path. If you rename or move the file, update the import there.