On this page
  1. Related
  2. Mechanics
  3. References
  4. Sources

The atlas reads Doom through the source code id Software released in 1997, the Linux port’s version 1.101. The DOS code was not released, so every claim here describes the Linux build, and the DOS 1.9 executable may differ wherever its code did.

The game logic runs at 35 tics/s2. Every roll reads a fixed table of 256 entries3, with separate indices for play and for cosmetics3,4. A new game, a loaded save, a demo, and a game started from the command line all restart both indices at the table’s start5.

Damage is a base times a small roll, with no defense stat on a monster: 5 × (1–3)6 per bullet, and (1–8) × damage7 for a projectile’s direct hit. A rocket’s explosion adds 128 − distance8, and the BFG’s tracers deal 15 × (1–8) per trace9. Bullets are hitscan10, and autoaim picks their vertical slope11. A sideways move adds to a forward one, the root of strafe-running12,13. A monster that survives a hit from another turns on it unless it switched targets recently (infighting)14, and each hit it survives may flinch it15.

Mechanics

MechanicKindHow
Random number generatorFixed tableone 256-byte table walked by two indices, one for play and one for the wipe, sounds, and screens
Damage formulaRandom multiplea base times 1–3, 1–8, or 1–10 from the table, and only a player's armor takes a share
HitscanHitscan beside projectilesbullets and melee trace a line in the tic they fire; rockets, plasma, and BFG balls fly
AutoaimVertical searchtraces ahead and 5.625° to each side set the shot's slope; only missiles turn toward the target
RunningMomentuma thrust each tic on the floor against 0.90625 friction, settling near 16.7 units/tic at a run
Strafe-runningSeparately capped axesforward and side moves are capped apart, so a diagonal run is 1.28 times as fast, and 1.41 at a side move of 50
Monster infightingRetaliationa monster that survives a hit turns on its attacker unless it hurt itself or switched within 100 chase steps, and a projectile can't hurt its shooter's own species
Pain chancePer-type rolleach hit a monster survives flinches it with a chance out of 256, from the zombieman's 200 to the Cyberdemon's 20
Difficulty levelDamage halvedthe easiest skill halves the damage the player takes
Reaction delayCountdown from spawna monster spawns with a count, 8 for the zombieman and 0 on Nightmare, and makes no ranged attack until its chase frames spend it, unless a hit has made it flinch
Demo playbackRecorded inputa 13-byte header, then 4 bytes per player per tic fed into each tic command; random indices reset at the start
Every claim about this game, by concept (31)
generalid 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.Code
AutoaimDoom 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.Code
Damage formulaEach 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.Code
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.Code
A 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.Code
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.Code
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.Code
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).Code
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.Code
Demo playbackIn the Linux 1.10 source, a Doom demo starts with a 13-byte header: the version (110), skill, episode, map, the deathmatch, respawn, fast, and no-monsters options, the recording player's number, and one in-game flag for each of the 4 players. Then, for every tic and every player in the game, come 4 bytes: forward move, side move, the high byte of the turn, and the buttons. A byte of 0x80 ends it. A one-player demo takes 140 bytes a second at 35 tics a second (computed).Code
Playback goes through the same path as play. Each tic, G_Ticker copies every player's command (ticcmd_t) from the network buffer, then, during a demo, overwrites its move, turn, and buttons from the demo; the player code then acts on that command as on a live one.Code
A demo keeps only the turn's high byte, rounded, so a recorded turn moves in steps of 1/256 of a full circle, about 1.4 degrees (computed). While recording, the game writes the command and reads it straight back ("make SURE it is exactly the same"), so the recording player also plays with the rounded turn and the recording matches what the player saw.Code
Playing a demo restores the recorded skill, episode, map, and options from its header and starts the level through G_InitNew, which resets both random indices to 0, as a recording started from the command line also does. A demo whose version byte isn't 110 is refused with "Demo is from a different game version!".Code
Playback ends at the 0x80 byte. A demo given with -playdemo then quits the game, and one given with -timedemo reports the tics and the real time taken. Otherwise the attract loop moves on: the title picture, demo1, the credits, demo2, a third page, demo3, and, in the retail Ultimate Doom only, demo4. During an attract demo, a key press that the menu doesn't take first, or a mouse or joystick button, opens the menu, and the demo keeps running behind it.Code
Recording (-record) ends when the player presses Q, when the buffer, 128 KiB unless -maxdemo sets another size in KiB, is within 16 bytes of full, when a player leaves a net game, or when the game stops on an error (I_Error); the game then writes the 0x80 byte and the file <name>.lmp, and exits with "Demo <name>.lmp recorded".Code
HitscanDoom'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).Code
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.Code
Monster infightingWhen 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.Code
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.Code
Pain chanceA 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.Code
Random number generatorDoom'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.Code
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.Code
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).Code
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.Code
Reaction delayA 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.Code
RunningDoom's game logic runs in tics of 1/35 second (TICRATE 35).Code
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.Code
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.Code
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.Code
Strafe-runningDoom 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.Code
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.Code

References

  1. ^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.Codeid-Software/DOOM
    How we know
    33enum { VERSION =  110 };
    
    linuxdoom-1.10/doomdef.h line 33 at a77dfb9 · upstream ↗
    12The bad news:  this code only compiles and runs on linux.  We couldn't
    13release the dos code because of a copyrighted sound library we used
    
    README.TXT lines 12–14 at a77dfb9 · upstream ↗
    77John Carmack
    7812-23-97
    
    README.TXT lines 77–78 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  2. ^Doom's game logic runs in tics of 1/35 second (TICRATE 35).Codeid-Software/DOOM
    How we know
    121// State updates, number of tics / second.
    122#define TICRATE		35
    
    linuxdoom-1.10/doomdef.h lines 121–122 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  3. ^ abDoom'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.Codeid-Software/DOOM
    How we know
    31unsigned char rndtable[256] = {
    32    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66 ,
    
    linuxdoom-1.10/m_random.c lines 31–32 at a77dfb9 · upstream ↗
    53int	rndindex = 0;
    54int	prndindex = 0;
    ⋮
    56// Which one is deterministic?
    57int P_Random (void)
    ⋮
    59    prndindex = (prndindex+1)&0xff;
    60    return rndtable[prndindex];
    ⋮
    63int M_Random (void)
    ⋮
    65    rndindex = (rndindex+1)&0xff;
    66    return rndtable[rndindex];
    
    linuxdoom-1.10/m_random.c lines 53–67 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  4. ^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.Codeid-Software/DOOM
    How we know
    633    damage = 5*(P_Random ()%3+1);
    634    angle = mo->angle;
    ⋮
    637	angle += (P_Random()-P_Random())<<18;
    
    linuxdoom-1.10/p_pspr.c lines 633–637 at a77dfb9 · upstream ↗
    894    if ( (P_Random () < target->info->painchance)
    
    linuxdoom-1.10/p_inter.c line 894 at a77dfb9 · upstream ↗
    159    y[0] = -(M_Random()%16);
    
    linuxdoom-1.10/f_wipe.c line 159 at a77dfb9 · upstream ↗
    326  // hacks to vary the sfx pitches
    ⋮
    330    pitch += 8 - (M_Random()&15);
    
    linuxdoom-1.10/s_sound.c lines 326–330 at a77dfb9 · upstream ↗
    523	    a->nexttic = bcnt + 1 + (M_Random()%a->period);
    
    linuxdoom-1.10/wi_stuff.c line 523 at a77dfb9 · upstream ↗
    992    st_randomnumber = M_Random();
    
    linuxdoom-1.10/st_stuff.c line 992 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  5. ^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).Codeid-Software/DOOMrevised
    How we know
    69void M_ClearRandom (void)
    ⋮
    71    rndindex = prndindex = 0;
    
    linuxdoom-1.10/m_random.c lines 69–72 at a77dfb9 · upstream ↗
    1414    M_ClearRandom (); 
    
    linuxdoom-1.10/g_game.c line 1414 at a77dfb9 · upstream ↗
    1345void G_DoNewGame (void) 
    ⋮
    1356    G_InitNew (d_skill, d_episode, d_map); 
    
    linuxdoom-1.10/g_game.c lines 1345–1356 at a77dfb9 · upstream ↗
    1226    // load a base level 
    1227    G_InitNew (gameskill, gameepisode, gamemap); 
    
    linuxdoom-1.10/g_game.c lines 1226–1227 at a77dfb9 · upstream ↗
    1613    // don't spend a lot of time in loadlevel 
    1614    precache = false;
    1615    G_InitNew (skill, episode, map); 
    
    linuxdoom-1.10/g_game.c lines 1613–1615 at a77dfb9 · upstream ↗
    1161    if ( gameaction != ga_loadgame )
    ⋮
    1163	if (autostart || netgame)
    1164	    G_InitNew (startskill, startepisode, startmap);
    
    linuxdoom-1.10/d_main.c lines 1161–1164 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  6. ^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.Codeid-Software/DOOM
    How we know
    626P_GunShot
    ⋮
    633    damage = 5*(P_Random ()%3+1);
    ⋮
    639    P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);
    
    linuxdoom-1.10/p_pspr.c lines 625–639 at a77dfb9 · upstream ↗
    660    P_BulletSlope (player->mo);
    661    P_GunShot (player->mo, !player->refire);
    
    linuxdoom-1.10/p_pspr.c lines 660–661 at a77dfb9 · upstream ↗
    684    P_BulletSlope (player->mo);
    ⋮
    686    for (i=0 ; i<7 ; i++)
    687	P_GunShot (player->mo, false);
    
    linuxdoom-1.10/p_pspr.c lines 684–687 at a77dfb9 · upstream ↗
    751    P_BulletSlope (player->mo);
    ⋮
    753    P_GunShot (player->mo, !player->refire);
    
    linuxdoom-1.10/p_pspr.c lines 751–753 at a77dfb9 · upstream ↗
    31unsigned char rndtable[256] = {
    
    linuxdoom-1.10/m_random.c lines 31–51 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  7. ^A 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.Codeid-Software/DOOM
    How we know
    290    // missiles can hit other things
    291    if (tmthing->flags & MF_MISSILE)
    
    linuxdoom-1.10/p_map.c lines 290–291 at a77dfb9 · upstream ↗
    322	// damage / explode
    323	damage = ((P_Random()%8)+1)*tmthing->info->damage;
    324	P_DamageMobj (thing, tmthing, tmthing->target, damage);
    
    linuxdoom-1.10/p_map.c lines 322–324 at a77dfb9 · upstream ↗
    1966    {		// MT_ROCKET
    ⋮
    1986	20,		// damage
    
    linuxdoom-1.10/info.c lines 1966–1986 at a77dfb9 · upstream ↗
    1992    {		// MT_PLASMA
    ⋮
    2012	5,		// damage
    
    linuxdoom-1.10/info.c lines 1992–2012 at a77dfb9 · upstream ↗
    2018    {		// MT_BFG
    ⋮
    2038	100,		// damage
    
    linuxdoom-1.10/info.c lines 2018–2038 at a77dfb9 · upstream ↗
    1914    {		// MT_TROOPSHOT
    ⋮
    1934	3,		// damage
    
    linuxdoom-1.10/info.c lines 1914–1934 at a77dfb9 · upstream ↗
    931    P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);
    
    linuxdoom-1.10/p_enemy.c line 931 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  8. ^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.Codeid-Software/DOOM
    How we know
    1966    {		// MT_ROCKET
    ⋮
    1979	S_EXPLODE1,		// deathstate
    
    linuxdoom-1.10/info.c lines 1966–1979 at a77dfb9 · upstream ↗
    263    {SPR_MISL,32769,8,{A_Explode},S_EXPLODE2,0,0},	// S_EXPLODE1
    
    linuxdoom-1.10/info.c line 263 at a77dfb9 · upstream ↗
    1598void A_Explode (mobj_t* thingy)
    ⋮
    1600    P_RadiusAttack ( thingy, thingy->target, 128 );
    
    linuxdoom-1.10/p_enemy.c lines 1598–1600 at a77dfb9 · upstream ↗
    1173    // Boss spider and cyborg
    1174    // take no damage from concussion.
    1175    if (thing->type == MT_CYBORG
    1176	|| thing->type == MT_SPIDER)
    1177	return true;	
    ⋮
    1182    dist = dx>dy ? dx : dy;
    1183    dist = (dist - thing->radius) >> FRACBITS;
    ⋮
    1191    if ( P_CheckSight (thing, bombspot) )
    ⋮
    1193	// must be in direct path
    1194	P_DamageMobj (thing, bombspot, bombsource, bombdamage - dist);
    
    linuxdoom-1.10/p_map.c lines 1173–1194 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  9. ^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.Codeid-Software/DOOM
    How we know
    253    {SPR_BFE1,32768,8,{NULL},S_BFGLAND2,0,0},	// S_BFGLAND
    ⋮
    255    {SPR_BFE1,32770,8,{A_BFGSpray},S_BFGLAND4,0,0},	// S_BFGLAND3
    
    linuxdoom-1.10/info.c lines 253–255 at a77dfb9 · upstream ↗
    789    for (i=0 ; i<40 ; i++)
    ⋮
    791	an = mo->angle - ANG90/2 + ANG90/40*i;
    ⋮
    795	P_AimLineAttack (mo->target, an, 16*64*FRACUNIT);
    ⋮
    805	damage = 0;
    806	for (j=0;j<15;j++)
    807	    damage += (P_Random()&7) + 1;
    ⋮
    809	P_DamageMobj (linetarget, mo->target,mo->target, damage);
    
    linuxdoom-1.10/p_pspr.c lines 789–809 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  10. ^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).Codeid-Software/DOOMrevised
    How we know
    483    slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
    484    P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);
    
    linuxdoom-1.10/p_pspr.c lines 483–484 at a77dfb9 · upstream ↗
    57#define MELEERANGE		(64*FRACUNIT)
    58#define MISSILERANGE	(32*64*FRACUNIT)
    
    linuxdoom-1.10/p_local.h lines 57–58 at a77dfb9 · upstream ↗
    1063P_LineAttack
    ⋮
    1082    P_PathTraverse ( t1->x, t1->y,
    1083		     x2, y2,
    1084		     PT_ADDLINES|PT_ADDTHINGS,
    1085		     PTR_ShootTraverse );
    
    linuxdoom-1.10/p_map.c lines 1063–1085 at a77dfb9 · upstream ↗
    984    thingtopslope = FixedDiv (th->z+th->height - shootz , dist);
    ⋮
    986    if (thingtopslope < aimslope)
    987	return true;		// shot over the thing
    ⋮
    1010    if (la_damage)
    1011	P_DamageMobj (th, shootthing, shootthing, la_damage);
    ⋮
    1013    // don't go any farther
    1014    return false;
    
    linuxdoom-1.10/p_map.c lines 984–1014 at a77dfb9 · upstream ↗
    556    P_SpawnPlayerMissile (player->mo, MT_ROCKET);
    
    linuxdoom-1.10/p_pspr.c line 556 at a77dfb9 · upstream ↗
    973    th = P_SpawnMobj (x,y,z, type);
    ⋮
    980    th->momx = FixedMul( th->info->speed,
    981			 finecosine[an>>ANGLETOFINESHIFT]);
    
    linuxdoom-1.10/p_mobj.c lines 973–984 at a77dfb9 · upstream ↗
    1966    {		// MT_ROCKET
    ⋮
    1982	20*FRACUNIT,		// speed
    
    linuxdoom-1.10/info.c lines 1966–1982 at a77dfb9 · upstream ↗
    1992    {		// MT_PLASMA
    ⋮
    2008	25*FRACUNIT,		// speed
    
    linuxdoom-1.10/info.c lines 1992–2008 at a77dfb9 · upstream ↗
    2018    {		// MT_BFG
    ⋮
    2034	25*FRACUNIT,		// speed
    
    linuxdoom-1.10/info.c lines 2018–2034 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  11. ^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.Codeid-Software/DOOM
    How we know
    601void P_BulletSlope (mobj_t*	mo)
    ⋮
    606    an = mo->angle;
    607    bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
    ⋮
    611	an += 1<<26;
    612	bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
    ⋮
    615	    an -= 2<<26;
    616	    bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
    
    linuxdoom-1.10/p_pspr.c lines 601–619 at a77dfb9 · upstream ↗
    1038    // can't shoot outside view angles
    1039    topslope = 100*FRACUNIT/160;	
    1040    bottomslope = -100*FRACUNIT/160;
    ⋮
    1050    if (linetarget)
    1051	return aimslope;
    ⋮
    1053    return 0;
    
    linuxdoom-1.10/p_map.c lines 1038–1053 at a77dfb9 · upstream ↗
    882    // this thing can be hit!
    883    if (thingtopslope > topslope)
    884	thingtopslope = topslope;
    ⋮
    889    aimslope = (thingtopslope+thingbottomslope)/2;
    890    linetarget = th;
    
    linuxdoom-1.10/p_map.c lines 882–892 at a77dfb9 · upstream ↗
    633    damage = 5*(P_Random ()%3+1);
    634    angle = mo->angle;
    ⋮
    639    P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);
    
    linuxdoom-1.10/p_pspr.c lines 633–639 at a77dfb9 · upstream ↗
    948    an = source->angle;
    949    slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
    ⋮
    951    if (!linetarget)
    ⋮
    954	slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
    ⋮
    956	if (!linetarget)
    ⋮
    959	    slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
    ⋮
    962	if (!linetarget)
    ⋮
    964	    an = source->angle;
    965	    slope = 0;
    ⋮
    979    th->angle = an;
    ⋮
    984    th->momz = FixedMul( th->info->speed, slope);
    
    linuxdoom-1.10/p_mobj.c lines 948–984 at a77dfb9 · upstream ↗
    69#define ANG90			0x40000000
    
    linuxdoom-1.10/tables.h line 69 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  12. ^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.Codeid-Software/DOOM
    How we know
    160    if (cmd->forwardmove && onground)
    161	P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
    ⋮
    163    if (cmd->sidemove && onground)
    164	P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);
    
    linuxdoom-1.10/p_user.c lines 160–164 at a77dfb9 · upstream ↗
    413    if (forward > MAXPLMOVE) 
    414	forward = MAXPLMOVE; 
    ⋮
    417    if (side > MAXPLMOVE) 
    418	side = MAXPLMOVE; 
    
    linuxdoom-1.10/g_game.c lines 413–420 at a77dfb9 · upstream ↗
    171#define MAXPLMOVE		(forwardmove[1]) 
    ⋮
    175fixed_t		forwardmove[2] = {0x19, 0x32}; 
    176fixed_t		sidemove[2] = {0x18, 0x28}; 
    
    linuxdoom-1.10/g_game.c lines 171–176 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  13. ^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.Codeid-Software/DOOM
    How we know
    277    // let movement keys cancel each other out
    278    if (strafe) 
    ⋮
    280	if (gamekeydown[key_right]) 
    ⋮
    283	    side += sidemove[speed]; 
    
    linuxdoom-1.10/g_game.c lines 277–289 at a77dfb9 · upstream ↗
    322    if (gamekeydown[key_straferight]) 
    323	side += sidemove[speed]; 
    324    if (gamekeydown[key_strafeleft]) 
    325	side -= sidemove[speed];
    
    linuxdoom-1.10/g_game.c lines 322–325 at a77dfb9 · upstream ↗
    413    if (forward > MAXPLMOVE) 
    414	forward = MAXPLMOVE; 
    ⋮
    417    if (side > MAXPLMOVE) 
    418	side = MAXPLMOVE; 
    
    linuxdoom-1.10/g_game.c lines 413–420 at a77dfb9 · upstream ↗
    171#define MAXPLMOVE		(forwardmove[1]) 
    ⋮
    176fixed_t		sidemove[2] = {0x18, 0x28}; 
    
    linuxdoom-1.10/g_game.c lines 171–176 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  14. ^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.Codeid-Software/DOOMrevised
    How we know
    886    // do the damage	
    887    target->health -= damage;	
    888    if (target->health <= 0)
    ⋮
    890	P_KillMobj (source, target);
    891	return;
    ⋮
    904    if ( (!target->threshold || target->type == MT_VILE)
    905	 && source && source != target
    906	 && source->type != MT_VILE)
    ⋮
    908	// if not intent on another player,
    909	// chase after this one
    910	target->target = source;
    911	target->threshold = BASETHRESHOLD;
    
    linuxdoom-1.10/p_inter.c lines 886–915 at a77dfb9 · upstream ↗
    60// follow a player exlusively for 3 seconds
    61#define	BASETHRESHOLD	 	100
    
    linuxdoom-1.10/p_local.h lines 60–61 at a77dfb9 · upstream ↗
    680    // modify target threshold
    681    if  (actor->threshold)
    ⋮
    683	if (!actor->target
    684	    || actor->target->health <= 0)
    ⋮
    686	    actor->threshold = 0;
    ⋮
    688	else
    689	    actor->threshold--;
    
    linuxdoom-1.10/p_enemy.c lines 680–689 at a77dfb9 · upstream ↗
    354    {CC_ARCH, MT_VILE},
    
    linuxdoom-1.10/f_finale.c line 354 at a77dfb9 · upstream ↗
    690#define CC_ARCH	"ARCH-VILE"
    
    linuxdoom-1.10/d_englsh.h line 690 at a77dfb9 · upstream ↗
    212    if ( (gamemode == commercial)
    ⋮
    222	if (gamemap == 30)
    223	  F_StartCast ();
    
    linuxdoom-1.10/f_finale.c lines 212–223 at a77dfb9 · upstream ↗
    42  commercial,	// DOOM 2 retail, E1 M34
    
    linuxdoom-1.10/doomdef.h line 42 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  15. ^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.Codeid-Software/DOOMrevised
    How we know
    887    target->health -= damage;	
    888    if (target->health <= 0)
    ⋮
    894    if ( (P_Random () < target->info->painchance)
    895	 && !(target->flags&MF_SKULLFLY) )
    ⋮
    897	target->flags |= MF_JUSTHIT;	// fight back!
    ⋮
    899	P_SetMobjState (target, target->info->painstate);
    
    linuxdoom-1.10/p_inter.c lines 887–900 at a77dfb9 · upstream ↗
    197boolean P_CheckMissileRange (mobj_t* actor)
    ⋮
    201    if (! P_CheckSight (actor, actor->target) )
    202	return false;
    ⋮
    204    if ( actor->flags & MF_JUSTHIT )
    ⋮
    206	// the target just hit the enemy,
    207	// so fight back!
    208	actor->flags &= ~MF_JUSTHIT;
    209	return true;
    
    linuxdoom-1.10/p_enemy.c lines 197–209 at a77dfb9 · upstream ↗
    1134    {		// MT_POSSESSED
    ⋮
    1143	200,		// painchance
    
    linuxdoom-1.10/info.c lines 1134–1143 at a77dfb9 · upstream ↗
    1160    {		// MT_SHOTGUY
    ⋮
    1169	170,		// painchance
    
    linuxdoom-1.10/info.c lines 1160–1169 at a77dfb9 · upstream ↗
    1394    {		// MT_TROOP
    ⋮
    1403	200,		// painchance
    
    linuxdoom-1.10/info.c lines 1394–1403 at a77dfb9 · upstream ↗
    1420    {		// MT_SERGEANT
    ⋮
    1429	180,		// painchance
    
    linuxdoom-1.10/info.c lines 1420–1429 at a77dfb9 · upstream ↗
    1472    {		// MT_HEAD
    ⋮
    1481	128,		// painchance
    
    linuxdoom-1.10/info.c lines 1472–1481 at a77dfb9 · upstream ↗
    1498    {		// MT_BRUISER
    ⋮
    1507	50,		// painchance
    
    linuxdoom-1.10/info.c lines 1498–1507 at a77dfb9 · upstream ↗
    1576    {		// MT_SKULL
    ⋮
    1585	256,		// painchance
    
    linuxdoom-1.10/info.c lines 1576–1585 at a77dfb9 · upstream ↗
    1602    {		// MT_SPIDER
    ⋮
    1611	40,		// painchance
    
    linuxdoom-1.10/info.c lines 1602–1611 at a77dfb9 · upstream ↗
    1654    {		// MT_CYBORG
    ⋮
    1663	20,		// painchance
    
    linuxdoom-1.10/info.c lines 1654–1663 at a77dfb9 · upstream ↗
    341    {CC_ZOMBIE, MT_POSSESSED},
    342    {CC_SHOTGUN, MT_SHOTGUY},
    ⋮
    344    {CC_IMP, MT_TROOP},
    345    {CC_DEMON, MT_SERGEANT},
    346    {CC_LOST, MT_SKULL},
    347    {CC_CACO, MT_HEAD},
    ⋮
    349    {CC_BARON, MT_BRUISER},
    ⋮
    355    {CC_SPIDER, MT_SPIDER},
    356    {CC_CYBER, MT_CYBORG},
    
    linuxdoom-1.10/f_finale.c lines 341–356 at a77dfb9 · upstream ↗
    677#define CC_ZOMBIE	"ZOMBIEMAN"
    678#define CC_SHOTGUN	"SHOTGUN GUY"
    ⋮
    680#define CC_IMP	"IMP"
    681#define CC_DEMON	"DEMON"
    682#define CC_LOST	"LOST SOUL"
    683#define CC_CACO	"CACODEMON"
    ⋮
    685#define CC_BARON	"BARON OF HELL"
    ⋮
    691#define CC_SPIDER	"THE SPIDER MASTERMIND"
    692#define CC_CYBER	"THE CYBERDEMON"
    
    linuxdoom-1.10/d_englsh.h lines 677–692 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

Sources

Code