data/claims/dune2.yamlDune II (OpenDUNE's C translation of the 1.07 DOS executable)
Game: Dune II.
Dune II came out in 1992. dune2/release
Value: 1992
WikidataWikidata ·Q596631, publication date (P577)+1992-01-01T00:00:00ZWikidata gives the year only (precision 9), with no reference and no platform qualifier.
Cited by: Dune II
OpenDUNE runs on the data files of Dune II 1.07, dune2.exe included, and keeps the original behavior behind a switch: with dune2_enhanced at 0 the "game acts like the original Dune II, including bugs", and at 1, the default, it applies the fixes that enhancement.txt lists. dune2/source-version
Value: 1.07
CodeOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) ·README.txt#L64Copy the original Dune2 1.07 data files (including dune2.exe) to data/.OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · README.txt#L95-L97- dune2_enhanced : 0 = game acts like the original Dune II, including bugs
1(default) = enable OpenDUNE enhancementsOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L81bool g_dune2_enhanced = true; /*!< If false, the game acts exactly like the original Dune2, including bugs. */OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · enhancement.txt#L3-L4When OpenDUNE is started in enhanced mode (default), a lot of bugs and
problems which are in the original Dune2 version, are fixed.Checked by claude, 2026-10-21 — read README.txt's install and debug-option sections, the flag's definition, and enhancement.txt's opening at the pinned commitREADME.txt itself says only that OpenDUNE "attempts to re-create the original game"; the comment on g_dune2_enhanced is where the project says the original mode acts "exactly like the original". Every other claim here reads OpenDUNE's code, which keeps each fix in a branch marked ENHANCEMENT; a claim that rests on one names it.
Cited by: Dune II
Each time a harvester's script calls Script_Unit_Harvest while the harvester stands on spice or thick spice with a load below 100, the load grows by 0 or 1 at random, capped at 100, and in 1 call out of 32 the tile loses a level: thick spice becomes spice, and spice becomes sand. The status line reports the load as a percentage full. dune2/harvest
About: Dune II Resource harvesting
Value
{
"perCall": [
0,
1
],
"capacity": 100,
"depleteChance": 0.03125
}src/script/unit.c#L1650-L1669if (u->amount >= 100) return 0;
…
if (type != LST_SPICE && type != LST_THICK_SPICE) return 0;
…
u->amount += Tools_Random_256() & 1;
…
if (u->amount > 100) u->amount = 100;
…
if ((Tools_Random_256() & 0x1F) != 0) return 1;
…
Map_ChangeSpiceAmount(packed, -1);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/map.c#L784-L788type = (type == LST_THICK_SPICE) ? LST_SPICE : LST_NORMAL_SAND;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L2061-L2069stringID = STR_IS_D_PERCENT_FULL;Checked by claude, 2026-10-21 — read Script_Unit_Harvest and Map_ChangeSpiceAmount's negative branch at the pinned commit; the yield is the same on spice and thick spice, so thick spice only lasts twice as many depletionsHow often the harvester's script calls this function is set by UNIT.EMC, a script in the game data that the repo doesn't hold, so the load gained per second isn't in the code read here.
Cited by: Dune II, Resource harvesting
A refinery empties a docked harvester a step at a time: each call to Script_Structure_RefineSpice moves up to 3 load units at full health, 2 once damaged, and 1 below 171/256 of full health (computed from hp × 256 / max × 3 / 256, at least 1), and pays 7 credits per unit to the player, or 6 to 9 at random per call to a computer house; the next call waits 6 script ticks. Computed: a full harvester (100) is worth 700 credits to the player. dune2/refine
About: Dune II Resource harvesting
Value
{
"creditsPerUnit": 7,
"aiCreditsPerUnit": [
6,
9
],
"unitsPerCall": [
1,
3
],
"fullLoadCredits": 700
}src/script/structure.c#L125-L136harvesterStep = (s->o.hitpoints * 256 / si->o.hitpoints) * 3 / 256;
…
if (u->amount != 0 && harvesterStep < 1) harvesterStep = 1;
…
creditsStep = 7;
if (u->o.houseID != g_playerHouseID) {
creditsStep += (Tools_Random_256() % 4) - 1;
…
creditsStep *= harvesterStep;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/script/structure.c#L146-L151h->credits += creditsStep;
u->amount -= harvesterStep;
…
s->o.script.delay = 6;Checked by claude, 2026-10-21 — read Script_Structure_RefineSpice at the pinned commit; the step is 3 only when hp × 256 / max is 256, and 1 when it is at most 170The computer's rate is rolled once per call and multiplies that call's whole step. How long a script tick lasts and how often BUILD.EMC calls the function are outside this code.
Cited by: Dune II, Pikmin, Resource harvesting
Each refinery stores 1,005 credits and each spice silo 1,000 (the structure table's defaults). On each house tick, credits above a house's storage are lost, except that the player keeps the mission's starting credits as a floor until storage passes them. OpenDUNE moved this check: its comment says the original ran it outside the per-house loop, and enhancement.txt says 1.07 thereby updated only the house that owns the latest structure. In the original mode, a structure still being built also counts toward storage. dune2/storage
About: Dune II Resource harvesting
Value
{
"refinery": 1005,
"silo": 1000
}src/table/structureinfo.c#L832/* creditsStorage */ 1005,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L1157/* creditsStorage */ 1000,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/house.c#L184-L197/* ENHANCEMENT -- Originally this code was outside the house loop, which seems very odd.
* This problem is considered to be so bad, that the original code has been removed. */
…
h->credits = h->creditsStorage;
…
uint16 maxCredits = max(h->creditsStorage, g_playerCreditsNoSilo);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/scenario.c#L78g_playerCreditsNoSilo = h->credits;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/house.c#L200-L203if (h->creditsStorage > g_playerCreditsNoSilo) {OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · enhancement.txt#L78-L79- Silo credit capping is done outside the main house loop, causing it to only
update the house which owns the latest structure. This allows you to goOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/house.c#L490-L491if (g_dune2_enhanced && s->o.flags.s.isNotOnMap) continue;Checked by claude, 2026-10-21 — read the two table rows, the clip in GameLoop_House, the starting-credits floor in scenario.c, and House_CalculatePowerAndCredit's enhanced skip at the pinned commitSince the original 1.07 check isn't in the code, the atlas can't say from this source exactly when 1.07 clipped a house's credits. PROFILE.INI's [construct] section can't replace a structure's storage.
Cited by: Resource harvesting
A factory or construction yard counts a build down from 256 × the item's build time. On each structure tick, every 30 game-timer ticks at normal game speed, a builder at full health takes 256 off the count (less for a computer house; dune2/ai-build-speed) and pays the build cost ÷ build time, carrying fractions of a credit in 1/256ths; a damaged builder takes off and pays only its share of full health (hit points × 256 ÷ maximum) each tick. When its owner can't pay a tick's share, the build waits, and a player's build goes on hold with a message. Computed: at full health an item takes its build time in structure ticks and costs about its build cost, which OpenDUNE's 60 Hz game timer makes half a second per unit of build time at normal speed. dune2/build-progress
About: Dune II Construction
Value
{
"tickTimerTicks": 30,
"countPerTimeUnit": 256,
"secondsPerTimeUnit": 0.5
}src/structure.c#L1665s->countDown = oi->buildTime << 8;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L66-L69s_tickStructureStructure = g_timerGame + Tools_AdjustToGameSpeed(30, 15, 60, true);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L175if (!s->o.flags.s.onHold && s->countDown != 0 && s->o.linkedID != 0xFF && s->state == STRUCTURE_STATE_BUSY && si->o.flags.factory) {OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L188-L215buildSpeed = 256;
if (s->o.hitpoints < si->o.hitpoints) {
buildSpeed = s->o.hitpoints * 256 / si->o.hitpoints;
…
buildCost = oi->buildCredits * 256 / oi->buildTime;
…
buildCost = buildSpeed * buildCost / 256;
…
buildCost += s->buildCostRemainder;
…
if (buildCost / 256 <= h->credits) {
s->buildCostRemainder = buildCost & 0xFF;
…OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L264-L269/* Out of money means the building gets put on hold */
if (s->o.houseID == g_playerHouseID) {
s->o.flags.s.onHold = true;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L1168Timer_Add(Timer_Tick, 1000000 / 60, false);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/timer.c#L364if ((s_timersActive & TIMER_GAME) != 0) g_timerGame++;Checked by claude, 2026-10-22 — read Structure_BuildObject's countdown, GameLoop_Structure's tick timer and factory branch, and OpenDUNE's timer setup at the pinned commit; Tools_AdjustToGameSpeed returns 30 at speed setting 2 and 15 to 60 at the othersThe repair facility runs through the same branch at a quarter of the cost (lines 204–206). The 60 Hz rate is OpenDUNE's timer; the atlas hasn't checked that the DOS executable's game timer ran at the same rate. Cancelling refunds the share of the cost that matches the progress made (line 1428).
Cited by: Construction, Dune II
A computer house builds at no more than (20 × mission index + 95)/256 of full speed, where the first mission is index 0, and pays per tick in the same proportion. Computed: 95/256, about 37%, in the first mission, rising to 255/256 in the ninth. dune2/ai-build-speed
About: Dune II Construction
Value
{
"base": 95,
"perMission": 20,
"outOf": 256
}src/structure.c#L193-L202/* For AIs, we slow down building speed in all but the last campaign */
if (g_playerHouseID != s->o.houseID) {
if (buildSpeed > g_campaignID * 20 + 95) buildSpeed = g_campaignID * 20 + 95;
…
buildCost = buildSpeed * buildCost / 256;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L288-L295g_campaignID++;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L931g_campaignID = 0;Checked by claude, 2026-10-22 — read the cap in GameLoop_Structure, and where g_campaignID starts at 0 and steps after a won mission, at the pinned commit; index 8 gives 255Cited by: Construction
The executable's structure table sets, among others, a concrete slab at 5 credits, 16 build-time units, and 20 hit points; a windtrap at 300, 48, and 200; a refinery at 400, 80, and 450; a spice silo at 150, 48, and 150; an outpost at 400, 80, and 500; a light factory at 400, 96, and 350; a heavy factory at 600, 144, and 200; and a palace at 999, 130, and 1,000. Each row also names the structures a house must own first and the first mission it can be built in; code moves the light factory's first mission from 3 to 2 for every house but the Harkonnen. PROFILE.INI, read from the game data at start, can replace a row's cost, time, hit points, and first mission, along with its fog radius and its build, target, and sort priorities. dune2/structure-table
Value
{
"concrete": {
"credits": 5,
"time": 16,
"hp": 20,
"mission": 1,
"requires": []
},
"windtrap": {
"credits": 300,
"time": 48,
"hp": 200,
"mission": 1,
"requires": []
},
"refinery": {
"credits": 400,
"time": 80,
"hp": 450,
"mission": 1,
"requires": [
"windtrap"
]
},
"silo": {
"credits": 150,
"time": 48,
"hp": 150,
"mission": 2,
"requires": [
"refinery",
"windtrap"
]
},
"outpost": {
"credits": 400,
"time": 80,
"hp": 500,
"mission": 2,
"requires": [
"windtrap"
]
},
"light-factory": {
"credits": 400,
"time": 96,
"hp": 350,
"mission": {
"harkonnen": 3,
"other": 2
},
"requires": [
"refinery",
"windtrap"
]
},
"heavy-factory": {
"credits": 600,
"time": 144,
"hp": 200,
"mission": 4,
"requires": [
"outpost",
"windtrap",
"light-factory"
]
},
"palace": {
"credits": 999,
"time": 130,
"hp": 1000,
"mission": 8,
"requires": [
"starport"
]
}
}src/table/structureinfo.c#L16-L41/* name */ "Concrete",
…
/* hitpoints */ 20,
…
/* buildCredits */ 5,
/* buildTime */ 16,
/* availableCampaign */ 1,
/* structuresRequired */ FLAG_STRUCTURE_NONE,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L601-L626/* name */ "Windtrap",
…
/* hitpoints */ 200,
…
/* buildCredits */ 300,
/* buildTime */ 48,
/* availableCampaign */ 1,
/* structuresRequired */ FLAG_STRUCTURE_NONE,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L796-L821/* name */ "Refinery",
…
/* hitpoints */ 450,
…
/* buildCredits */ 400,
/* buildTime */ 80,
/* availableCampaign */ 1,
/* structuresRequired */ FLAG_STRUCTURE_WINDTRAP,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L1121-L1146/* name */ "Spice Silo",
…
/* hitpoints */ 150,
…
/* buildCredits */ 150,
/* buildTime */ 48,
/* availableCampaign */ 2,
/* structuresRequired */ FLAG_STRUCTURE_REFINERY | FLAG_STRUCTURE_WINDTRAP,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L1186-L1211/* name */ "Outpost",
…
/* hitpoints */ 500,
…
/* buildCredits */ 400,
/* buildTime */ 80,
/* availableCampaign */ 2,
/* structuresRequired */ FLAG_STRUCTURE_WINDTRAP,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L211-L236/* name */ "Light Fctry",
…
/* hitpoints */ 350,
…
/* buildCredits */ 400,
/* buildTime */ 96,
/* availableCampaign */ 3,
/* structuresRequired */ FLAG_STRUCTURE_REFINERY | FLAG_STRUCTURE_WINDTRAP,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L276-L301/* name */ "Heavy Fctry",
…
/* hitpoints */ 200,
…
/* buildCredits */ 600,
/* buildTime */ 144,
/* availableCampaign */ 4,
/* structuresRequired */ FLAG_STRUCTURE_OUTPOST | FLAG_STRUCTURE_WINDTRAP | FLAG_STRUCTURE_LIGHT_VEHICLE,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L146-L171/* name */ "Palace",
…
/* hitpoints */ 1000,
…
/* buildCredits */ 999,
/* buildTime */ 130,
/* availableCampaign */ 8,
/* structuresRequired */ FLAG_STRUCTURE_STARPORT,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L568-L604Ini_GetString("construct", NULL, keys, keys, 2000, source);
…
oi->buildCredits = buildCredits;
oi->buildTime = buildTime;
oi->hitpoints = hitpoints;
oi->fogUncoverRadius = fogUncoverRadius;
oi->availableCampaign = availableCampaign;
oi->priorityBuild = priorityBuild;
oi->priorityTarget = priorityTarget;
…
oi->sortPriority = (uint8)sortPriority;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L1904-L1906if (s->o.houseID != HOUSE_HARKONNEN && i == STRUCTURE_LIGHT_VEHICLE) {
availableCampaign = 2;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L945ReadProfileIni("PROFILE.INI");Checked by claude, 2026-10-22 — read each row's name, hit points, cost, time, first mission, and requirements in src/table/structureinfo.c, and ReadProfileIni, at the pinned commitThe atlas hasn't read a 1.07 PROFILE.INI, so the values the game runs with may differ from this table where that file lists a structure. The build time counts structure ticks (dune2/build-progress).
Cited by: Tech tree
The player's construction yard offers a structure once the house owns every structure in its row's requirement set, the mission number has reached the row's first mission, the house may build it, and the yard's upgrade level is high enough. Two exceptions are coded: for the Harkonnen, the WOR, which trains troopers, needs no barracks and opens from the second mission; for other houses, the light factory opens from the second mission. A computer house's yard skips the requirement set and the upgrade level. dune2/prerequisites
src/structure.c#L1895-L1912if (i == STRUCTURE_WOR_TROOPER && s->o.houseID == HOUSE_HARKONNEN && g_campaignID >= 1) {
structuresRequired &= ~(1 << STRUCTURE_BARRACKS);
availableCampaign = 2;
…
if ((structuresBuilt & structuresRequired) == structuresRequired || s->o.houseID != g_playerHouseID) {
if (s->o.houseID != HOUSE_HARKONNEN && i == STRUCTURE_LIGHT_VEHICLE) {
availableCampaign = 2;
…
if (g_campaignID >= availableCampaign - 1 && (localsi->o.availableHouse & (1 << s->o.houseID)) != 0) {
if (s->upgradeLevel >= localsi->o.upgradeLevelRequired || s->o.houseID != g_playerHouseID) {Checked by claude, 2026-10-22 — read the construction-yard case of Structure_GetBuildable at the pinned commit; g_campaignID is 0 in the first mission, so `availableCampaign - 1` makes the row's number the 1-based missionThe Harkonnen exception applies from g_campaignID 1, the second mission, matching the availableCampaign it sets. Factories filter units the same way by requirement set and upgrade level, without the mission check (lines 1857–1876).
Cited by: Tech tree
A structure fits where every footprint tile is rock (entirely or mostly), a concrete slab, or a destroyed wall, with no unit or structure on it; slabs and the construction yard can't go on a slab. For the player, one of the tiles ringing the footprint, corners included, must also hold one of the player's structures, or a slab or wall the player owns; the construction yard is exempt, and a computer house's placement skips the check. For every structure but slabs and the construction yard, which never count missing slabs, the footprint tiles without a slab take (maximum hit points ÷ 2) × (tiles without a slab) ÷ (footprint tiles) off the new structure's starting hit points. Computed: such a structure placed with no slab starts at half health. dune2/placement
About: Dune II Structure placement
CodeOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) ·src/structure.c#L748-L784if (si->o.flags.notOnConcrete) {
if (!g_table_landscapeInfo[lst].isValidForStructure2 && g_validateStrictIfZero == 0) {
…
if (!g_table_landscapeInfo[lst].isValidForStructure && g_validateStrictIfZero == 0) {
…
if (lst != LST_CONCRETE_SLAB) neededSlabs++;
…
if (Object_GetByPackedTile(curPos) != NULL) {OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L786-L814if (g_validateStrictIfZero == 0 && isValid && type != STRUCTURE_CONSTRUCTION_YARD && !g_debugScenario) {
…
if (s->o.houseID != g_playerHouseID) continue;
…
if (lst != LST_CONCRETE_SLAB && lst != LST_WALL) continue;
if (g_map[curPos].houseID != g_playerHouseID) continue;
…
return -neededSlabs;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L1305-L1309const int16 g_table_structure_layoutTilesAround[STRUCTURE_LAYOUT_MAX][16] = {OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/landscapeinfo.c#L57-L74{ /* 4 / LST_ENTIRELY_ROCK */
…
/* isValidForStructure */ true,
…
{ /* 5 / LST_MOSTLY_ROCK */OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/landscapeinfo.c#L129-L134{ /* 10 / LST_CONCRETE_SLAB */
…
/* isValidForStructure */ true,
/* isSand */ false,
/* isValidForStructure2 */ false,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/landscapeinfo.c#L165-L170{ /* 13 / LST_DESTROYED_WALL */OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L16-L22/* notOnConcrete */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L530-L531if (validBuildLocation == 0 && s->o.houseID == g_playerHouseID && !g_debugScenario && g_validateStrictIfZero == 0) return false;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L549-L554/* If the return value is negative, there are tiles without slab. This gives a penalty to the hitpoints. */
…
s->o.hitpoints -= (si->o.hitpoints / 2) * tilesWithoutSlab / structureTileCount;Checked by claude, 2026-10-22 — read Structure_IsValidBuildLocation, the ring offsets, the landscape rows (only rows 4, 5, 10, and 13 allow structures; row 10 alone refuses notOnConcrete ones), and Structure_Place at the pinned commit; the construction yard's row also sets notOnConcrete (structureinfo.c line 542)The adjacency test compares against g_playerHouseID whoever is building, so it can only serve the player; Structure_Place's refusal also applies to the player alone. Every structure's maximum hit points in the default table is even, so a structure with no slab starts at exactly half.
Cited by: Dune II, Structure placement
The executable's unit table sets hit points, speed (out of 256), range in tiles, fire delay, and damage per shot: the Trike 100, 45, 3, 50, and 5; the Quad 130, 40, 3, 50, and 7; the combat tank 200, 25, 4, 80, and 25; the siege tank 300, 20, 5, 90, and 30; the rocket launcher 100, 30, 9, 120, and 75; the Devastator 400, 10, 5, 100, and 40; and the sonic tank 110, 30, 8, 80, and 60. PROFILE.INI, read from the game data at start, can replace any of these. dune2/unit-table
About: Dune II Damage formula
Value
{
"trike": {
"hp": 100,
"speed": 45,
"range": 3,
"fireDelay": 50,
"damage": 5,
"credits": 150,
"time": 40
},
"quad": {
"hp": 130,
"speed": 40,
"range": 3,
"fireDelay": 50,
"damage": 7,
"credits": 200,
"time": 48
},
"tank": {
"hp": 200,
"speed": 25,
"range": 4,
"fireDelay": 80,
"damage": 25,
"credits": 300,
"time": 64
},
"siege-tank": {
"hp": 300,
"speed": 20,
"range": 5,
"fireDelay": 90,
"damage": 30,
"credits": 600,
"time": 96
},
"launcher": {
"hp": 100,
"speed": 30,
"range": 9,
"fireDelay": 120,
"damage": 75,
"credits": 450,
"time": 72
},
"devastator": {
"hp": 400,
"speed": 10,
"range": 5,
"fireDelay": 100,
"damage": 40,
"credits": 800,
"time": 104
},
"sonic-tank": {
"hp": 110,
"speed": 30,
"range": 8,
"fireDelay": 80,
"damage": 60,
"credits": 600,
"time": 104
}
}src/table/unitinfo.c#L967-L1031/* name */ "Trike",
…
/* hitpoints */ 100,
…
/* buildCredits */ 150,
/* buildTime */ 40,
…
/* movingSpeedFactor */ 45,
…
/* fireDelay */ 50,
/* fireDistance */ 3,
/* damage */ 5,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1113-L1177/* name */ "Quad",
…
/* hitpoints */ 130,
…
/* buildCredits */ 200,
/* buildTime */ 48,
…
/* movingSpeedFactor */ 40,
…
/* fireDelay */ 50,
/* fireDistance */ 3,
/* damage */ 7,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L675-L739/* name */ "Tank",
…
/* hitpoints */ 200,
…
/* buildCredits */ 300,
/* buildTime */ 64,
…
/* movingSpeedFactor */ 25,
…
/* fireDelay */ 80,
/* fireDistance */ 4,
/* damage */ 25,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L748-L812/* name */ "Siege Tank",
…
/* hitpoints */ 300,
…
/* buildCredits */ 600,
/* buildTime */ 96,
…
/* movingSpeedFactor */ 20,
…
/* fireDelay */ 90,
/* fireDistance */ 5,
/* damage */ 30,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L529-L593/* name */ "Launcher",
…
/* hitpoints */ 100,
…
/* buildCredits */ 450,
/* buildTime */ 72,
…
/* movingSpeedFactor */ 30,
…
/* fireDelay */ 120,
/* fireDistance */ 9,
/* damage */ 75,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L821-L885/* name */ "Devastator",
…
/* hitpoints */ 400,
…
/* buildCredits */ 800,
/* buildTime */ 104,
…
/* movingSpeedFactor */ 10,
…
/* fireDelay */ 100,
/* fireDistance */ 5,
/* damage */ 40,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L894-L958/* name */ "Sonic Tank",
…
/* hitpoints */ 110,
…
/* buildCredits */ 600,
/* buildTime */ 104,
…
/* movingSpeedFactor */ 30,
…
/* fireDelay */ 80,
/* fireDistance */ 8,
/* damage */ 60,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.h#L197uint16 movingSpeedFactor; /*!< Factor speed of movement of Unit, where 256 is full speed. */OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/script/unit.c#L607-L609if ((int16)(ui->fireDistance << 8) < (int16)distance) return 0;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L629-L651Ini_GetString("combat", NULL, keys, keys, 2000, source);
…
ui->damage = damage;
ui->movingSpeedFactor = movingSpeedFactor;
ui->fireDelay = fireDelay;
ui->fireDistance = fireDistance;Checked by claude, 2026-10-22 — read each unit's row in src/table/unitinfo.c and the [combat] reader in ReadProfileIni at the pinned commit; range is compared in 1/256 tiles against fireDistance << 8The table names the combat tank "Tank" and the rocket launcher "Launcher". The value also carries each unit's cost and build time from the same rows. The atlas hasn't read a PROFILE.INI from the 1.07 data files.
A shot carries its unit's table damage, with no roll; only troopers and trooper squads firing beyond 2 tiles switch to a missile at damage − damage/4. The whole damage applies only at the point of impact, where a unit, or a structure on the impact tile, loses it from its hit points, down to 0, with no armor or defense stat; units farther from the point take less (dune2/splash). Units flagged to fire twice (among them the Trike, Quad, rocket launcher, siege tank, and Devastator) follow a shot with a second after a delay of 5 rather than twice their fire delay (at normal game speed), but only while above half health; every fire delay gets 0 or 1 added at random. dune2/weapon-damage
About: Dune II Damage formula
CodeOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) ·src/script/unit.c#L623-L628damage = ui->damage;
…
fireTwice = ui->flags.firesTwice && u->o.hitpoints > ui->o.hitpoints / 2;
…
if ((u->o.type == UNIT_TROOPERS || u->o.type == UNIT_TROOPER) && (int16)distance > 512) typeID = UNIT_MISSILE_TROOPER;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/script/unit.c#L658-L659damage -= damage / 4;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/script/unit.c#L683-L692u->fireDelay = Tools_AdjustToGameSpeed(ui->fireDelay * 2, 1, 0xFFFF, true);
…
if (u->o.flags.s.fireTwiceFlip) u->fireDelay = Tools_AdjustToGameSpeed(5, 1, 10, true);
…
u->fireDelay += Tools_Random_256() & 1;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/map.c#L427-L431Unit_Damage(u, hitpoints >> (distance >> 2), 0);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L1544-L1548if (unit->o.hitpoints >= damage) {
unit->o.hitpoints -= damage;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L1049-L1053if (s->o.hitpoints >= damage) {
s->o.hitpoints -= damage;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1012/* firesTwice */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1158/* firesTwice */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L574/* firesTwice */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L793/* firesTwice */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L866/* firesTwice */ true,Checked by claude, 2026-10-22 — read Script_Unit_Fire, Unit_Damage, and Structure_Damage at the pinned commit, and the firesTwice flag in the Trike (L967), Quad (L1113), Launcher (L529), Siege Tank (L748), and Devastator (L821) rows; distance 512 is 2 tiles in 1/256-tile unitsThe 'Thopter, light infantry, trooper squad, and Raider Trike rows also set firesTwice. Fire delays count unit ticks, and Tools_AdjustToGameSpeed scales them at game speeds other than normal. How far damage spreads from the impact point is dune2/splash.
Cited by: Dune II
A shell or missile damages where it explodes, not the unit it was fired at: the explosion damages every unit within one tile of the point (two for the Death Hand explosion), its own side's included, by the damage halved once per quarter tile of distance, so full within a quarter tile, half to a half, a quarter to three quarters, and an eighth to one tile; the frigate and bullets in flight take none. A structure on the impact tile takes the full damage. A shell flies to the target's position at the moment of firing and explodes there, or earlier on a wall, structure, or mountain tile in its path; a turret's shell passes over its own side's walls and structures. dune2/splash
About: Dune II Damage formula
Value
{
"radiusTiles": 1,
"halvingStepTiles": 0.25
}src/map.c#L405-L431uint16 reactionDistance = (type == EXPLOSION_DEATH_HAND) ? 32 : 16;
…
distance = Tile_GetDistance(position, u->o.position) >> 4;
if (distance >= reactionDistance) continue;
…
if (!(u->o.type == UNIT_SANDWORM && type == EXPLOSION_SANDWORM_SWALLOW) && u->o.type != UNIT_FRIGATE) {
Unit_Damage(u, hitpoints >> (distance >> 2), 0);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/map.c#L488-L501Structure *s = Structure_Get_ByPackedTile(positionPacked);
…
Structure_Damage(s, hitpoints, 0);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L1540if (!ui->flags.isNormalUnit && unit->o.type != UNIT_SANDWORM) return false;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L1981-L1983bullet->targetAttack = target;
bullet->o.hitpoints = damage;
bullet->currentDestination = tile;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L2020-L2021bullet->currentDestination = tile;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L1438-L1444Map_MakeExplosion((ui->explosionType + unit->o.hitpoints / 20) & 3, newPosition, unit->o.hitpoints, unit->originEncoded);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.c#L1399-L1412if (unit->o.type == UNIT_BULLET) {
…
if (g_map[Tile_PackTile(newPosition)].houseID == unit->o.houseID) {
…
if (type == LST_WALL || type == LST_STRUCTURE || type == LST_ENTIRELY_MOUNTAIN) {OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/tile.c#L39-L45if (distance_x > distance_y) return distance_x + (distance_y / 2);Checked by claude, 2026-10-22 — read Map_MakeExplosion's unit loop and structure hit, Unit_Damage's guard, Unit_CreateBullet, and the bullet's impact paths in Unit_Move at the pinned commit; Tile_GetDistance is in 1/256 tiles, so >> 4 gives sixteenths and >> 2 of that counts quarter tilesDistance is the larger axis plus half the smaller, so the radius is a rounded octagon rather than a circle. Bullets (the shells of tanks and light units) carry their damage as their own hit points. A missile flagged inaccurate lands off target (dune2/missile-scatter). The Deviator's missile converts units instead of damaging them (unit.c line 1441–1442).
Cited by: Dune II
The rocket launcher's and the Deviator's missiles aim at a random point near the target. 15 times in 16 the miss distance is a random byte halved until it is at most 8 + the distance to the target in whole tiles, and 1 time in 16 at most 8 + a second random byte, in sixteenths of a tile, in a random direction. The rocket turret's missiles carry no such flag and fly to the target point. dune2/missile-scatter
About: Dune II Hit chance
CodeOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) ·src/unit.c#L1985-L1987if (ui->flags.notAccurate) {
bullet->currentDestination = Tile_MoveByRandom(tile, (Tools_Random_256() & 0xF) != 0 ? Tile_GetDistance(position, tile) / 256 + 8 : Tools_Random_256() + 8, false);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/tile.c#L319-L325newDistance = Tools_Random_256();
while (newDistance > distance) newDistance /= 2;
…
orientation = Tools_Random_256();
x += ((_stepX[orientation] * distance) / 128) * 16;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1405-L1454/* name */ "Rocket",
…
/* notAccurate */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1551-L1600/* name */ "GRocket",
…
/* notAccurate */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L1478-L1527/* name */ "ARocket",
…
/* notAccurate */ false,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/unit.h#L31-L33UNIT_MISSILE_ROCKET = 19,
UNIT_MISSILE_TURRET = 20,
UNIT_MISSILE_DEVIATOR = 21,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L595/* bulletType */ UNIT_MISSILE_ROCKET,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/unitinfo.c#L668/* bulletType */ UNIT_MISSILE_DEVIATOR,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/script/structure.c#L529type = UNIT_MISSILE_TURRET;Checked by claude, 2026-10-22 — read Unit_CreateBullet's missile branch and Tile_MoveByRandom at the pinned commit, and matched the table rows to the enum: Rocket is row 19, ARocket 20, GRocket 21; the Launcher (L529) and Deviator (L602) rows name their missiles, and the turret's fire function picks UNIT_MISSILE_TURRETTile_MoveByRandom's step moves (stepX × distance / 128) × 16 in 1/256-tile units, so the distance counts sixteenths of a tile. The halving makes short misses far more common than long ones.
Cited by: Dune II
From the third mission on, every 10,800 game-timer ticks at normal game speed, each structure marked as degrading loses hit points while it stands above half its table maximum: 3 for the Harkonnen, 2 for the Ordos, and 1 for every other house. Placement marks a structure when any footprint tile lacks a concrete slab, except a construction yard, which never counts missing slabs; in the original mode it marks every structure placed, slabs or not, and OpenDUNE's enhanced mode (the default) leaves a construction yard and a structure built wholly on slabs unmarked. Structures a scenario places start unmarked, and slabs and walls never decay. Computed: OpenDUNE's 60 Hz timer makes the interval 3 minutes, and a structure placed with no slab, which starts at half health, doesn't decay until repaired above it. dune2/decay
About: Dune II Structure decay
Value
{
"intervalTimerTicks": 10800,
"intervalSeconds": 180,
"amount": {
"harkonnen": 3,
"ordos": 2,
"other": 1
},
"floor": 0.5,
"fromMission": 3
}src/structure.c#L61-L63if (s_tickStructureDegrade <= g_timerGame && g_campaignID > 1) {
tickDegrade = true;
s_tickStructureDegrade = g_timerGame + Tools_AdjustToGameSpeed(10800, 5400, 21600, true);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L95if (s->o.type == STRUCTURE_SLAB_1x1 || s->o.type == STRUCTURE_SLAB_2x2 || s->o.type == STRUCTURE_WALL) continue;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L121-L122if (tickDegrade && s->o.flags.s.degrades && s->o.hitpoints > si->o.hitpoints / 2) {
Structure_Damage(s, hi->degradingAmount, 0);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/houseinfo.c#L9-L12/* name */ "Harkonnen",
…
/* degradingAmount */ 3,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/houseinfo.c#L41-L44/* name */ "Ordos",
…
/* degradingAmount */ 2,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/houseinfo.c#L25-L92/* degradingAmount */ 1,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L550-L561if (validBuildLocation < 0) {
…
s->o.flags.s.degrades = true;
} else {
/* ENHANCEMENT -- When you build a structure completely on slabs, it should not degrade */
if (!g_dune2_enhanced) {
s->o.flags.s.degrades = true;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L766-L777if (si->o.flags.notOnConcrete) {
…
if (lst != LST_CONCRETE_SLAB) neededSlabs++;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/table/structureinfo.c#L536-L542/* notOnConcrete */ true,OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/scenario.c#L284-L285s->o.flags.s.degrades = false;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/opendune.c#L1168Timer_Add(Timer_Tick, 1000000 / 60, false);Checked by claude, 2026-10-22 — read GameLoop_Structure's decay timer and test, the house table's degradingAmount for all six houses (Atreides, Fremen, Sardaukar, and Mercenary are 1), Structure_Place's marking, and the scenario loader at the pinned commit; g_campaignID > 1 is the third mission, as it counts from 0enhancement.txt lists the original behavior as a bug ("When building a structure completely on slabs, it still degrades"). In the original mode, then, concrete spares a structure only the starting hit-point penalty (dune2/placement). Units also carry a degrades flag, with a separate 1-hit-point roll as they move (unit.c line 1457).
Cited by: Dune II, Structure decay
A computer house's construction yard builds only structures the house has lost. Removing a structure records its type and position in the first free of five slots per house; while the house's AI is active and it has credits, an idle yard builds the first recorded type it can build, places the finished structure at once at the recorded position, and clears the slot. If no slot matches or placement fails at every match, the house gets the cost back and the structure is dropped. dune2/ai-rebuild
About: Dune II Construction
CodeOpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) ·src/structure.c#L1338-L1342for (i = 0; i < 5; i++) {
if (h->ai_structureRebuild[i][0] != 0) continue;
h->ai_structureRebuild[i][0] = s->o.type;
h->ai_structureRebuild[i][1] = packed;OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L1993-L2003if (s->o.type == STRUCTURE_CONSTRUCTION_YARD) {
for (i = 0; i < 5; i++) {
type = h->ai_structureRebuild[i][0];OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L308-L319/* AI maintenance on structures */
if (h->flags.isAIActive && s->o.flags.s.allocated && s->o.houseID != g_playerHouseID && h->credits != 0) {
…
if (si->o.flags.factory && s->countDown == 0 && s->o.linkedID == 0xFF) {
uint16 type = Structure_AI_PickNextToBuild(s);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/structure.c#L240-L261/* The AI places structures which are operational immediately */
…
if (!Structure_Place(ns, h->ai_structureRebuild[i][1])) continue;
…
/* If the AI no longer had in memory where to store the structure, free it and forget about it */
…
h->credits += nsi->o.buildCredits;Checked by claude, 2026-10-22 — read Structure_Remove's slot loop, the construction-yard case of Structure_AI_PickNextToBuild, the AI maintenance block, and the completion branch in GameLoop_Structure at the pinned commit; Structure_BuildObject has no other caller for a computer house's yardA sixth loss while five slots are full isn't recorded. Slot type 0 marks a free slot, and 0 is also the concrete slab's type, so a lost slab is never rebuilt. The same maintenance block has a computer house start repairing any structure below half health. Other factories pick units by build priority with a 1-in-4 random override (lines 2026–2036).
Cited by: Construction, Dune II
The first time a computer house's structure is hit, Structure_HouseUnderAttack sets the house's full-scale-attack flag and, in OpenDUNE's enhanced mode (the default), sends its armed units on area guard to hunt. In the original mode the routine returns after setting the flag: OpenDUNE's comment says Dune II searched only for carryalls (unit type 0), so the rest did nothing, and enhancement.txt adds that the bug "makes the game much easier in its original form". dune2/ai-retaliation
src/structure.c#L1940-L1971if (houseID != g_playerHouseID && h->flags.doneFullScaleAttack) return;
h->flags.doneFullScaleAttack = true;
…
/* ENHANCEMENT -- Dune2 originally only searches for units with type 0 (Carry-all). In result, the rest of this function does nothing. */
if (!g_dune2_enhanced) return;
…
if (ui->bulletType == UNIT_INVALID) continue;
…
if ((u->actionID == ACTION_GUARD && u->actionID == ACTION_AMBUSH) || u->actionID == ACTION_AREA_GUARD) Unit_SetAction(u, ACTION_HUNT);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · src/map.c#L500Structure_HouseUnderAttack(s->o.houseID);OpenDUNE: a C re-creation of Dune II from its DOS executable (OpenDUNE/OpenDUNE) · enhancement.txt#L39-L42- When you attack the structure of the AI, the idea is that they massively
start to attack you (payback and stuff). To do this, Dune2 searches all
Units with type 0 (Carry-alls), instead of type 0xFFFF (all units).
WARNING: this glitch makes the game much easier in its original form.Checked by claude, 2026-10-22 — read Structure_HouseUnderAttack and its caller in Map_MakeExplosion at the pinned commit; the guard-and-ambush test can never be true, so only area-guard units switchThe original search isn't in OpenDUNE's code; the claim about what 1.07 did rests on the project's comment and enhancement list. No other code reads the flag; OpenDUNE clears it only for the player's house (opendune.c line 337), which takes a different branch of the routine.
Cited by: Dune II