Shawn M Moore
and 3 contributors


NetHack::Menu - parse and interact with a NetHack menu


version 0.08


    use NetHack::Menu;
    my $menu = NetHack::Menu->new(vt => $term_vt102);

    # compile all pages of the menu
    until ($menu->at_end) {

    # we want to stuff all blessed items into our bag
    $menu->select(sub { /blessed/ });

    # but we don't want things that will make our bag explode
    $menu->deselect(sub { /cancell|bag.*(holding|tricks)/ });



NetHack requires a lot of menu management. This module aims to alleviate the difficulty of parsing and interacting with menus.

This module is meant to be as general and flexible as possible. You just give it a Term::VT102 object, send the commands it gives you to NetHack, and update the Term::VT102 object. Your code should look roughly the same as the code given in the Synopsis.


new (vt => Term::VT102, select_count => (single|multi)) -> NetHack::Menu

Takes a Term::VT102 (or a behaving subclass, such as Term::VT102::Boundless or Term::VT102::ZeroBased). Also takes an optional select_count which determines the type of menu. NetHack::Menu cannot intuit it by itself, it depends on the application to know what it is dealing with. Default: multi.

select_count [single|multi] -> (single|multi)

Accessor for select_count. Default: multi.

WARNING: No-select menus are potentially ambiguous with --More--. See below.

has_menu -> Bool

Is there currently a menu on the screen?

at_end -> Bool

This will return whether we've finished compiling the menu. This must be called for each page because this is what does all the compilation.

Note that if there's no menu, this will croak.

all_items -> [ NetHack::Menu::Item ]

Returns all items in the menu.

selected_items -> [ NetHack::Menu::Item ]

Returns all selected items in the menu.

next -> Str

Returns the string to be used to get to the next page. Note that you should not ignore this method and use > or a space if your menu may not start on page 1. This method will make sure everything is hunky-dory anyway, so you should still use it.

select Code

Evaluates the code for each item on the menu and selects those which produce a true value. The code ref receives $_ as the text of the item (e.g. a blessed +1 quarterstaff (weapon in hands)). The code ref also receives the item's selector (the character you'd type to toggle the item) as an argument.

Note that you can stack up multiple selects (and deselects) before eventually finishing the menu with $menu->commit.

Do note that selecting is not the same as toggling.

This currently returns no useful value.

select_quantity Code

Same as select, but instead of returning a truth value the coderef should return undef (if no change is to be made for this item), a non-negative integer (to select a specific amount), or the special string 'all'.

deselect Code

Same as select, but different in the expected way. :)

commit -> Str

This will return the string to be sent that will navigate the menu and toggle the requested items.


  • Not everyone uses the default ^, |, and > menu accelerators. Provide a way to change them.

  • Not everyone uses Term::VT102. Provide some way to pass in just a string or something. This will be added on an if-needed basis. Anyone?


No-select menus

Unfortunately, NetHack uses the string --More-- to indicate a no-select menu. This is ambiguous with a list of messages that spills over onto another "page".

The expected way to handle no-select menus is to:

Look at the topline
Decide if the topline is a no-select menu

This can be done by looking to see if it contains, for example, "Discoveries". Note that "Things that are here" can appear on the third line. Argh!

If so, use NetHack::Menu
Otherwise, hit space


  • Shawn M Moore <>

  • Stefan O'Rear <>


This software is copyright (c) 2013 by Shawn M Moore.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.