PDA

View Full Version : [3.3] Potential problem with low power random artifacts


PowerWyrm
September 7, 2011, 13:40
From scramble_artifact() in randart.c:


/* Set depth and rarity info according to power */
...
a_ptr->alloc_max = MIN(127, (ap * 4) / 5);
a_ptr->alloc_min = MIN(100, ((ap + 100) * 100 / max_power));


The problem here is that for ap less than 20, the result is a_ptr->alloc_max less than a_ptr->alloc_min.

From make_artifact():


/* Enforce maximum depth (strictly) */
if (a_ptr->alloc_max < p_ptr->depth) continue;


This means that low power random artifacts will have a really small depth range. If the item has a base level that is much higher, the random artifact may even never be generated.

Another problem, from make_artifact():


/* XXX XXX Enforce minimum "depth" (loosely) */
if (a_ptr->alloc_min > p_ptr->depth)
{
/* Get the "out-of-depth factor" */
int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

/* Roll for out-of-depth creation */
if (randint0(d) != 0) continue;
}


After enforcing that depth is lower than a_ptr->alloc_max, a rarity penalty is applied for out-of-depth randarts. With low ap randarts, since a_ptr->alloc_max is less than a_ptr->alloc_min, they are all considered out-of-depth! The out-of-depth factor will also increase as ap decreases... leading to less powerful randarts being generated... less often.

Fix: ensure that a_ptr->alloc_max is always greater than a_ptr->alloc_min

PowerWyrm
September 7, 2011, 13:49
For a_ptr->alloc_max, something should also ensure that the artifact has some decent chance to be generated. This means checking somehow against kind->alloc_min...

Magnate
September 7, 2011, 13:50
From scramble_artifact() in randart.c:


/* Set depth and rarity info according to power */
...
a_ptr->alloc_max = MIN(127, (ap * 4) / 5);
a_ptr->alloc_min = MIN(100, ((ap + 100) * 100 / max_power));


The problem here is that for ap less than 20, the result is a_ptr->alloc_max less than a_ptr->alloc_min.

From make_artifact():


/* Enforce maximum depth (strictly) */
if (a_ptr->alloc_max < p_ptr->depth) continue;


This means that low power random artifacts will have a really small depth range. If the item has a base level that is much higher, the random artifact may even never be generated.

Another problem, from make_artifact():


/* XXX XXX Enforce minimum "depth" (loosely) */
if (a_ptr->alloc_min > p_ptr->depth)
{
/* Get the "out-of-depth factor" */
int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

/* Roll for out-of-depth creation */
if (randint0(d) != 0) continue;
}


After enforcing that depth is lower than a_ptr->alloc_max, a rarity penalty is applied for out-of-depth randarts. With low ap randarts, since a_ptr->alloc_max is less than a_ptr->alloc_min, they are all considered out-of-depth! The out-of-depth factor will also increase as ap decreases... leading to less powerful randarts being generated... less often.

Fix: ensure that a_ptr->alloc_max is always greater than a_ptr->alloc_minThis one isn't quite so terrible, but thanks for spotting and reporting. Randarts don't get power below 35 (the Phial), so the <20 issue doesn't arise. I can't imagine a standart weaker than the Phial that would get added to V, but you're right that an assert would be a useful sanity check.

Second, the special artifacts (which include the two lowest-powered, the Phial and Star) have different code governing their max depths, so they have a broader range. It does mean that very weak weapons and armour (which tend to start at power ~50) have a small range in which to be found, but ...

... I'm going to rewrite randart.c completely for 3.4, and the depth and alloc computation will be different.