facebookresearch / nle

The NetHack Learning Environment
Other
939 stars 114 forks source link

Does the permonst mlevel correspond to the Base Monster Level? #258

Closed dmadeka closed 2 years ago

dmadeka commented 2 years ago

I was trying to create an Embedding Layer for the difficulty of the monster and figured Id ask here:

In [1]: from nle.nethack import permonst                                                                                                                                                                           

In [2]: dispater, geryon = permonst(304), permonst(303)                                                                                                                                                            

In [3]: dispater.mname, dispater.mlevel                                                                                                                                                                            
Out[3]: ('Dispater', 78)

In [4]: geryon.mname, geryon.mlevel                                                                                                                                                                                
Out[4]: ('Geryon', 72)

The documentation seems to indicate it should be the base monster level. But that doesnt seem to align with the Nethack Wiki base levels for Dispater and Geryon - mostly because it looks like the NetHack Wiki is wrong! Probably needs some updating for the max level - leaving this here for future debuggers' reference!

For nn.Embedding layers, here's a useful script:

In [1]: import numpy as np                                                                                                                                                                                         

In [2]: from nle.nethack import NUMMONS, permonst                                                                                                                                                                  

In [3]: levels = []                                                                                                                                                                                                

In [4]: diffs = []                                                                                                                                                                                                 

In [5]: for i in range(NUMMONS): 
   ...:     levels.append(permonst(i).mlevel) 
   ...:     diffs.append(permonst(i).difficulty) 
   ...:                                                                                                                                                                                                            

In [6]: np.unique(levels).shape                                                                                                                                                                                    
Out[6]: (32,)

In [7]: np.unique(diffs).shape                                                                                                                                                                                     
Out[7]: (36,)

In [8]: np.unique(levels)                                                                                                                                                                                          
Out[8]: 
array([  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,
        13,  14,  15,  16,  17,  18,  19,  20,  25,  28,  30,  50,  56,
        66,  72,  78,  89, 105, 106])

In [9]: np.unique(diffs)                                                                                                                                                                                           
Out[9]: 
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
       18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 34, 36, 40, 45,
       53, 57])

It might be better to rebase the levels so that the levels Embedding index_select doesnt have a bunch of unnecessary rows.

heiner commented 2 years ago

The same issue (on a much worse scale) happens when trying to use glyph ids for embedding, see https://github.com/facebookresearch/nle/issues/21.