The Official NPPAngband And NPPMoria Forum

You are not logged in.

- Topics: Active | Unanswered

Pages: **1**

**CyclopsSlayer****Member**- Registered: 2007-10-22
- Posts: 104

We were having a discussion in voice comm this evening and a comment came up that made me think of the spell failure chances in the various *bands.

What are all the modifiers to the %Fail, or is it just susceptible to pseudo RNG ringing? At a 4% Fail I would expect one in 25 spells failing, but it sure seems higher than that, but I would need to parse a log to be 100% sure.

- Less than max HP/Mana?

- Afflicted by a condition? (stun, bleed, poison...)

- Caster is in Melee? or has been hit recently?

- others?

Probably just an artifact of perception, and only noticing when things go wrong, but...

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

It is a simple percentage, but I agree it always seems higher.

- Less than max HP/Mana? - does not affect spellcasting chances.

- Afflicted by a condition? (stun, bleed, poison...) stunning increases spell failure rate. And some side effects, like confusion, blindness, and hallucination, prevent the player from casting spells.

- Caster is in Melee? or has been hit recently? Only it it causes a negative side effect like stunning.

- others? - Various equipment penalties, such as a priest wielding an edged weapon, or a mage wearing unsuitable gloves.

Offline

**CyclopsSlayer****Member**- Registered: 2007-10-22
- Posts: 104

Just did a quick and dirty test, 5 full mana bars from my L28 Ranger, so 190 casts of Acid Bolt, mana cost 1, 9% Failure.

190 Casts

Predicted Failure 17 (17.1)

Actual Failures 19 (Higher than expected but not outside margin of error for the sample size)

What was interesting was that 5 of those failures came grouped together. Which if I remember my math properly is something like 1:1/0.09^4 or 15,240. (caveat; it has been decades since my last class in statistics so, ymmv)

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

It definitely seems like spells are more likely to fail consecutive times. I will have to think about that one.

Offline

**RunningAway****Member**- Registered: 2012-02-27
- Posts: 246

It feels to me like failures cluster.

However, even if you cast a spell on consecutive turns, remember that there is a lot more going on between those castings. It's likely with all of the other processing that the rng is being called hundreds of times each turn.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

I remember reading that the RNG only reads 28 bits at a time, due to some reason 20 years ago. I wonder if on newer computers or newer compilers the game isn't replacing those last 4 bits with zeros sometimes.

Offline

**camb****Member**- Registered: 2006-01-29
- Posts: 706

NPPAngband wrote:

It definitely seems like spells are more likely to fail consecutive times.

Yes I often notice failure clusters too. They seem to happen quite regularly, unless their nuisance value is making them seem more prevalent than they really are.

And occasionally success clusters with rare items, e.g. two gain stat potions or two rings of speed occurring in quick succession at low levels etc.

Cameron

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

Exactly. Most of these rarity checks are (if random number between 0 and X equals zero), where if x is zero, it passes the test. So a string of zeros in the RNG could easily become a string of statistically unlikely events.

Offline

**CyclopsSlayer****Member**- Registered: 2007-10-22
- Posts: 104

A friend that plays Vanilla exclusively was also reporting clustered failures last night after his test. So some core function or code in common may be at fault?

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

I just ran a fair amount of testing on the RNG, and over the long haul it is consistently random. I first started with generating 20000 numbers between 1 and 20, and recorded the number of times the same number repeated (results should center around 1000 times. Here were the results from running that test 15 times:

969, 997, 996, 1005, 968, 1007, 1004, 1006, 965, 1035, 1060, 1021, 971, 981, 995.

I then ran a test where I recorded the number of times a random number between 1 and 20 came up when generating that number a million times, and and also kept track of how many times the same number repeats. Again, the count for each number was all of the numbers were pretty close to 50000, as it should be.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

However, I think the key to what we are trying to test is not long-term randomness, but rather the bessel function, which answeres questions like: If you roll 10 six sided dice, needing 4s to hit, what are the odds of getting 7 or more hits? I played around with it, and I did not see any special patterns. While doing this I tracked the number of times a number repeated. Sometimes it would roll 100 numbers without repeating once. Sometimes the same number repeated 5 out of 20 times. But I don't see any special patterns.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

So I tried looking for streaks of low numbers out of a million times generating a number between 0 and 99.

Essentially, with a 2% failure rate, in a million tries it consistently failed is 3 times straight at the most. With a 5% failure rate, in a million tries the max failure rate was consistently 7 times in a row.

Don't get me wrong. I still think there is something slightly wrong with the RNG, I just haven't been able to devise a test to figure it out

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

Here is the code if anybody wants to play with it. I just placed this at the beginning of process_player in dungeon.c, and walked around the dungeon for a bit, so every time I moved it generated new results:

/* Test the RNG */

if (TRUE)

{

int this_roll, last_roll;

u32b streak = 0, max_streak = 0;

u32b i, x = 100, succeeds = 0;

last_roll = randint0(x);

for (i = 0; i < 1000000; i++)

{

this_roll = randint0(x);

if (this_roll < 2)

{

streak++;

succeeds++;

}

else

{

if (max_streak < streak) max_streak = streak;

streak = 0;

}

last_roll = this_roll;

}

playtesting(format("succeeds is %d, max_streak is %d ", succeeds, max_streak));

}

Offline

**camb****Member**- Registered: 2006-01-29
- Posts: 706

NPPAngband wrote:

if (this_roll < 2)

Wasn't the special case 0? And if so shouldn't it be: if (this_roll < 1) ...

Cameron

Offline

**RunningAway****Member**- Registered: 2012-02-27
- Posts: 246

Regarding the test code. If you really wanted to test the randomness, you should use a separate seed because this is not really recording sequential calls to the rng.

For non-coders, random number generators are not random because computers don't do random well, but a good one fakes it pretty well. What happens is that you start with a number, called a 'seed' that is run through a set of calculations that produce another number that should, in theory, differ significantly from the original. That's the output. You keep track of this number, and each time you need a random number, you take the last output and run it through again to get the next random number. The upshot is that the sequence is repeatable. Each time you start with a given seed number, you get the exact same sequence of numbers as output. The challenge is to make sure the numbers are random enough to make it difficult for an observer to predict the next number. Even then, proving that it's random enough requires a lot of statistical analysis.

Take the town level, for example. The layout of the town map is not stored anywhere. What happens is that the town uses its own random number seed, which is the only thing stored when you are not on the town level. The town is recreated from scratch each time you go there by feeding the town seed into the rng because using the same seed always guarantees the same results.

Check out z-rand.h and z-rand.c for the random number generator used by Angband.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

camb wrote:

NPPAngband wrote:if (this_roll < 2)

Wasn't the special case 0? And if so shouldn't it be: if (this_roll < 1) ...

Cameron

Yes. I was testing a bunch of numbers there.... 1, 2, 3, 5. That was just the last iteration.

I had done an extensive test before that one about how often the # zero showed up twice in a row.

Offline

**RunningAway****Member**- Registered: 2012-02-27
- Posts: 246

I just realized something. The color shimmer effects (option animate_flicker) affect game outcome because it uses the same random number generator and seed as the rest of the game.

With this setting turned on, if something is shimmering on screen, the amount of time you take between commands affects the outcome. If this setting is turned off, a saved game is repeatable when you use the exact same keypresses each time regardless of how long you take between commands.

See multi_hued_attr() in cave.c.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

Good point! Maybe that should have its own special random seed.

I was thinking about adding the ability to record games, like some other roguelikes have. If I ever added it I'll bet I would have gone crazy trying to figure out why it wasn't working.

Offline

**RunningAway****Member**- Registered: 2012-02-27
- Posts: 246

I looked at the random number generator code. Switching between seeds looks like a lot of overhead, especially if you're going to be switching back and forth a lot.

I suppose you could make a random number struct that encapsulates all of the data. Use pointers to switch back and forth.

Offline

**NPPAngband****NPPAngband Maintainer**- Registered: 2004-07-01
- Posts: 1,647
- Website

I think that is what already happens. For example, the town generator and player ghost template generator have their own special RNG.

In this case, switching to a special RNG for color shimmer effects only happens when the game is waiting for player input (where the game spends 99.99% of its processing time), so it would not slow down anything.

Offline

Pages: **1**