how does stealth work?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wobbly
    Prophet
    • May 2012
    • 2631

    how does stealth work?

    Just checking some stuff.

    A monster wakes on it's own turn? Perception is effectively multiplied by monster speed & divided by player speed.
    Chance is stealth dependent?
    Amount of sleepiness lost is distance dependent?
  • wobbly
    Prophet
    • May 2012
    • 2631

    #2
    Ok monsters wake in book keeping time not their turn. So player speed matters, monster speed doesn't?

    Comment

    • t4nk
      Swordsman
      • May 2016
      • 336

      #3
      Originally posted by wobbly
      Just checking some stuff.
      The calculations are:

      edit: (LOL, disregard that. I just remembered that my Angband repo is on 4.0.5! I recall Nick changed stealth when he changed pathfinding)
      edit2: (It seems he changed it back? well, then the description below is correct)

      Player's noise is 1 << (30 - stealth). In other words, noise is 2 in the power of (30 - stealth).

      Then, the game does this:
      Code:
      int notice = randint(1024);
      
      if (notice * notice * notice <= noise)
      {
          int wake_up_amount = 1;
      
          if (distance_to_player < 50)
               wake_up_amount = 100 / distance_to_player;
      
          wake_up_monster_a_little(wake_up_amount);
      }
      The noise stuff is in player-calcs.c: calc_bonuses() and other stuff in mon-move.c: process_monster_timed().

      edit: in 4.1.3 it's in monster_reduce_sleep()

      A monster wakes on it's own turn? Perception is effectively multiplied by monster speed & divided by player speed. Chance is stealth dependent?
      Amount of sleepiness lost is distance dependent?
      Yes to all of that.
      Last edited by t4nk; September 9, 2018, 16:04.

      Comment

      • t4nk
        Swordsman
        • May 2016
        • 336

        #4
        Originally posted by wobbly
        Ok monsters wake in book keeping time not their turn. So player speed matters, monster speed doesn't?
        I think it does. process_monster():
        Code:
            
            /* Not enough energy to move yet */
            if (mon->energy < minimum_energy) continue;
        
            ...
        
            /* Give this monster some energy */
            mon->energy += turn_energy(mspeed);
        
             /* End the turn of monsters without enough energy to move */
             if (!moving)
                 continue;
        
            /* Use up "some" energy */
            mon->energy -= z_info->move_energy;
        
            /* Check if the monster is active */
            if (monster_check_active(c, mon)) {
                /* Process timed effects - skip turn if necessary */
                 if (process_monster_timed(c, mon))

        Comment

        • DavidMedley
          Veteran
          • Oct 2019
          • 1004

          #5
          How does distance affect stealth?

          Incorrect conclusions deleted, corrected and reposted below.
          Last edited by DavidMedley; January 24, 2020, 04:48.
          Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

          Comment

          • DavidMedley
            Veteran
            • Oct 2019
            • 1004

            #6
            Monster Awareness Ratings

            I'm going to relate what my research has tentatively discovered. Confirmation or correction greatly appreciated. I'm sure I'm missing something, based on experiments.

            Question: What do the monster "awareness" ratings mean in game terms?

            Answer:
            The descriptions given in monster recall correspond to values between 0 and 255. The table below shows what a monster race's "sleepiness" is based on that description.
            Code:
            Min	Max	Description
            0	0	is ever vigilant for
            1	1	is vigilant for
            2	3	is very observant of
            4	5	is observant of
            6	10	is fairly observant of
            11	25	takes a while to see
            26	45	takes quite a while to see
            46	75	tends to overlook
            76	95	pays little attention to
            96	200	pays very little attention to
            201	255	prefers to ignore
            When an individual monster is created in the dungeon (not summoned) it starts with a personalized sleepiness equal to RS*2+1d(RS*10) where RS is racial sleepiness. The level 1 "wild dog" has racial sleepiness 10, so each one will start with 20+1d100 individual sleepiness.

            Each time a monster would normally get a turn, you have a chance to disturb its sleep. You must be within its detection range. If you do disturb it, its sleepiness goes down by 1 (or more if you're closer than 50 feet). If the monster reaches 0 sleepiness it wakes up. The chance for you to disturb a monster is 100% at stealth 0 or less, and decreases by almost exactly 50% for every 3 points of stealth, up to 28 where the minimum of about 0.20% is reached.

            --------
            But by that description, monsters would sleep about 10x too much!! So I must be missing something. Here's the code that I'm pretty sure converts the racial sleep into individual sleep (I need better terms there, as well).

            Code:
            	/* Enforce sleeping if needed */
            	if (sleep && race->sleep) {
            		int val = race->sleep;
            		mon->m_timed[MON_TMD_SLEEP] = ((val * 2) + randint1(val * 10));
            	}
            Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

            Comment

            • Pete Mack
              Prophet
              • Apr 2007
              • 6883

              #7
              David--look at the code above. the amount of wakeup is also scaled, by 100/distance. This means that you have to be nearby to wake it up fast, and adjacent you will wake him up in 1/10 nominal time.
              Last edited by Pete Mack; January 24, 2020, 03:08.

              Comment

              • DavidMedley
                Veteran
                • Oct 2019
                • 1004

                #8
                OK. So when I read
                Code:
                int wake_up_amount = 1;
                
                    if (distance_to_player < 50)
                         wake_up_amount = 100 / distance_to_player;
                
                    wake_up_monster_a_little(wake_up_amount);
                I assumed that distance must be in feet. But if it's in squares then that's the order of magnitude I was missing. Thanks!!!
                Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

                Comment

                • Pete Mack
                  Prophet
                  • Apr 2007
                  • 6883

                  #9
                  I do notice that perfect stealth is not actually possible, as there is a 1/1024 chance of disturbance even when stealth is 30.

                  Comment

                  • Derakon
                    Prophet
                    • Dec 2009
                    • 9022

                    #10
                    Originally posted by DavidMedley
                    OK. So when I read
                    Code:
                    int wake_up_amount = 1;
                    
                        if (distance_to_player < 50)
                             wake_up_amount = 100 / distance_to_player;
                    
                        wake_up_monster_a_little(wake_up_amount);
                    I assumed that distance must be in feet. But if it's in squares then that's the order of magnitude I was missing. Thanks!!!
                    I'm pretty sure that all of the units in-game are purely aesthetic, and you should divide by the greatest common denominator to get the numbers the code uses. For example, all item weights in the code are in decipounds, a bonkers unit if ever there was one.

                    Comment

                    • Pete Mack
                      Prophet
                      • Apr 2007
                      • 6883

                      #11
                      I am kinda surprised the game doesn't use ounces. At every other opportunity, the original coding used shift operators as much as possible.

                      Comment

                      • DavidMedley
                        Veteran
                        • Oct 2019
                        • 1004

                        #12
                        How does distance affect stealth?

                        Question: How does distance affect stealth?

                        Quick Answer: The expected number of turns until a monster wakes is proportional to your distance from it. If you are twice as far, it takes twice as many turns to wake up.

                        Long Answer:
                        We know from the monster recall that there's a max distance at which a creature can hear you. This is calculated essentially the same as walking distance i.e., down hallways, around corners, through open/closed/broken doors, over passable rubble, but not through walls or impassable rubble. Additionally, a monster can see you, which ignores all light levels but otherwise works as you would expect (20 squares max, no visual obstructions).

                        If a monster can "notice [hear] you from 60 feet" you are safe from being heard at 6 squares away or more. In addition, every 3 full points of stealth you have reduces this by 1 square. All monsters can also notice [see] you from 210 feet, so you are safe from being seen at 21 squares away or if LOS is blocked.

                        If you are within this detection range, distance does not affect your chance to disturb the monster (stealth does). But distance can greatly affect how much you wake the monster per turn. The amount a monster wakes (loses sleepiness) is inversely proportional to the distance: 100/distance (round down). If a monster reaches 0 sleepiness, it wakes.

                        I'll address just how many sleepiness points a monster has and what your chance to disturb a monster is elsewhere.

                        Quick word on smell: If you look up a monster's stats (in monster.txt or elsewhere), smell is listed near hearing for most non-humans. This is not used for waking a monster at all. It is used to help an awake monster decide where to go to find you. Stealth has no effect.

                        -----

                        Some relevant code snippets

                        In the code below, local_noise is the distance noise has to travel from the player to the monster in game squares. Shows distance is inversely proportional to sleep reduction (closer wakes more).
                        Code:
                        int sleep_reduction = 1;
                        int local_noise = c->noise.grids[mon->grid.y][mon->grid.x];
                        /* Test - wake up faster in hearing distance of the player 
                         * Note no dependence on stealth for now */
                        if ((local_noise > 0) && (local_noise < 50)) {
                        	sleep_reduction = (100 / local_noise);
                        }
                        The code below shows that monsters cannot hear you at exactly their "notice from" distance, and that stealth can reduce that distance.
                        Code:
                        static bool monster_can_hear(struct chunk *c, struct monster *mon)
                        {
                        	int base_hearing = mon->race->hearing
                        		- player->state.skills[SKILL_STEALTH] / 3;
                        	if (c->noise.grids[mon->grid.y][mon->grid.x] == 0) {
                        		return false;
                        	}
                        	return base_hearing > c->noise.grids[mon->grid.y][mon->grid.x];
                        }
                        Monsters also cannot smell you at their max smell distance
                        Code:
                        static bool monster_can_smell(struct chunk *c, struct monster *mon)
                        {
                        	if (c->scent.grids[mon->grid.y][mon->grid.x] == 0) {
                        		return false;
                        	}
                        	return mon->race->smell > c->scent.grids[mon->grid.y][mon->grid.x];
                        }
                        Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

                        Comment

                        • DavidMedley
                          Veteran
                          • Oct 2019
                          • 1004

                          #13
                          Originally posted by Pete Mack
                          I do notice that perfect stealth is not actually possible, as there is a 1/1024 chance of disturbance even when stealth is 30.
                          I'm pretty sure it's actually 2/1024
                          Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

                          Comment

                          • Pete Mack
                            Prophet
                            • Apr 2007
                            • 6883

                            #14
                            randint starts at 1.

                            Comment

                            • DavidMedley
                              Veteran
                              • Oct 2019
                              • 1004

                              #15
                              It may have changed
                              Code:
                              int player_noise = 1 << (30 - stealth);
                              int notice = randint0(1024);
                              ...
                              if ((notice * notice * notice) <= player_noise)
                              {reduce sleep}
                              notice can be 0 or 1, so notice^3 can be, too. player_noise can't get less than 1. If they're both 1, sleep is reduced.
                              Please like my indie game company on Facebook! https://www.facebook.com/RatherFunGames

                              Comment

                              Working...
                              😀
                              😂
                              🥰
                              😘
                              🤢
                              😎
                              😞
                              😡
                              👍
                              👎