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.