forked from facebookresearch/nle
-
Notifications
You must be signed in to change notification settings - Fork 16
Add pixel observations #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
0c32b1d
Some initial experimental code - not for merging
StephenOman c8062bd
more updates - not for merging
StephenOman 8ee7959
test getter
StephenOman a88ddf9
Merge branch 'main' into pixel-experiments
StephenOman 1afe829
test tileset from python
StephenOman 524f9de
Complete functions to get the tileset and the frame from the glyphs
StephenOman 769e23e
Move tile file path control to Python
StephenOman 1b2e154
Merge branch 'main' into add-pixel-observations
StephenOman ade8553
Install tile descriptors into hackdir
StephenOman 22a0913
Expose tile dimensions to Nethack python
StephenOman 5859aa1
Tidy up tile setup code
StephenOman 239a098
Update error handling for frame rendering
StephenOman eddf655
Update test suite for new tile functionality
StephenOman eecf7db
Add documentation for tile usage
StephenOman d968a6a
Add script to generate animated tile gif
StephenOman a7ac1f7
Remove temporary scaffolding files
StephenOman cc77eeb
Merge branch 'main' into add-pixel-observations
StephenOman bd16502
fix CMakeLists.txt lint issues
StephenOman 4ba6f5a
Remove unneeded namespace
StephenOman 7aaaa80
Fix c and c++ lint issues
StephenOman b5cd470
Merge branch 'main' into add-pixel-observations
StephenOman 0a03ae1
Merge conflict edit
StephenOman 6d32c9e
Switch to using target_compile_options to reduce noisy warnings from …
StephenOman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| Using NetHack's tiles for image observations | ||
| ============================================ | ||
|
|
||
| Tiles | ||
| ***** | ||
|
|
||
| NetHack as we know and love is a text based game with characters representing the dungeon | ||
| levels and objects. The RL Environment represents these in an observation numpy array: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| obs[0]["chars"] | ||
|
|
||
| Each character is also associated with a unique glyph id, which is represented in the "glyph" observation: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| obs[0]["glyph"] | ||
|
|
||
| NetHack also contains a set of tile descriptor files which can be used to generate | ||
| the equivalent RGB values so that the game can be rendered as an image-based display. | ||
|
|
||
| The source for the descriptor files are here: | ||
|
|
||
| .. code-block:: console | ||
|
|
||
| win/share/monsters.txt | ||
| win/share/objects.txt | ||
| win/share/other.txt | ||
|
|
||
| When converted to RGB, the full set of tiles looks like this: | ||
|
|
||
| .. image:: https://github.com/NetHack-LE/nle/raw/main/dat/nle/tileset.png | ||
| :alt: NetHack tileset | ||
| :align: center | ||
| \ | ||
|
|
||
| Installation | ||
| ************ | ||
|
|
||
| The tile descriptor files are included in the distribution and are installed in the | ||
| `nethackdir/tiles` directory. | ||
|
|
||
|
|
||
| Initialisation | ||
| ************** | ||
|
|
||
| To get NLE to render the tiles as an observation set, you must set the render_mode to | ||
| "pixel" when the environment is created. For example: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| env = gym.make("NetHack-v0", render_mode="pixel") | ||
|
|
||
| The next step is to add the Gymnasium RenderObservationWrapper to the environment. This | ||
| ensures that every time the envrionment is rendered, the observations will include the | ||
| RGB tile observations automatically. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| env = gym.wrappers.AddRenderObservation( | ||
| env, render_only=False, render_key="pixel", obs_key="glyphs") | ||
|
|
||
| RGB observations | ||
| **************** | ||
|
|
||
| The RGB tiles representing the underlying dungeon can be accessed using the "pixel" | ||
| key in the observations dictionary. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| rgb_frame = obs[0]["pixel"] | ||
|
|
||
| This frame is a 3D numpy array, each 2D slice represents all the pixels in the | ||
| rendered game screen, and the 3rd dimension represents the RGB values for each pixel. | ||
|
|
||
| Example | ||
| ******* | ||
|
|
||
| Here's a short example of how to set up the environment to use the tile-based RGB observations: | ||
|
|
||
| (Note that you need to install the Pillow library to run this example, which can be done with `pip install Pillow`) | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import gymnasium as gym | ||
| from PIL import Image | ||
| import nle | ||
|
|
||
| env = gym.make("NetHack-v0", render_mode="pixel") | ||
| env = gym.wrappers.AddRenderObservation( | ||
| env, render_only=False, render_key="pixel", obs_key="glyphs") | ||
| env.unwrapped.seed(1234, 5678, False, 1) | ||
|
|
||
| obs, _ = env.reset() # each reset generates a new dungeon | ||
| rgb_frame = obs["pixel"] | ||
|
|
||
| # Convert the RGB frame to an image and display it | ||
| img = Image.fromarray(rgb_frame) | ||
| img.show() | ||
|
|
||
|
|
||
| Here's an animated example of what the tile-based rendering looks like | ||
| after a few steps in the environment: | ||
|
|
||
| .. image:: https://github.com/NetHack-LE/nle/raw/main/dat/nle/nethack_tiles_animation.gif | ||
| :alt: NetHack tileset | ||
| :align: center | ||
| \ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| import gymnasium as gym | ||
| from PIL import Image | ||
|
|
||
| import nle # noqa: F401 | ||
|
|
||
| env = gym.make("NetHack-v0", render_mode="pixel") | ||
| env = gym.wrappers.AddRenderObservation( | ||
| env, render_only=False, render_key="pixel", obs_key="glyphs" | ||
| ) | ||
| env.unwrapped.seed(1234, 5678, False, 1) | ||
|
|
||
|
|
||
| frames = [] | ||
|
|
||
| obs = env.reset() | ||
| frame = obs[0]["pixel"] | ||
| img = Image.fromarray(frame, "RGB") | ||
| frames.append(img) | ||
|
|
||
| NORTH = 0 | ||
| WEST = 3 | ||
| SOUTH = 2 | ||
| EAST = 1 | ||
|
|
||
| # Get out of starting room | ||
| steps = [EAST, EAST, NORTH, NORTH, WEST, WEST, WEST, WEST, WEST] | ||
| # Go to room two | ||
| steps += [ | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| WEST, | ||
| SOUTH, | ||
| WEST, | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| SOUTH, | ||
| WEST, | ||
| SOUTH, | ||
| WEST, | ||
| WEST, | ||
| ] | ||
| # Traverse room two | ||
| steps += [WEST, WEST, WEST, WEST, NORTH, NORTH, NORTH, NORTH] | ||
| # Go to room three | ||
| steps += [ | ||
| WEST, | ||
| NORTH, | ||
| NORTH, | ||
| WEST, | ||
| WEST, | ||
| NORTH, | ||
| NORTH, | ||
| WEST, | ||
| WEST, | ||
| NORTH, | ||
| NORTH, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| WEST, | ||
| NORTH, | ||
| ] | ||
| # Traverse room three | ||
| steps += [NORTH, NORTH] | ||
| # Go back towards room two and kill the monster | ||
| steps += [SOUTH, SOUTH, SOUTH, EAST, EAST, EAST, EAST, EAST] | ||
| # Continue to room two | ||
| steps += [ | ||
| EAST, | ||
| EAST, | ||
| EAST, | ||
| SOUTH, | ||
| SOUTH, | ||
| EAST, | ||
| EAST, | ||
| SOUTH, | ||
| SOUTH, | ||
| EAST, | ||
| EAST, | ||
| SOUTH, | ||
| SOUTH, | ||
| EAST, | ||
| SOUTH, | ||
| SOUTH, | ||
| ] | ||
| # Traverse room two to other exit | ||
| steps += [WEST, WEST, WEST, WEST, WEST, WEST, WEST, WEST, WEST, NORTH] | ||
| # Go to room four | ||
| steps += [NORTH, NORTH, NORTH, NORTH] | ||
|
|
||
| for action in range(len(steps)): | ||
| obs = env.step(steps[action]) | ||
| env.unwrapped.nethack.draw_frame(frame) | ||
| img = Image.fromarray(frame, "RGB") | ||
| frames.append(img) | ||
|
|
||
| print(f"Saving animation with {len(frames)} frames...") | ||
| frames[0].save( | ||
| "nethack_tiles_animation.gif", | ||
| save_all=True, | ||
| append_images=frames[1:], | ||
| duration=400, | ||
| loop=0, | ||
| ) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.