data/claims/doom.yamlDoom (id Software's Linux source release, linuxdoom-1.10)
Game: Doom.
id Software's released Doom source is version 1.10 of the Linux port: doomdef.h sets VERSION to 110, and John Carmack's README, signed 1997-12-23, says the code "only compiles and runs on linux" because the DOS code's sound library could not be released. doom/source-version
Value: 110
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/doomdef.h#L33enum { VERSION = 110 };DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · README.TXT#L12-L14The bad news: this code only compiles and runs on linux. We couldn't
release the dos code because of a copyrighted sound library we usedDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · README.TXT#L77-L78John Carmack
12-23-97Checked by claude, 2026-10-21 — read doomdef.h's version enum and the README at the pinned commitEvery other Doom claim here reads this Linux code. The DOS 1.9 executable is not in the release, so a claim holds for DOS only as far as the two share game code.
Cited by: Doom
Doom's game logic runs in tics of 1/35 second (TICRATE 35). doom/tic-rate
Value: 35 tics/s
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/doomdef.h#L121-L122// State updates, number of tics / second.
#define TICRATE 35Checked by claude, 2026-10-21 — read the define at the pinned commitCited by: Doom
Doom's random numbers come from rndtable, a fixed table of 256 bytes, walked by two indices: each call to P_Random or M_Random adds 1 to its own index, wraps it at 256, and returns that table entry. doom/rng
About: Doom Random number generator
Value: 256 entries
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/m_random.c#L31-L32unsigned char rndtable[256] = {
0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66 ,DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/m_random.c#L53-L67int rndindex = 0;
int prndindex = 0;
…
// Which one is deterministic?
int P_Random (void)
{
prndindex = (prndindex+1)&0xff;
return rndtable[prndindex];
}
…
int M_Random (void)
{
…Checked by claude, 2026-10-21 — read the table and both functions; each pre-increments its own index, masked to 8 bitsBecause the index steps before the read, the first call after a reset returns entry 1 (8), and entry 0 comes up only on the 256th call. The comment "Which one is deterministic?" is id's own.
Cited by: Doom
Doom's play code (weapon damage, aim spread, pain) rolls P_Random, and M_Random serves the rest: the screen wipe, sound pitch, intermission animations, and the status bar. doom/rng-streams
About: Doom Random number generator
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_pspr.c#L633-L637damage = 5*(P_Random ()%3+1);
angle = mo->angle;
…
angle += (P_Random()-P_Random())<<18;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_inter.c#L894if ( (P_Random () < target->info->painchance)DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_wipe.c#L159y[0] = -(M_Random()%16);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/s_sound.c#L326-L330// hacks to vary the sfx pitches
…
pitch += 8 - (M_Random()&15);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/wi_stuff.c#L523a->nexttic = bcnt + 1 + (M_Random()%a->period);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/st_stuff.c#L992st_randomnumber = M_Random();Checked by claude, 2026-10-21 — grepped every M_Random call in linuxdoom-1.10 (st_stuff.c, f_wipe.c, wi_stuff.c, s_sound.c only); the play files p_*.c call P_RandomThe split keeps cosmetic draws off the play sequence, so a wipe or a sound doesn't shift a later damage roll. The code shows the split; why id made it is not stated beyond the comment quoted under doom/rng.
Cited by: Doom
G_InitNew resets both of Doom's random indices to 0, and it runs when a new game starts, when a saved game loads, when a demo starts playing, and when the command line starts a game directly (a warp or autostart, or a net game). doom/rng-reset
About: Doom Random number generator
Value: 0
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/m_random.c#L69-L72void M_ClearRandom (void)
{
rndindex = prndindex = 0;
}DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L1414M_ClearRandom ();DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L1345-L1356void G_DoNewGame (void)
…
G_InitNew (d_skill, d_episode, d_map);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L1226-L1227// load a base level
G_InitNew (gameskill, gameepisode, gamemap);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L1613-L1615// don't spend a lot of time in loadlevel
precache = false;
G_InitNew (skill, episode, map);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/d_main.c#L1161-L1164if ( gameaction != ga_loadgame )
{
if (autostart || netgame)
G_InitNew (startskill, startepisode, startmap);Checked by claude, 2026-10-21 — M_ClearRandom has one caller, G_InitNew (L1414); G_InitNew's callers are G_DoLoadGame (L1227), G_DoNewGame (L1356), G_DoPlayDemo (L1615), and D_DoomMain's command-line start (d_main.c L1164)Moving to the next map does not call G_InitNew, so the play index carries over between maps within a game.
Cited by: Doom
Doom's rndtable is not a permutation: its 256 entries hold 166 distinct values, 101 of them once, 45 twice, 16 three times, 3 four times, and 1 five times; the value 145 appears 5 times and the value 0 twice. doom/rng-table
About: Doom Random number generator
Value
{
"distinct": 166,
"once": 101,
"twice": 45,
"thrice": 16,
"four-times": 3,
"five-times": 1
}linuxdoom-1.10/m_random.c#L31-L51unsigned char rndtable[256] = {
…
120, 163, 236, 249
};Checked by claude, 2026-10-21 — extracted the 256 numbers from L32-L50 and counted them (sort | uniq -c, then counted the counts); 0 sits at entries 0 and 83, and the values sum to 32,986, a mean of 128.85Final Fantasy's battle table is likewise not a permutation (see ff1/rng-table), but Doom's repeats far more.
Each bullet from Doom's pistol, chaingun, or shotgun deals 5*(P_Random()%3+1), so 5, 10, or 15; the shotgun fires 7 such pellets. Over one pass of the table the multipliers 1, 2, and 3 come up 75, 88, and 93 times. doom/bullet-damage
About: Doom Damage formula
Value
[ 5, 10, 15 ]
linuxdoom-1.10/p_pspr.c#L625-L639P_GunShot
…
damage = 5*(P_Random ()%3+1);
…
P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L660-L661P_BulletSlope (player->mo);
P_GunShot (player->mo, !player->refire);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L684-L687P_BulletSlope (player->mo);
…
for (i=0 ; i<7 ; i++)
P_GunShot (player->mo, false);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L751-L753P_BulletSlope (player->mo);
…
P_GunShot (player->mo, !player->refire);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/m_random.c#L31-L51unsigned char rndtable[256] = {
…
};Checked by claude, 2026-10-21 — read P_GunShot and its three callers (A_FirePistol, A_FireShotgun, A_FireCGun); counted rndtable's entries mod 3 (0 → 75, 1 → 88, 2 → 93)The counts make the mean over a full pass 5 × 530/256 ≈ 10.35, a little above the 10 a uniform byte would give. No defense stat enters; only a player's armor reduces damage (doom/armor).
Cited by: Doom
Doom's fist deals (P_Random()%10+1)<<1, 2 to 20, multiplied by 10 while the player has the berserk strength power; the chainsaw deals 2 to 20. doom/melee-damage
About: Doom Damage formula
Value
[ 2, 20 ]
linuxdoom-1.10/p_pspr.c#L476-L479damage = (P_Random ()%10+1)<<1;
…
if (player->powers[pw_strength])
damage *= 10;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L510damage = 2*(P_Random ()%10+1);Checked by claude, 2026-10-21 — read A_Punch and A_SawA Doom projectile that hits a shootable thing, other than a monster of its shooter's species, deals ((P_Random()%8)+1) times its type's damage value: a rocket's 20 gives 20 to 160, a plasma ball's 5 gives 5 to 40, a BFG ball's 100 gives 100 to 800, and an imp's fireball's 3 gives 3 to 24. doom/missile-damage
About: Doom Damage formula
Value
[ 1, 8 ]
linuxdoom-1.10/p_map.c#L290-L291// missiles can hit other things
if (tmthing->flags & MF_MISSILE)DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L322-L324// damage / explode
damage = ((P_Random()%8)+1)*tmthing->info->damage;
P_DamageMobj (thing, tmthing, tmthing->target, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1966-L1986{ // MT_ROCKET
…
20, // damageDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1992-L2012{ // MT_PLASMA
…
5, // damageDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L2018-L2038{ // MT_BFG
…
100, // damageDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1914-L1934{ // MT_TROOPSHOT
…
3, // damageDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L931P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);Checked by claude, 2026-10-21 — read PIT_CheckThing's missile branch and the damage field of each mobjinfo entry; A_TroopAttack (the imp) launches MT_TROOPSHOTThe roll happens only when the projectile touches a shootable thing; a rocket's blast (doom/rocket-blast) and the BFG's tracers (doom/bfg-spray) come on top.
Cited by: Doom
A Doom rocket's explosion deals 128 minus the distance to each shootable thing in sight of the blast, measured as the larger of the x and y gaps less the thing's radius, and the Cyberdemon and Spider Mastermind take none. doom/rocket-blast
About: Doom Damage formula
Value: 128 HP
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/info.c#L1966-L1979{ // MT_ROCKET
…
S_EXPLODE1, // deathstateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L263{SPR_MISL,32769,8,{A_Explode},S_EXPLODE2,0,0}, // S_EXPLODE1DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L1598-L1600void A_Explode (mobj_t* thingy)
{
P_RadiusAttack ( thingy, thingy->target, 128 );DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L1173-L1194// Boss spider and cyborg
// take no damage from concussion.
if (thing->type == MT_CYBORG
|| thing->type == MT_SPIDER)
return true;
…
dist = dx>dy ? dx : dy;
dist = (dist - thing->radius) >> FRACBITS;
…
if ( P_CheckSight (thing, bombspot) )
{
// must be in direct path
…Checked by claude, 2026-10-21 — traced MT_ROCKET's death state to A_Explode, then read PIT_RadiusAttackThe distance is in whole map units and clamps at 0, so a thing touching the blast takes 128. The same blast hurts the player who fired it, since only the two bosses are skipped.
Cited by: Doom
When a Doom BFG ball's explosion reaches its third frame, 40 traces fan across 90° around the ball's heading, each starting from the player who fired it and reaching 1,024 units, and each trace that finds a target deals the sum of 15 rolls of 1 to 8, so 15 to 120. doom/bfg-spray
About: Doom Damage formula
Value
[ 15, 120 ]
linuxdoom-1.10/info.c#L253-L255{SPR_BFE1,32768,8,{NULL},S_BFGLAND2,0,0}, // S_BFGLAND
…
{SPR_BFE1,32770,8,{A_BFGSpray},S_BFGLAND4,0,0}, // S_BFGLAND3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L789-L809for (i=0 ; i<40 ; i++)
{
an = mo->angle - ANG90/2 + ANG90/40*i;
…
P_AimLineAttack (mo->target, an, 16*64*FRACUNIT);
…
damage = 0;
for (j=0;j<15;j++)
damage += (P_Random()&7) + 1;
…
P_DamageMobj (linetarget, mo->target,mo->target, damage);Checked by claude, 2026-10-21 — read A_BFGSpray and the BFG ball's death states (S_BFGLAND, S_BFGLAND2, then S_BFGLAND3 calls A_BFGSpray)The comment on L793 says mo->target "is the originator (player)". The traces start where the player stands when the spray runs, so the player's position, not the ball's, decides what they reach.
Cited by: Doom
Doom's monster attacks use the same multiple-of-a-base form: a zombieman's bullet deals ((P_Random()%5)+1)*3, 3 to 15; an imp's claw (P_Random()%8+1)*3, 3 to 24; a demon's bite ((P_Random()%10)+1)*4, 4 to 40; and a Baron of Hell's claw (P_Random()%8+1)*10, 10 to 80, an attack function (A_BruisAttack) the code shares with Doom II's Hell Knight (MT_KNIGHT). doom/monster-damage
About: Doom Damage formula
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_enemy.c#L802-L818void A_PosAttack (mobj_t* actor)
…
damage = ((P_Random()%5)+1)*3;
P_LineAttack (actor, angle, MISSILERANGE, slope, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L913-L925void A_TroopAttack (mobj_t* actor)
…
if (P_CheckMeleeRange (actor))
{
S_StartSound (actor, sfx_claw);
damage = (P_Random()%8+1)*3;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L935-L945void A_SargAttack (mobj_t* actor)
…
damage = ((P_Random()%10)+1)*4;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L979-L989void A_BruisAttack (mobj_t* actor)
…
damage = (P_Random()%8+1)*10;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L340-L349castinfo_t castorder[] = {
{CC_ZOMBIE, MT_POSSESSED},
…
{CC_IMP, MT_TROOP},
{CC_DEMON, MT_SERGEANT},
…
{CC_BARON, MT_BRUISER},DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/d_englsh.h#L677-L685#define CC_ZOMBIE "ZOMBIEMAN"
…
#define CC_IMP "IMP"
#define CC_DEMON "DEMON"
…
#define CC_BARON "BARON OF HELL"DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L320-L321{SPR_POSS,4,10,{A_FaceTarget},S_POSS_ATK2,0,0}, // S_POSS_ATK1
{SPR_POSS,5,8,{A_PosAttack},S_POSS_ATK3,0,0}, // S_POSS_ATK2DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1134-L1146{ // MT_POSSESSED
…
S_POSS_ATK1, // missilestateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L588-L590{SPR_TROO,4,8,{A_FaceTarget},S_TROO_ATK2,0,0}, // S_TROO_ATK1
…
{SPR_TROO,6,6,{A_TroopAttack},S_TROO_RUN1,0,0}, // S_TROO_ATK3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1394-L1405{ // MT_TROOP
…
S_TROO_ATK1, // meleestateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L621-L623{SPR_SARG,4,8,{A_FaceTarget},S_SARG_ATK2,0,0}, // S_SARG_ATK1
…
{SPR_SARG,6,8,{A_SargAttack},S_SARG_RUN1,0,0}, // S_SARG_ATK3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1420-L1431{ // MT_SERGEANT
…
S_SARG_ATK1, // meleestateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L673-L675{SPR_BOSS,4,8,{A_FaceTarget},S_BOSS_ATK2,0,0}, // S_BOSS_ATK1
…
{SPR_BOSS,6,8,{A_BruisAttack},S_BOSS_RUN1,0,0}, // S_BOSS_ATK3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1498-L1509{ // MT_BRUISER
…
S_BOSS_ATK1, // meleestateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L702-L704{SPR_BOS2,4,8,{A_FaceTarget},S_BOS2_ATK2,0,0}, // S_BOS2_ATK1
…
{SPR_BOS2,6,8,{A_BruisAttack},S_BOS2_RUN1,0,0}, // S_BOS2_ATK3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1550-L1561{ // MT_KNIGHT
…
S_BOS2_ATK1, // meleestateDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L348{CC_HELL, MT_KNIGHT},DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L212-L223if ( (gamemode == commercial)
…
if (gamemap == 30)
F_StartCast ();Checked by claude, 2026-10-21 — read each action function, then traced each type's attack state in info.c (MT_POSSESSED's missilestate S_POSS_ATK1 leads to A_PosAttack; MT_TROOP, MT_SERGEANT, MT_BRUISER, and MT_KNIGHT's meleestate chains end in A_TroopAttack, A_SargAttack, A_BruisAttack, and A_BruisAttack); the cast list, run only in commercial (DOOM 2) mode, names MT_KNIGHT the HELL KNIGHTThe names come from the cast call's list in f_finale.c and d_englsh.h. The Baron of Hell's claw is its melee branch; at range it throws MT_BRUISERSHOT (damage value 8) instead.
Damage to a Doom player is halved on the easiest skill (sk_baby), and then armor takes a share: a third with the armor pickup (type 1) and half with the MegaArmor (type 2), until its points run out; monsters have no armor or defense value. doom/armor
About: Doom Damage formula
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_inter.c#L798-L800player = target->player;
if (player && gameskill == sk_baby)
damage >>= 1; // take half damage in trainer modeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_inter.c#L854-L869if (player->armortype)
{
if (player->armortype == 1)
saved = damage/3;
else
saved = damage/2;
…
if (player->armorpoints <= saved)
{
// armor is used up
saved = player->armorpoints;
player->armortype = 0;
…DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_inter.c#L370-L380case SPR_ARM1:
if (!P_GiveArmor (player, 1))
…
case SPR_ARM2:
if (!P_GiveArmor (player, 2))DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/d_englsh.h#L80-L81#define GOTARMOR "Picked up the armor."
#define GOTMEGA "Picked up the MegaArmor!"DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_inter.c#L886-L887// do the damage
target->health -= damage;Checked by claude, 2026-10-21 — read P_DamageMobj from the top to the health subtraction; the armor block sits inside `if (player)`, and nothing else between the call and L887 reduces damageP_GiveArmor sets the points to 100 times the type (L258), so 100 for armor and 200 for MegaArmor. God mode and invulnerability ignore damage under 1000 (L847-L852).
Cited by: Difficulty level
Doom's bullets and melee are hitscan: P_LineAttack traces a line in the same tic, out to 2,048 units for guns and 64 for melee, and damages the first shootable thing whose height spans the shot's slope; rockets, plasma, and BFG balls are objects spawned by P_SpawnPlayerMissile that move each tic at their type's speed (20, 25, and 25 units per tic). doom/hitscan
Value
{
"guns": 2048,
"melee": 64
}linuxdoom-1.10/p_pspr.c#L483-L484slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_local.h#L57-L58#define MELEERANGE (64*FRACUNIT)
#define MISSILERANGE (32*64*FRACUNIT)DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L1063-L1085P_LineAttack
…
P_PathTraverse ( t1->x, t1->y,
x2, y2,
PT_ADDLINES|PT_ADDTHINGS,
PTR_ShootTraverse );DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L984-L1014thingtopslope = FixedDiv (th->z+th->height - shootz , dist);
…
if (thingtopslope < aimslope)
return true; // shot over the thing
…
if (la_damage)
P_DamageMobj (th, shootthing, shootthing, la_damage);
…
// don't go any farther
return false;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L556P_SpawnPlayerMissile (player->mo, MT_ROCKET);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L973-L984th = P_SpawnMobj (x,y,z, type);
…
th->momx = FixedMul( th->info->speed,
finecosine[an>>ANGLETOFINESHIFT]);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1966-L1982{ // MT_ROCKET
…
20*FRACUNIT, // speedDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1992-L2008{ // MT_PLASMA
…
25*FRACUNIT, // speedDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L2018-L2034{ // MT_BFG
…
25*FRACUNIT, // speedChecked by claude, 2026-10-21 — read P_LineAttack and PTR_ShootTraverse (a solid wall or a closed gap stops the trace at L922-L942); P_GunShot and the monster gun attacks pass MISSILERANGE, A_Punch and A_Saw MELEERANGE (+1); A_FireMissile, A_FireBFG, and A_FirePlasma call P_SpawnPlayerMissileA trace stops at the first solid wall, or at a two-sided line whose opening the slope misses, before it reaches anything behind. Melee range is 64 units.
Doom aims vertically for the player: P_BulletSlope traces 1,024 units straight ahead, then 5.625° (1<<26) to the left, then to the right, and takes the slope to the middle of the first shootable thing's visible part, within ±100/160; a bullet keeps the player's facing and takes only that slope, but a player's rocket, plasma, or BFG ball also turns to the side trace that found the target and flies level when none did. doom/autoaim
Value: 5.625 °
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_pspr.c#L601-L619void P_BulletSlope (mobj_t* mo)
…
an = mo->angle;
bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
…
an += 1<<26;
…
an -= 2<<26;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L1038-L1053// can't shoot outside view angles
topslope = 100*FRACUNIT/160;
bottomslope = -100*FRACUNIT/160;
…
if (linetarget)
return aimslope;
…
return 0;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L882-L892// this thing can be hit!
if (thingtopslope > topslope)
thingtopslope = topslope;
…
aimslope = (thingtopslope+thingbottomslope)/2;
linetarget = th;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L633-L639damage = 5*(P_Random ()%3+1);
angle = mo->angle;
…
P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L948-L984an = source->angle;
slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
…
if (!linetarget)
{
an = source->angle;
slope = 0;
}
…
th->angle = an;
…
th->momz = FixedMul( th->info->speed, slope);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/tables.h#L69#define ANG90 0x40000000Checked by claude, 2026-10-21 — read P_BulletSlope, P_AimLineAttack, PTR_AimTraverse, P_GunShot, and P_SpawnPlayerMissile; 1<<26 over ANG90's 2^30 is 90/16 = 5.625°The ±100/160 limit is the comment's "view angles"; two-sided lines narrow it as the trace passes ledges (PTR_AimTraverse, L842-L857). A positive angle step turns counterclockwise, so the first side trace looks left. The shotgun calls P_BulletSlope once for all its pellets.
Cited by: Autoaim, Doom, Perfect Dark
Doom's shotgun turns each of its 7 pellets by (P_Random()-P_Random())<<18, up to about 5.6° either side, at one shared vertical slope; the pistol and chaingun turn their shots the same way except while player->refire is 0, which covers the pistol's first shot and the chaingun's first two in a burst of held fire, and those fly straight. doom/shotgun-spread
Value: 5.6 °
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_pspr.c#L626-L639( mobj_t* mo,
boolean accurate )
…
if (!accurate)
angle += (P_Random()-P_Random())<<18;
…
P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L684-L687P_BulletSlope (player->mo);
…
for (i=0 ; i<7 ; i++)
P_GunShot (player->mo, false);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L661P_GunShot (player->mo, !player->refire);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L753P_GunShot (player->mo, !player->refire);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_pspr.c#L350-L359if ( (player->cmd.buttons & BT_ATTACK)
…
player->refire++;
P_FireWeapon (player);
…
player->refire = 0;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L149-L152{SPR_PISG,0,4,{NULL},S_PISTOL2,0,0}, // S_PISTOL1
{SPR_PISG,1,6,{A_FirePistol},S_PISTOL3,0,0},// S_PISTOL2
{SPR_PISG,2,4,{NULL},S_PISTOL4,0,0}, // S_PISTOL3
{SPR_PISG,1,5,{A_ReFire},S_PISTOL,0,0}, // S_PISTOL4DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L188-L190{SPR_CHGG,0,4,{A_FireCGun},S_CHAIN2,0,0}, // S_CHAIN1
{SPR_CHGG,1,4,{A_FireCGun},S_CHAIN3,0,0}, // S_CHAIN2
{SPR_CHGG,1,0,{A_ReFire},S_CHAIN,0,0}, // S_CHAIN3DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/tables.h#L69#define ANG90 0x40000000Checked by claude, 2026-10-21 — read P_GunShot, its callers, A_ReFire, and the pistol and chaingun states (each fire cycle ends in A_ReFire, which raises refire only if fire is still held); the largest difference of two table bytes is 255, and 255 × 2^18 over 2^32 of a turn is 5.60°The difference of two rolls makes small turns likelier than large ones. Releasing fire resets refire to 0, so tapping the pistol keeps every shot exact. The code's Doom II super shotgun (A_FireShotgun2) fires 20 pellets, turns them by twice as much (<<19), and spreads their slopes too.
Cited by: Hitscan
Each tic a Doom player stands on the floor, P_MovePlayer adds a thrust of the command's forward and side moves times 2,048 (1/32 unit per tic for each step of move), the side thrust at 90° to the facing; a keyboard sets the forward move to 25 walking or 50 running and the side move to 24 or 40, and the player gets no thrust in the air. doom/thrust
Value
{
"forward": [
25,
50
],
"side": [
24,
40
]
}linuxdoom-1.10/p_user.c#L156-L164// Do not let the player control movement
// if not onground.
onground = (player->mo->z <= player->mo->floorz);
…
if (cmd->forwardmove && onground)
P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
…
if (cmd->sidemove && onground)
P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_user.c#L64-L67angle >>= ANGLETOFINESHIFT;
…
player->mo->momx += FixedMul(move,finecosine[angle]);
player->mo->momy += FixedMul(move,finesine[angle]);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L175-L176fixed_t forwardmove[2] = {0x19, 0x32};
fixed_t sidemove[2] = {0x18, 0x28};Checked by claude, 2026-10-21 — read P_MovePlayer and P_Thrust; FRACUNIT is 65,536, so a move of 1 times 2,048 is 1/32 unit; G_BuildTiccmd indexes the tables by the run key (speed)The ticcmd tables are read from the Linux source's G_BuildTiccmd. Mouse and joystick input add to the same forward and side moves.
After a Doom thing moves on the floor, its momentum is multiplied by FRICTION (0xe800, 0.90625) each tic, and set to 0 once both axes are under STOPSPEED (1/16 unit per tic) with no move commanded; friction skips missiles, a charging lost soul, anything in the air, and a corpse halfway off a step still moving faster than 1/4 unit per tic on an axis, and the no-momentum cheat stops a player outright. Each axis of momentum is capped at 30 units per tic. doom/friction
Value: 0.90625 ×/tic
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_mobj.c#L111-L112#define STOPSPEED 0x1000
#define FRICTION 0xe800DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L137-L140if (mo->momx > MAXMOVE)
mo->momx = MAXMOVE;
else if (mo->momx < -MAXMOVE)
mo->momx = -MAXMOVE;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_local.h#L54#define MAXMOVE (30*FRACUNIT)DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L193-L198// slow down
if (player && player->cheats & CF_NOMOMENTUM)
{
// debug option for no sliding at all
mo->momx = mo->momy = 0;
return;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L201-L240if (mo->flags & (MF_MISSILE | MF_SKULLFLY) )
return; // no friction for missiles ever
…
if (mo->z > mo->floorz)
return; // no friction when airborne
…
if (mo->flags & MF_CORPSE)
{
// do not stop sliding
// if halfway off a step with some momentum
if (mo->momx > FRACUNIT/4
…
…Checked by claude, 2026-10-21 — read P_XYMovement; 0xe800 / 0x10000 = 0.90625 and 0x1000 / 0x10000 = 1/16The corpse test compares the floor the corpse rests on with its own sector's floor. The cap clamps x and y separately, so a diagonal move can exceed 30 units per tic in total.
Computed from the thrust and friction, not measured: with a thrust of a each tic and friction 0.90625, a Doom player on the floor settles at the speed v where a = 0.09375·v, about 16.7 units per tic (583 units/s) running forward and 8.3 walking; neither comes near the 30-unit cap. doom/run-speed
Value: 16.7 units/tic
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_tick.c#L148-L152for (i=0 ; i<MAXPLAYERS ; i++)
if (playeringame[i])
P_PlayerThink (&players[i]);
…
P_RunThinkers ();DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_user.c#L160-L161if (cmd->forwardmove && onground)
P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L147-L163xmove = mo->momx;
ymove = mo->momy;
…
ptryx = mo->x + xmove;
ptryy = mo->y + ymove;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_mobj.c#L238-L239mo->momx = FixedMul (mo->momx, FRICTION);
mo->momy = FixedMul (mo->momy, FRICTION);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L175fixed_t forwardmove[2] = {0x19, 0x32};DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/doomdef.h#L122#define TICRATE 35Checked by claude, 2026-10-21 — derived from the lines, not measured: P_PlayerThink adds the thrust a, P_RunThinkers then moves the player by its momentum and applies friction f, so the steady step v satisfies v = f·v + a, v = a/(1 − f); running a = 50/32 = 1.5625 gives 16.67, walking 25/32 gives 8.33; × 35 tics/s = 583Fixed-point truncation in FixedMul shaves the result slightly. A probe in a source port that keeps vanilla physics could measure it (T4).
Doom applies forward and side thrust at 90° to each other and caps each move separately, so running forward (50) while running sideways (40) gives √(50² + 40²) ≈ 64, 1.28 times the forward run alone. doom/strafe-running
About: Doom Strafe-running
Value: 1.28 ×
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_user.c#L160-L164if (cmd->forwardmove && onground)
P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
…
if (cmd->sidemove && onground)
P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L413-L420if (forward > MAXPLMOVE)
forward = MAXPLMOVE;
…
if (side > MAXPLMOVE)
side = MAXPLMOVE;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L171-L176#define MAXPLMOVE (forwardmove[1])
…
fixed_t forwardmove[2] = {0x19, 0x32};
fixed_t sidemove[2] = {0x18, 0x28};Checked by claude, 2026-10-21 — read G_BuildTiccmd's clamps and P_MovePlayer; the two thrusts are perpendicular (angle and angle − ANG90), so their sum has length √(f² + s²); 64.03/50 = 1.28Friction scales both axes alike, so the ratio holds for the settled speed too (about 21.3 units per tic against 16.7). Read from the Linux source's input code.
Cited by: Doom, Strafe-running
Holding Doom's strafe modifier makes the turn keys add a side move, and the strafe keys add theirs on top, so a turn key and a strafe key pressed together reach 80, clamped to MAXPLMOVE (50); a run then moves at √(50² + 50²) ≈ 70.7, 1.41 times the forward run alone. doom/sr50
About: Doom Strafe-running
Value: 50
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/g_game.c#L277-L289// let movement keys cancel each other out
if (strafe)
{
if (gamekeydown[key_right])
{
…
side += sidemove[speed];DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L322-L325if (gamekeydown[key_straferight])
side += sidemove[speed];
if (gamekeydown[key_strafeleft])
side -= sidemove[speed];DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L413-L420if (forward > MAXPLMOVE)
forward = MAXPLMOVE;
…
if (side > MAXPLMOVE)
side = MAXPLMOVE;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/g_game.c#L171-L176#define MAXPLMOVE (forwardmove[1])
…
fixed_t sidemove[2] = {0x18, 0x28};Checked by claude, 2026-10-21 — read G_BuildTiccmd; with strafe held, key_right adds sidemove[speed] (L280-L283), key_straferight adds it again (L322-L323), 40 + 40 = 80, and L417-L418 clamp it to forwardmove[1] = 0x32The name SR50 (strafe-running at side move 50) is players' usage, not the code's. Mouse movement with strafe held adds mousex*2 to the same total (L406-L407) and meets the same clamp. Read from the Linux source's input code.
Cited by: Doom, Strafe-running
When damage with a source hits a Doom monster and the monster survives, it makes that source its target, player or monster alike, unless the source is the monster itself or Doom II's Arch-vile (MT_VILE), or the monster's threshold from an earlier switch is still above 0; a damaged Arch-vile ignores its own threshold. Damage with no source never retargets. Each switch sets the threshold to 100; A_Chase lowers it by 1 per call and clears it at once when the target is gone or dead. doom/infighting
About: Doom Monster infighting
Value: 100
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_inter.c#L886-L915// do the damage
target->health -= damage;
if (target->health <= 0)
{
P_KillMobj (source, target);
return;
}
…
if ( (!target->threshold || target->type == MT_VILE)
&& source && source != target
&& source->type != MT_VILE)
{
…DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_local.h#L60-L61// follow a player exlusively for 3 seconds
#define BASETHRESHOLD 100DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L680-L689// modify target threshold
if (actor->threshold)
{
if (!actor->target
|| actor->target->health <= 0)
{
actor->threshold = 0;
}
else
actor->threshold--;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L354{CC_ARCH, MT_VILE},DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/d_englsh.h#L690#define CC_ARCH "ARCH-VILE"DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L212-L223if ( (gamemode == commercial)
…
if (gamemap == 30)
F_StartCast ();DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/doomdef.h#L42commercial, // DOOM 2 retail, E1 M34Checked by claude, 2026-10-21 — read the end of P_DamageMobj (the test is `(!target->threshold || target->type == MT_VILE) && source && source != target && source->type != MT_VILE`) and A_Chase's threshold block; MT_VILE is the cast list's ARCH-VILE, and the cast call runs only in commercial (DOOM 2) mode after map 30The same code makes a monster turn on a player, so infighting is the general rule rather than a special case. A_Chase runs once per chase state, which lasts several tics, so 100 chase steps is longer than the comment's 3 seconds. The Arch-vile tests are Doom II code in the shared source and never fire in Doom (1993).
Cited by: Doom, Monster infighting
A Doom projectile that touches a monster of its shooter's own type explodes without dealing damage, so those projectiles can't start infighting within a species; a hitscan attack has no such check. doom/same-species
About: Doom Monster infighting
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_map.c#L299-L313if (tmthing->target && (
tmthing->target->type == thing->type ||
(tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)||
(tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) )
{
// Don't hit same species as originator.
…
if (thing->type != MT_PLAYER)
{
// Explode, but do no damage.
// Let players missile other players.
return false;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_map.c#L974-L1011// shoot a thing
th = in->d.thing;
if (th == shootthing)
return true; // can't shoot self
…
if (la_damage)
P_DamageMobj (th, shootthing, shootthing, la_damage);Checked by claude, 2026-10-21 — read PIT_CheckThing's missile branch and PTR_ShootTraverse's thing branch; the latter checks only the shooter itself and shootability before calling P_DamageMobjA zombieman's bullet can therefore hit another zombieman and turn it (doom/infighting). The MT_PLAYER exception lets one player's rockets hit another. A rocket's blast is separate (P_RadiusAttack) and has no species check. The code also counts MT_KNIGHT (Doom II's Hell Knight, f_finale.c L348) as the Baron's species.
Cited by: Monster infighting
A Doom monster that survives a hit enters its pain state when P_Random() is below its pain chance, out of 256, unless it is a lost soul in mid-charge; the table gives the zombieman and imp 200, the demon 180, the shotgun guy 170, the cacodemon 128, the Baron of Hell 50, the Spider Mastermind 40, and the Cyberdemon 20, and the lost soul's 256 always succeeds. The pain sets MF_JUSTHIT, so the monster's next missile-range check passes at once if it can see its target. doom/pain-chance
About: Doom Pain chance
Value
{
"zombieman": 200,
"imp": 200,
"demon": 180,
"shotgun-guy": 170,
"cacodemon": 128,
"baron": 50,
"spider-mastermind": 40,
"cyberdemon": 20,
"lost-soul": 256
}linuxdoom-1.10/p_inter.c#L887-L900target->health -= damage;
if (target->health <= 0)
…
if ( (P_Random () < target->info->painchance)
&& !(target->flags&MF_SKULLFLY) )
{
target->flags |= MF_JUSTHIT; // fight back!
…
P_SetMobjState (target, target->info->painstate);DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L197-L209boolean P_CheckMissileRange (mobj_t* actor)
…
if (! P_CheckSight (actor, actor->target) )
return false;
…
if ( actor->flags & MF_JUSTHIT )
{
// the target just hit the enemy,
// so fight back!
actor->flags &= ~MF_JUSTHIT;
return true;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1134-L1143{ // MT_POSSESSED
…
200, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1160-L1169{ // MT_SHOTGUY
…
170, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1394-L1403{ // MT_TROOP
…
200, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1420-L1429{ // MT_SERGEANT
…
180, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1472-L1481{ // MT_HEAD
…
128, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1498-L1507{ // MT_BRUISER
…
50, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1576-L1585{ // MT_SKULL
…
256, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1602-L1611{ // MT_SPIDER
…
40, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1654-L1663{ // MT_CYBORG
…
20, // painchanceDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/f_finale.c#L341-L356{CC_ZOMBIE, MT_POSSESSED},
{CC_SHOTGUN, MT_SHOTGUY},
…
{CC_IMP, MT_TROOP},
{CC_DEMON, MT_SERGEANT},
{CC_LOST, MT_SKULL},
{CC_CACO, MT_HEAD},
…
{CC_BARON, MT_BRUISER},
…
{CC_SPIDER, MT_SPIDER},
{CC_CYBER, MT_CYBORG},DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/d_englsh.h#L677-L692#define CC_ZOMBIE "ZOMBIEMAN"
#define CC_SHOTGUN "SHOTGUN GUY"
…
#define CC_IMP "IMP"
#define CC_DEMON "DEMON"
#define CC_LOST "LOST SOUL"
#define CC_CACO "CACODEMON"
…
#define CC_BARON "BARON OF HELL"
…
#define CC_SPIDER "THE SPIDER MASTERMIND"
#define CC_CYBER "THE CYBERDEMON"Checked by claude, 2026-10-21 — read P_DamageMobj's pain test and each mobjinfo entry's painchance field (spawnhealth is 3 lines below the type, painchance 9); P_Random tops out at 255, so 256 always passesThe pain state interrupts the monster's attack or chase. The missile-range check skips the reaction-time and distance tests when MF_JUSTHIT is set. The player's own entry is 255 (info.c L1117).
Cited by: Doom, Pain chance, Quake II
A Doom monster spawns with its type's reactiontime (8 for the zombieman) except on Nightmare, where it stays 0; each call of A_Chase lowers it by 1, and while it is above 0 the missile-range check refuses a ranged attack, unless the monster has flinched from a hit (its pain-chance roll, which sets MF_JUSTHIT) since the check last ran. Melee attacks don't check it. doom/reaction-time
About: Doom Reaction delay
Value: 8
CodeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) ·linuxdoom-1.10/p_mobj.c#L491-L504memset (mobj, 0, sizeof (*mobj));
…
if (gameskill != sk_nightmare)
mobj->reactiontime = info->reactiontime;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/info.c#L1134-L1140{ // MT_POSSESSED
…
8, // reactiontimeDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L676-L677if (actor->reactiontime)
actor->reactiontime--;DOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_enemy.c#L203-L213if ( actor->flags & MF_JUSTHIT )
…
return true;
…
if (actor->reactiontime)
return false; // do not attack yetDOOM: the Linux source release (id-Software/DOOM, linuxdoom-1.10) · linuxdoom-1.10/p_inter.c#L894-L897if ( (P_Random () < target->info->painchance)
…
target->flags |= MF_JUSTHIT; // fight back!Checked by claude, 2026-10-22 — read P_DamageMobj's pain roll, which sets MF_JUSTHIT, and P_SpawnMobj's zeroing and Nightmare test, the zombieman's mobjinfo entry, A_Chase's decrement, and P_CheckMissileRange's early returns; A_Chase's melee branch calls P_CheckMeleeRange, which doesn't read reactiontimeA_Chase runs as the action of a monster's chase frames, so the count falls once per chase frame, not once per tic.
Cited by: Reaction delay