Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old August 10, 2010, 01:19   #1
nullfame
Adept
 
Join Date: Dec 2007
Posts: 165
nullfame is on a distinguished road
[V] Question on Extracting Monster Power

I've become very interested in a monster power calculation which I mentioned in passing in another thread. Magnate asked me to look at eval_r_power in init1.c and pointed me at ticket 869, review and revise said algorithm. I've read the algorithm pretty closely and though I don't have any specific suggestions (yet!) I noticed a few omissions (e.g., ARROW_1-4) and likely errors (e.g., if (rsf_has(r_ptr->spell_flags, RSF_TELE_LEVEL) && spell_dam < 40) spell_dam = 25; when I assume you would want the assignment to be 40 or the test 25). I don't think these minor issues are contributing to the power ratings being out of whack as described in the ticket but ironing those out seems like an obvious starting point before making suggestions.

I just want to be able to print the monster list and their current power ratings so as I iron those issues out I can verify my results. I've written maybe 10 lines of C in my life but am quite comfortable with a number of descendants (especially PHP, Java, Perl, and JavaScript... I'll give you 1 guess as to what I do for a living). I'm on a Mac and can get it to compile which is always a bonus. I'm using r2035 for now.

Reading the code I came across emit_r_info_index in init1.c which sounds like a real winner (once one realizes "r_info" refers to monsters... heh). So I tacked this on after the description:

Code:
file_putf(fp, "D:%d:%d\n",r_ptr->power, r_ptr->highest_threat);
I also tried doing it as a comment before appending it to the description. Then over in init2.c I dropped the conditional from this line in init_r_info:
Code:
if (arg_rebalance) r_head.emit_info_txt_index = emit_r_info_index;
I don't know if arg_rebalance is true or false (I assume) or what. I also tried explicitly setting it to true.

So I build, launch, roll a character, take a turn in town, and quit assuming it would spit my new monster.txt out but that doesn't appear to be the case. Honestly I'm not even sure where to look (I assume in the "package contents" of Angband.app).

Or, is this just a totally silly approach to begin? Am I missing something else fundamental?

Don't ask me why my curiosity is so piqued by this obscure and utterly unimportant function and ticket with zero gameplay value. I like to think of myself as a special brand of crazy.
nullfame is offline   Reply With Quote
Old August 10, 2010, 03:10   #2
myshkin
Angband Devteam member
 
Join Date: Apr 2007
Posts: 334
myshkin is on a distinguished road
You were almost there...

Quote:
Originally Posted by nullfame View Post
Then over in init2.c I dropped the conditional from this line in init_r_info:
Code:
if (arg_rebalance) r_head.emit_info_txt_index = emit_r_info_index;
I don't know if arg_rebalance is true or false (I assume) or what. I also tried explicitly setting it to true.
By default, arg_rebalance is true only if you give angband the command-line option -r. The Windows port supports setting this variable via an .ini file, but the Mac OS X port doesn't seem to have the same.

Quote:
So I build, launch, roll a character, take a turn in town, and quit assuming it would spit my new monster.txt out but that doesn't appear to be the case. Honestly I'm not even sure where to look (I assume in the "package contents" of Angband.app).
It's in $HOME/Library/Preferences/Angband/monster.txt. Notice

Code:
 /* Open for output */
path_build(user_file, 1024, ANGBAND_DIR_USER, format("%s.txt", filename));
in init_info() of init2.c. ANGBAND_DIR_USER gets defined earlier in init2.c, in init_file_paths().

Code:
#ifdef PRIVATE_USER_PATH

        /* Build the path to the user specific directory */
        path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VERSION_NAME);
        ANGBAND_DIR_USER = string_make(buf);

#else /* !PRIVATE_USER_PATH */

        ANGBAND_DIR_USER = string_make(format("%suser", datapath));

#endif /* PRIVATE_USER_PATH */
That definition relies on PRIVATE_USER_PATH, which, for you, is set in Makefile.osx:

Code:
CFLAGS = \
        -I. $(WARNINGS) -std=gnu99 $(OPT) -DMACH_O_CARBON -DHAVE_MKSTEMP \
        -DPRIVATE_USER_PATH=\"~/Library/Preferences\" -DUSE_PRIVATE_PATHS \
        -arch ppc -arch i386 -mmacosx-version-min=10.0
myshkin is offline   Reply With Quote
Old August 10, 2010, 03:28   #3
nullfame
Adept
 
Join Date: Dec 2007
Posts: 165
nullfame is on a distinguished road
Quote:
Originally Posted by myshkin View Post
You were almost there...

It's in $HOME/Library/Preferences/Angband/monster.txt.
Ha! There is it. Grrr, and I was so proud of myself having stumbled that far along too. I even looked in there but was looking for an edit subdirectory and didn't notice it in my mess of dumps and preferences. Thanks for the help.
nullfame is offline   Reply With Quote
Old August 10, 2010, 15:26   #4
andrewdoull
Unangband maintainer
 
andrewdoull's Avatar
 
Join Date: Apr 2007
Location: Sydney, Australia
Age: 44
Posts: 872
andrewdoull is on a distinguished road
Any errors are undoubtedly my fault - I updated the power calculation code at one point and problems like ARROW1-4 missing are inherited from the Unangband code.

Andrew
__________________
The Roflwtfzomgbbq Quylthulg summons L33t Paladins -more-
In UnAngband, the level dives you.
ASCII Dreams: http://roguelikedeveloper.blogspot.com
Unangband: http://unangband.blogspot.com
andrewdoull is offline   Reply With Quote
Old August 10, 2010, 16:39   #5
nullfame
Adept
 
Join Date: Dec 2007
Posts: 165
nullfame is on a distinguished road
Actually it's a nice piece of code and is more or less what I had in mind (scale for damage and HP, assign arbitrary values to non-damage spells). As a contributor, maybe I can ask you a question of intent: why is monster power scaled by level?

The ticket compares the power of snagas (28) to uruks (24). Everything gets a (what I'm calling) "raw power" and then that is scaled to the average HP and average damage output of everything on previous levels. Snagas are scaled relative to centipedes, snakes, and yeeks. Probably the most dangerous thing you see beforehand is a green naga. So, naturally their power rating is high for their level. Uruks are scaled against early dragons, demons, and loner humans/elves. While their "raw power" (numerator) is higher than the snaga's the product of average monster damage and hp (denominator) grows much quicker in those early levels.

I feel like a minor tweak to that calculation could make a difference, I just want to understand why it was done that way so I can factor that in to my proposal. Perhaps it's nothing more than keeping the power ratings within a smaller range of numbers.
nullfame is offline   Reply With Quote
Old August 10, 2010, 18:34   #6
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,916
Derakon is on a distinguished road
I can come up with one explanation: it helps you to determine how valuable a given piece of anti-Foo equipment is at a given depth in the dungeon. Slay Orc weapons would be very useful when you first find Snagas since they're practically the most dangerous thing around. By the time you get to Uruks, you generally have more dangerous creatures around to deal with, so a Slay Orc brand isn't so helpful.
Derakon is offline   Reply With Quote
Old August 31, 2010, 20:18   #7
Magnate
Angband Devteam member
 
Join Date: May 2007
Location: London, UK
Posts: 5,057
Magnate is on a distinguished road
Send a message via MSN to Magnate Send a message via Yahoo to Magnate
Quote:
Originally Posted by Derakon View Post
I can come up with one explanation: it helps you to determine how valuable a given piece of anti-Foo equipment is at a given depth in the dungeon. Slay Orc weapons would be very useful when you first find Snagas since they're practically the most dangerous thing around. By the time you get to Uruks, you generally have more dangerous creatures around to deal with, so a Slay Orc brand isn't so helpful.
That's a fair point, and I find myself ambivalent about whether the power calc should rate snagas as more dangerous than uruks or not ... for their depth. I think the problem is that the power calc is sort of expected to represent the absolute power of the monster, i.e. wherever it's found. If you meet a snaga and an uruk together before you're powerful enough to ignore both, it's pretty obvious which one's more dangerous. This is the thinking behind the original algorithm (which has its roots in randart generation).

Nullfame: how much hassle would it be to maintain two values of power, one for absolute and one modified for native depth? And by the way, huge congrats on working out as much as you did without help - that's way further than I got when I started. And thanks again for picking this up - I'm not sure it would ever have reached the top of my to-do list. I look forward to testing and committing it. Did you ever get the emitted monster.txt to show the power rating, btw? That would be a good start - but your next job is to get it to do that *without* rebalancing!
Magnate is offline   Reply With Quote
Old August 31, 2010, 21:31   #8
nullfame
Adept
 
Join Date: Dec 2007
Posts: 165
nullfame is on a distinguished road
Quote:
Originally Posted by Magnate View Post
how much hassle would it be to maintain two values of power, one for absolute and one modified for native depth?
I am glad you suggested this because it is what I am doing. IMO this will not be useful because, I believe by definition, raw_power will always be in the same order as scaled_power on the same level and they are meaningless on different levels, but I haven't fully fleshed out my thoughts on the subject.

I was planning to submit my patch in two phases, unless you advise me otherwise:

1. Changes I consider to be non-controversial: accounting for ARROW, BOULDER, SHRIEK, ESCORT, ESCORTS, HURT_LIGHT, and adjusting the aforementioned test/assignment inconsistencies. I have this diff ready to submit (on another machine). These will not close the ticket.

2. Changes I think fix the problem but fundamentally alter the algorithm: using the sum of spell damage and melee damage instead of the max of the two, not scaling by level for the power value (but saving a scaled_power), using a constant overflow adjustment rather than by level (i.e., scaling by level again). I have this code written but haven't prepared a diff. I'm writing a detailed explanation my proposals for the few people that might be interested. Maybe this weekend.

There may be other minor changes I'm missing but these are certainly the most important ones. I've looked a lot at how power and depth compare within a given monster symbol and that seems pretty consistent and when they are out of order it is usually because the power value is right (Bolg) or they are so close on depth or power that it really doesn't matter (low mushrooms). I haven't studied how the power value looks across symbols by depth but being right within a race is an encouraging sign.
nullfame is offline   Reply With Quote
Old August 31, 2010, 21:45   #9
Magnate
Angband Devteam member
 
Join Date: May 2007
Location: London, UK
Posts: 5,057
Magnate is on a distinguished road
Send a message via MSN to Magnate Send a message via Yahoo to Magnate
Quote:
Originally Posted by nullfame View Post
I am glad you suggested this because it is what I am doing. IMO this will not be useful because, I believe by definition, raw_power will always be in the same order as scaled_power on the same level and they are meaningless on different levels, but I haven't fully fleshed out my thoughts on the subject.

I was planning to submit my patch in two phases, unless you advise me otherwise:

1. Changes I consider to be non-controversial: accounting for ARROW, BOULDER, SHRIEK, ESCORT, ESCORTS, HURT_LIGHT, and adjusting the aforementioned test/assignment inconsistencies. I have this diff ready to submit (on another machine). These will not close the ticket.

2. Changes I think fix the problem but fundamentally alter the algorithm: using the sum of spell damage and melee damage instead of the max of the two, not scaling by level for the power value (but saving a scaled_power), using a constant overflow adjustment rather than by level (i.e., scaling by level again). I have this code written but haven't prepared a diff. I'm writing a detailed explanation my proposals for the few people that might be interested. Maybe this weekend.

There may be other minor changes I'm missing but these are certainly the most important ones. I've looked a lot at how power and depth compare within a given monster symbol and that seems pretty consistent and when they are out of order it is usually because the power value is right (Bolg) or they are so close on depth or power that it really doesn't matter (low mushrooms). I haven't studied how the power value looks across symbols by depth but being right within a race is an encouraging sign.
This all sounds excellent - thanks for your work. I'm sure you're right about the depth thing: I think we might not need the scaled_power value, at least for my purposes (items) - though it might come in handy in dungeon generation one day.

In case it's helpful, here's the rest of my thinking when I created the ticket: my ultimate aim is to get rid of all the arbitrary power constants which are used to peg the values of various attack methods, spells etc. (These are not to be confused with the actual damage constants in monster/constants.h - those we can't get rid of.)

So ideally the power algorithm would be constructed in such a way that we can use the constants for the time being, and replace them with formulae piece by piece, as they become available. This is subject to the Pareto principle: using a formula for the power of breath damage is easy (so easy in fact that it's already there, IIRC), but calculating the power value of TELE_AWAY is probably unachievable - certainly more effort than it's worth.

Once you've done your first two stages, I'd be interested in your views on this ambition, and which values you think we could calculate.
Magnate is offline   Reply With Quote
Old September 6, 2010, 04:58   #10
nullfame
Adept
 
Join Date: Dec 2007
Posts: 165
nullfame is on a distinguished road
I'm not sure the right way to submit a patch (can I combine all the diffs in to one file somehow?) but here is a tar.gz with the two patches (edit: against 2041):

init1.c-AMF-p1.diff: just the non-controversial changes.
init1.c-AMF-p2.diff and types.h-AMF-p2.diff: the contents of the first patch and other changes I propose.

The non-controversial changes are accounting for a number of spells, fixing a few comparison/assignment inconsistencies, modifying for escorts (giving a small bonus than friends), and modifying for HURT_LIGHT.

My major changes are:

1. Not scaling the monsters by level. Instead the raw power is used for the power rating but a scaled_power value is still saved.

2. Prevent overflow consistently across all levels. There was code with the comment "use an adjustment factor to prevent overflow" with code that started dividing the power value by 100 at level 40, 10,000 at 65, and 1,000,000 at 95. I assume that was to prevent integer overflow. I think this would be better handled with a consistent value (what I've done) or maybe an exponential.

3. Add magic to melee, don't pick the maximum of the two. Spell power is scaled by frequency but melee power is not. This results in having 90% of monsters rated by melee alone. Monsters with spell casting abilities are simply more dangerous, especially when they can cast in addition to melee output.

Mostly I think it works. Here are a few strange outliers:

Death quasit < Storm giant
Castamir the Usurper < Aranea
Smaug the Golden < Elder aranea
Azriel, Angel of Death < The Cat Lord

I'm not sure what to do about the first one. It might even be right. The other 3, and a few other similar examples, says to me FRIENDS and ESCORTS are probably overvalued. And summon kin, while often dangerous, is non-threatening on a cat. That kinda brings to to Magnate's point:

Quote:
Originally Posted by Magnate View Post
ideally the power algorithm would be constructed in such a way that we can use the constants for the time being, and replace them with formulae piece by piece, as they become available.
I like this and believe figuring some of that out should probably be undertaken before trying to tweak the flags above. You're gonna have arbitrary numbers here and there, but the more that is formulaic the more reference you have for choosing the arbitrary numbers.

I think you could calculate the value of summons and summon-esq spells (SHRIEK, TELE_AWAY) by looking at the danger levels of what is likely to be summoned. E.g., the most dangerous thing the cat lord can summon is a sabre-tooth tiger which isn't a major threat on dl66. Saruman can bring a lot of threats to the table on dl60. You would have to run through the list recalculating a few times.

Something like HASTE and HEAL probably don't belong with attack spells and can be removed. Some are hard to think about like FORGET but maybe with some thought you could pin it between two formulaic values (e.g., it's less dangerous than a frost bolt but more than ARROW_1). Blow effects like TERRIFY or LOSE_CON would need similar thought.

I would be willing to work further on it at some point, depending what people think.
Attached Files
File Type: zip Monster-Power-Patches-AMF.zip (2.1 KB, 153 views)

Last edited by nullfame; September 6, 2010 at 05:00. Reason: diffs are for 2041
nullfame is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
OAngband and power-diving Therem Harth Variants 6 October 3, 2012 01:05
Is it easier to find the Rings of Power now? Bilbo Vanilla 7 June 30, 2010 04:21
Object and Monster generation question Zikke Vanilla 30 April 21, 2010 04:13
The power of you andrewdoull Idle chatter 15 December 28, 2007 19:20
Expanding the power of the look command again with mouseover. Irashtar Vanilla 4 October 20, 2007 03:28


All times are GMT +1. The time now is 05:46.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.