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

Noise detection decides which enemies hear a sound the player makes. In Metal Gear Solid each noise has a power. A quiet noise reaches guards within 1,500 units, a loud one within 8,000, and an explosion is heard at any distance. A knock on a wall or a footstep on a noisy floor reaches only the one guard nearest by route1.

  • By powerMetal Gear Solid (1998). A noise's power sets who hears it: a radius, every guard, or the one nearest guard, which is how a knock on a wall draws a single guard.1

Games

GameYearHowNote
Metal Gear Solid1998By powera noise's power sets who hears it: a radius, every guard, or the one nearest guard, which is how a knock on a wall draws a single guard
Every claim about this mechanic, by game (1)
Metal Gear Solid 1998In Metal Gear Solid Integral (SLPM-86247), a noise is a power, a length, and a position (GM_SetNoise), and a noise replaces the current one only if its power is higher, or equal with a length at least as long. A guard whose field_BA3 bit 1 is set (its setup sets it) hears the current noise by its power (s00a_command_800C9930): 5 within 1,500 units, 200 within COM_NOISEMODE_DIS (8,000 by default; a stage script's y option sets it), 255 at any distance, and 100 only if it is the guard the commander picked; for every power but 255 the guard must be on Snake's map, and 255 has its own test on GM_ClaymoreMap. Other powers aren't heard, such as the 4 of Snake's kick. For a 100, the commander (s00a_command_800CF9A0), outside mode 1, picks the guard within COM_NOISEMODE_DIS of the noise whose HZD_ZoneDistance to it is under 300 and least; that guard hears it and clears it, so one guard answers. Knocking on a wall makes a 100: sna_knock_80054D68 probes the wall beside Snake and, when the surface's attribute code is under 4, starts NewAfterSe, which 6 frames later plays the knock and calls GM_SetNoise(100, 16) at Snake's position. A footstep makes a 100 when Snake isn't in a duct (PLAYER_INTRUDE) and the stage script's n list gives the floor under him a nonzero noise flag. Explosions (blast.c) and stun grenades (stngrnd.c) make a 255. A patrolling guard (think2 0, s00a_command_800CD210) answers a heard noise (field_BA1 bit 1) after bits 4 and 2 and before footprints (bit 16) and sight; for a 255 it goes to the same reaction state as a sighting (think2 7), which after 21 updates (computed) sets its alert_level to 255.Code

References

  1. ^ abIn Metal Gear Solid Integral (SLPM-86247), a noise is a power, a length, and a position (GM_SetNoise), and a noise replaces the current one only if its power is higher, or equal with a length at least as long. A guard whose field_BA3 bit 1 is set (its setup sets it) hears the current noise by its power (s00a_command_800C9930): 5 within 1,500 units, 200 within COM_NOISEMODE_DIS (8,000 by default; a stage script's y option sets it), 255 at any distance, and 100 only if it is the guard the commander picked; for every power but 255 the guard must be on Snake's map, and 255 has its own test on GM_ClaymoreMap. Other powers aren't heard, such as the 4 of Snake's kick. For a 100, the commander (s00a_command_800CF9A0), outside mode 1, picks the guard within COM_NOISEMODE_DIS of the noise whose HZD_ZoneDistance to it is under 300 and least; that guard hears it and clears it, so one guard answers. Knocking on a wall makes a 100: sna_knock_80054D68 probes the wall beside Snake and, when the surface's attribute code is under 4, starts NewAfterSe, which 6 frames later plays the knock and calls GM_SetNoise(100, 16) at Snake's position. A footstep makes a 100 when Snake isn't in a duct (PLAYER_INTRUDE) and the stage script's n list gives the floor under him a nonzero noise flag. Explosions (blast.c) and stun grenades (stngrnd.c) make a 255. A patrolling guard (think2 0, s00a_command_800CD210) answers a heard noise (field_BA1 bit 1) after bits 4 and 2 and before footprints (bit 16) and sight; for a 255 it goes to the same reaction state as a sighting (think2 7), which after 21 updates (computed) sets its alert_level to 255.CodeFoxdieTeam/mgs_reversingrevised
    How we know
    74static inline void GM_SetNoise( int power, int length, SVECTOR *pos )
    ⋮
    76    int old ;
    ⋮
    78    old = GM_NoisePower ;
    79    if ( power < old ) return ;
    80    if ( power == old && length < GM_NoiseLength ) return ;
    81    GM_NoisePower = power ;
    82    GM_NoiseLength = length ;
    83    GM_NoisePosition = *pos ;
    
    source/game/g_macro.h lines 74–84 at bf9189e · upstream ↗
    62void s00a_command_800C9930( WatcherWork* work )
    ⋮
    64    CONTROL *ctrl;
    65    if ( !( work->field_BA3 & 1 ) )
    ⋮
    67        return;
    ⋮
    72        return;
    ⋮
    78        return;
    ⋮
    83    if ( GM_NoisePower == 0xFF )
    ⋮
    86        if ( !( ctrl->map->index & GM_ClaymoreMap ) &&
    ⋮
    90            return;
    ⋮
    93    else
    ⋮
    95        if ( !( ctrl->map->index & GM_PlayerMap ) )
    ⋮
    97            return;
    ⋮
    
    source/enemy/enemy.c lines 62–130 at bf9189e · upstream ↗
    677    work->field_BA3 =  7;
    
    source/enemy/watcher.c line 677 at bf9189e · upstream ↗
    1190    COM_NOISEMODE_DIS = 0x1F40;
    ⋮
    1192    ops = GCL_GetOption( 'y' );
    1193    if ( ops )
    ⋮
    1195        COM_NOISEMODE_DIS = GCL_StrToInt( ops );
    
    source/enemy/command.c lines 1190–1196 at bf9189e · upstream ↗
    714int s00a_command_800CF9A0( WatcherWork *work, int dis, int idx )
    ⋮
    721    if ( TOPCOMMAND.mode == 1 )
    ⋮
    723        goto exit;
    ⋮
    726    if ( GM_NoisePower != 0x64 )
    ⋮
    728        goto exit;
    ⋮
    733       goto exit;
    ⋮
    736    if ( GV_DiffVec3( &GM_NoisePosition, &ctrl->mov ) >= COM_NOISEMODE_DIS )
    ⋮
    738        goto exit;
    ⋮
    741    x = s00a_command_800CF940( ctrl->map->hzd, &ctrl->mov, &GM_NoisePosition );
    ⋮
    743    if ( x < 300 && x < dis )
    ⋮
    745        COM_NoiseMinDisID = idx;
    746        dis = x;
    
    source/enemy/command.c lines 714–750 at bf9189e · upstream ↗
    697int s00a_command_800CF940( HZD_HDL *hzd, SVECTOR *pos, SVECTOR *pos2 )
    ⋮
    702    from = HZD_GetAddress( hzd, pos, -1 );
    ⋮
    707        to = HZD_GetAddress( hzd, pos2, -1 );
    708        do {
    709            return HZD_ZoneDistance( hzd, from & 0xFF, to & 0xFF );
    
    source/enemy/command.c lines 697–711 at bf9189e · upstream ↗
    4128        if (sna_8004F628(work, &vec, -250, HZD_CHK_D_SEGMENT | HZD_CHK_F_SEGMENT, SEGMENT_ATR, var_t0))
    ⋮
    4130            temp_v0 = HZD_GetOnlineHazardAtr();
    4131            code = (temp_v0 >> 8) & 7;
    ⋮
    4133            if (code < 4)
    ⋮
    4135                temp_v0 = GM_GetNoiseSound(temp_v0, 0);
    4136                noise = temp_v0;
    4137                NewAfterSe(noise, 6);
    
    source/chara/snake/sna_init.c lines 4128–4137 at bf9189e · upstream ↗
    14static void Act(Work *work)
    ⋮
    16    if ( --work->time == 0 )
    ⋮
    18        // Play the sound
    19        GM_SeSetMode(&GM_PlayerPosition, work->sound, GM_SEMODE_BOMB);
    ⋮
    21        // Allow soliders/chavs/whatever to hear it
    22        GM_SetNoise(100, 16, &GM_PlayerPosition);
    
    source/chara/snake/afterse.c lines 14–22 at bf9189e · upstream ↗
    104        else
    ⋮
    106            index = asioto_800C396C(work);
    ⋮
    112            bank2 = asioto_800C392C(work);
    113            if (bank2 >= 0)
    ⋮
    115                GM_SeSet(&GM_PlayerPosition, work->se[bank2][index]);
    ⋮
    117                if (work->noise[bank2] != 0)
    ⋮
    119                    GM_SetNoise(100, 4, &GM_PlayerPosition);
    
    source/enemy/asioto.c lines 104–120 at bf9189e · upstream ↗
    90        if (GM_PlayerStatus & PLAYER_INTRUDE)
    ⋮
    92            if (GM_PlayerStatus & PLAYER_MOVE)
    
    source/enemy/asioto.c lines 90–92 at bf9189e · upstream ↗
    193    if (GCL_GetOption('n'))
    ⋮
    202            work->noise[i] = GCL_StrToInt(GCL_NextStr());
    
    source/enemy/asioto.c lines 193–202 at bf9189e · upstream ↗
    6847        sound = SE_KICK_SWING;
    ⋮
    6854        GM_SetNoise(4, 2, &work->control.mov);
    
    source/chara/snake/sna_init.c lines 6847–6854 at bf9189e · upstream ↗
    170        GM_SetNoise(255, 32, &work->pos);
    
    source/bullet/blast.c line 170 at bf9189e · upstream ↗
    224        GM_SetNoise(255, 32, &work->field_E0);
    
    source/okajima/stngrnd.c line 224 at bf9189e · upstream ↗
    1939    if ( work->field_BA1 & 4 )
    ⋮
    1941        s00a_command_800CB3F0( work );
    ⋮
    1943    else if ( work->field_BA1 & 2)
    ⋮
    1945        s00a_command_800CB610( work );
    ⋮
    1947    else if ( work->field_BA1 & 1)
    ⋮
    1949        s00a_command_800CB504( work );
    ⋮
    1951    else if ( work->field_BA1 & 16 )
    ⋮
    1953        s00a_command_800CB628( work );
    
    source/enemy/think.c lines 1939–1954 at bf9189e · upstream ↗
    558    case 255:
    559        s00a_command_800CAB74( work );
    560        s00a_command_800CEB54();
    561        work->think2 = 7;
    562        work->think3 = 16;
    
    source/enemy/think.c lines 558–562 at bf9189e · upstream ↗
    2344        case 16:
    2345        if ( s00a_command_800CBE90( work ) )
    ⋮
    2356            work->alert_level = 255;
    
    source/enemy/think.c lines 2344–2356 at bf9189e · upstream ↗
    953int s00a_command_800CBE90( WatcherWork* work )
    ⋮
    962    if ( work->count3 > 20 )
    ⋮
    964        return 1;
    ⋮
    967    work->count3++;
    
    source/enemy/think.c lines 953–969 at bf9189e · upstream ↗

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

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

    In the claim ledger

Sources

Code