
Location
Badges
Activity
Challenge Categories
Challenges Entered
ASCII-rendered single-player dungeon crawl game
Latest submissions
See Allgraded | 150708 | ||
failed | 150701 | ||
graded | 148917 |
Participant | Rating |
---|---|
![]() |
0 |
Participant | Rating |
---|
NeurIPS 2021 - The NetHack Challenge

Are the specs for the machine that the evaluations are run on available anywhere?
Over 3 years agoHi All!
Firstly thanks for this discussion and everyoneβs contribution to it. Itβs been very valuable for us organizers!
Our solution to the above problem is not the change the rules (30 mins will still be the maximum each agent gets for acting), but rather to ensure that network latency does not βrun down the clockβ on game time, or get counted (as it clearly shouldnβt).
As such, AIcrowd have implemented a solution that should allow a random model to take more than 20,000 steps per second, in the environment, sequentially. Under the previous calculations this should allow at least 20,000 * 0.5 * 3600 / 128 =~ 280k
steps per episode for a random agent.
I should also note that in final evaluation, we run 4096 episodes over 24hrs (instead of 512 in 2 hrs) further adding to the max number of steps you can run can achieve 280k * (512 / 4) / (4096 / 48 )
.
Iβm sure @dipam can fill in with more specific details on timing later. I hope this clears up the matter and many thanks to AIcrowd for making it possible!

Getting started without GPU?
Over 3 years agoA touch overdue here, but since this question was posted, prebuilt Docker images have been released as well as a sample colab for running baselines.

Colab Notebook including submission and working ttyrec recording
Over 3 years agoHi all. Just vis a vis the original question/colab notebooks there is now a separate Baselines notebook, available on colab, and in the Notebooks section of the Competition Pages

Action and observation int mapping
Over 3 years agoFor glyphs I recommend looking a Trying to print out natural-language glyph meanings

Hardcoding "Elbereth"
Over 3 years agoHey there!
Something like this would be totally allowed by the rules. The best place to do this is NOT to extend the base env - because AIcrowd will always create the NetHackChallenge-v0 env.
As you mention, the best thing to do is write a wrapper for this environment that wraps around NetHackChallenge. I know it feels hacky, but the simplest solution is to write wrapper that would override the step function, accepting a slightly larger action space, and then when this action is taken, stepping through [βEβ, β-β, βEβ, βlβ, βbβ, βeβ, βrβ,β¦] - as you mentioned! That would probably be the solution in the fewest lines of code.
The way AI crowd does evaluations is simple: they trigger the running what ever is in run.sh
, and wait for you to generate rollouts using aicrowd_gym.make('NetHackChallenge-v0')
, and they keep track of the scores for each env (which they build for you as above). What you subsequently do with the env is up to you, so adding wrappers is totally fine, as long as at its heart you are running on the right gym environment.
If you are looking at doing this in the starter kit, look at submission_config.py
and the variable MAKE_ENV_FN
. This is the function that is called to create the environment by the rollout.py
and you can see there is already a wrapper which adds a TimeLimit. As youβve already noticed, this wrapper is in env/wrappers.py
and is a sensible place to put your wrappers.
Vis a vis which track you would be entered into if you added this composite action but then did Deep RLβ¦ I donβt think this would constitute a symbolic bot, and would still be using a neural network. Hope this helps

Trying to print out natural-language glyph meanings
Over 3 years agoAnswer:
Glyphs are divided into classes and not all glyphs have easily accessible βnatural languageβ descriptions. For instance, the 4 glyphs that represent the beam of a wand (in each direction) do not have special string in NetHack associated with them. However, for monsters and objects there are ready descriptions. To get something printed out for all the glyphs, use something like:
NB: This answer applies from nle==0.7.2 - before this release, objects give the wrong descriptions
from nle import nethack as nh
obj_classes = {getattr(nh, x): x for x in dir(nh) if x.endswith('_CLASS')}
glyph_classes = sorted((getattr(nh, x), x)
for x in dir(nh) if x.endswith('_OFF'))
for i in range(nh.MAX_GLYPH):
desc = ''
if glyph_classes and i == glyph_classes[0][0]:
cls = glyph_classes.pop(0)[1]
if nh.glyph_is_monster(i):
desc = f': "{nh.permonst(nh.glyph_to_mon(i)).mname}"'
if nh.glyph_is_normal_object(i):
obj = nh.objclass(nh.glyph_to_obj(i))
appearance = nh.OBJ_DESCR(obj) or nh.OBJ_NAME(obj)
oclass = ord(obj.oc_class)
desc = f': {obj_classes[oclass]}: "{appearance}"'
print(f'Glyph {i} Type: {cls.replace("_OFF","")} {desc}' )
Finally, itβs worth noting that the glyph does not give the full state of the object - just how what tile the window should use to render the image. The glyph text above will give you βshort swordβ but not β+1 blessed rusted short swordβ. In NLEβs case the glyph will tell you what the appearance of a potion is, but not what you might have identified it as. For that you should use the GLANCE
or LOOK
commands, where you ask the game to give you a description of whats on a certain tile.
More About Glyph Classes:
What is a Glyph?
From display.h
:
/*
* A glyph is an abstraction that represents a _unique_ monster, object,
* dungeon part, or effect. The uniqueness is important. For example,
* It is not enough to have four (one for each "direction") zap beam glyphs,
* we need a set of four for each beam type. Why go to so much trouble?
* Because it is possible that any given window dependent display driver
* [print_glyph()] can produce something different for each type of glyph.
* That is, a beam of cold and a beam of fire would not only be different
* colors, but would also be represented by different symbols.
*
* Glyphs are grouped for easy accessibility:
*
* monster Represents all the wild (not tame) monsters. Count: NUMMONS.
*
* pet Represents all of the tame monsters. Count: NUMMONS
*
* invisible Invisible monster placeholder. Count: 1
*
* detect Represents all detected monsters. Count: NUMMONS
*
* corpse One for each monster. Count: NUMMONS
*
* ridden Represents all monsters being ridden. Count: NUMMONS
*
* object One for each object. Count: NUM_OBJECTS
*
* cmap One for each entry in the character map. The character map
* is the dungeon features and other miscellaneous things.
* Count: MAXPCHARS
*
* explosions A set of nine for each of the following seven explosion types:
* dark, noxious, muddy, wet, magical, fiery, frosty.
* The nine positions represent those surrounding the hero.
* Count: MAXEXPCHARS * EXPL_MAX (EXPL_MAX is defined in hack.h)
*
* zap beam A set of four (there are four directions) for each beam type.
* The beam type is shifted over 2 positions and the direction
* is stored in the lower 2 bits. Count: NUM_ZAP << 2
*
* swallow A set of eight for each monster. The eight positions rep-
* resent those surrounding the hero. The monster number is
* shifted over 3 positions and the swallow position is stored
* in the lower three bits. Count: NUMMONS << 3
*
* warning A set of six representing the different warning levels.
*
* statue One for each monster. Count: NUMMONS
A glyph is simply a unique id that codes for a visual representation of the dungeon. NetHack provides these to allow different ports of the game to display things however they like. For instance, when you are playing iNetHack, or BrowserHack - two NetHack ports/versions that use image based tiles for the graphical interface - you could make a pet dragon looks could look cuter than a non-pet dragon, and the same for a ridden dragon. The core source code allows developers to easily port to a visual version of the game as they please.
So the glyph id is for unique visualisation of the dungeon, and they are composed as a giant enum. All off the enum offsets are available on the nethack
object in NLE, and you can more closesly look at the static functions and enums by ready /win/rl/pynethack.cc
in the NLE repo.
With objects, the situation gets a little more complicated, as each glyph which is an object (eg ring of polymorph) also has a unique description/material (iron ring) defined statically, but which are then dynamically shuffled at the start of the game. The functions on nethack
are all defined statically, so if the identities have been shuffled (eg for scrolls) OBJ_DESCR
will return the correct description, but OBJ_NAME
will not. So OBJ_NAME
will only be guaranteed to be the correct string, when OBJ_DESCR
is None
(i.e. not used/there is no shuffling).
Learning More
If you want to learn more about glyphs, the best thing to do is to read /win/rl/pynethack.cc
or poke around the nethack
object, or if you want even more complete descriptions try the GLANCE
or LOOK
commands, or (cheat) you can get a text description of an object by picking it up and checking inv_strs
Notebooks
-
IntroToNetHack Welcome to NetHack and the NetHack Learning Environment!eric_hammyΒ· Almost 4 years ago
Are the specs for the machine that the evaluations are run on available anywhere?
Over 3 years agoOne more note: Itβs worth highlighting at this point that the overhead that was being faced was down to communicating βchattilyβ over the network - something that probably could also have been mitigated by moving to of batches of environments, if you were previously operating serially. Thankfully though, AIcrowdβs solution requires no refactoring!