39 Monster AI Logic
In this tour you’ll explore how Doom monsters sense and pursue players. You’ll see where AI routines live (p_enemy.c
), how sounds alert enemies (P_NoiseAlert
), how they spot targets (A_Look
), pursue or attack them (A_Chase
), face them (A_FaceTarget
), and how the thinker dispatches these actions (P_MobjThinker
).
Files: linuxdoom-1.10/p_enemy.c
The file p_enemy.c implements monster AI and behavior logic in DOOM.
linuxdoom-1.10/p_enemy.c
(lines 158–166): P_NoiseAlert spreads information about a sound event through the game world, allowing monsters to become aware of noise-making targets.
P_RecursiveSound
spreads sound awareness through connected sectors, marking each with the soundtarget
and depth
. This causes monsters in those sectors to wake up and pursue the sound source.
linuxdoom-1.10/p_enemy.c
(lines 115–119): This check prevents processing sectors that have already been flooded during sound propagation.
linuxdoom-1.10/p_enemy.c
(lines 121–123): Marks this sector as processed by updating its validation and sound propagation state.
linuxdoom-1.10/p_enemy.c
(lines 125–133): The code checks each linedef, using P_LineOpening to measure passage heights between sectors. Lines with zero or negative openrange are blocked passages.
linuxdoom-1.10/p_enemy.c
(lines 141–147): Sound propagation stops after passing through one sound-blocking line. When encountering a sound barrier, the recursion continues but marks that a barrier has been crossed.
linuxdoom-1.10/p_enemy.c
(lines 604–610): A_Look prepares monsters to respond to player actions by resetting their wake-up threshold and checking their sector’s soundtarget.
linuxdoom-1.10/p_enemy.c
(lines 626–633): A_Look scans for visible players before initiating chase behavior.
linuxdoom-1.10/p_enemy.c
(lines 512–515): Sets up a circular scan through players, using lastlook to track which player was checked last.
linuxdoom-1.10/p_enemy.c
(lines 517–521): The search limits player checks to avoid excessive scanning - either checking two players maximum or completing one full rotation through player slots.
linuxdoom-1.10/p_enemy.c
(lines 529–533): For each candidate, it discards those with health ≤ 0(529) or not visible via P_CheckSight(532), ensuring only alive and in-sight players proceed.
linuxdoom-1.10/p_enemy.c
(lines 543–544): For non-360° vision monsters, the code checks if the player is behind them (between 90° and 270° angles) and beyond melee range. Such targets are ignored.
linuxdoom-1.10/p_enemy.c
(lines 672–680): A_Chase controls monster behavior and runs each game tick. It manages the monster’s reaction timing and target selection.
linuxdoom-1.10/p_enemy.c
(lines 724–732): When in close range, monsters switch to their melee attack state, such as a demon’s bite attack.
linuxdoom-1.10/p_enemy.c
(lines 735–742): Checks if missile attacks are allowed based on game difficulty and movecount.
linuxdoom-1.10/p_enemy.c
(lines 763–768): When movement fails or the monster has moved its allotted steps, it picks a new direction to chase the player.
linuxdoom-1.10/p_enemy.c
(lines 782–790): A_FaceTarget makes an actor turn to face its target. When called, the actor immediately snaps to point directly at its target.
linuxdoom-1.10/p_enemy.c
(lines 787–787): Disables ambush mode, allowing the monster to visibly turn towards its target.
linuxdoom-1.10/p_enemy.c
(lines 789–792): Updates the actor’s angle to face directly at its target by calculating the angle between their positions.
linuxdoom-1.10/p_enemy.c
(lines 794–795): For shadow-flagged targets, a random angle jitter is added to create a flickering effect.
Next we’ll look at P_MobjThinker
, which processes monster movement and behavior each game tick.
linuxdoom-1.10/p_mobj.c
(lines 415–422): P_MobjThinker dispatches AI behavior, handling movement and state transitions that trigger monster actions.
This completes the walkthrough of Doom’s monster AI logic: sensing
, targeting
, attacking
, and the thinker loop
that glues it all together.