Wish generator & validator

3.6 · 3.7 · 5.0

Build a wish, get the string to paste into the prompt — and, more usefully, find out which parts of it the game is actually going to honor. Enchantment above +2 is a dice roll, charge counts are capped at whatever mksobj() happened to roll, several adjectives are quietly discarded when your Luck is negative, and a few objects are swapped out from under you before they are even created. Every rule here was read out of readobjnam() in src/objnam.c and mksobj() in src/mkobj.c, and each one cites its line.

Game state
Version
3.7 and 5.0 parse wishes identically — the generator diffs readobjnam() between the two branches on every run and fails if they ever diverge.
Luck
Negative Luck turns "blessed" into cursed, drops erodeproof and poison, and flips any surviving enchantment above +2.
Counting the one you are about to wish for. Only matters for artifact wishes. If you have not seen any yet, leave it at 1.
Build the wish
Picking an artifact replaces the object above: the base item comes from artilist[].

Beatitude
Blank means "do not say", which leaves the randomly rolled value alone.
Only mergeable objects can stack.
Adjectives
Type this at the prompt

readobjnam_preparse() loops over the adjectives, so their order does not matter to the parser — this is the order the game itself prints them in doname(), which is the least surprising thing to type back.

Where the versions disagree
RuleNetHack 3.6NetHack 3.7 / 5.0Source
What this does and does not cover

This is a model of readobjnam(), not of the whole game. It tells you how your wish string will be parsed and which requests survive. It does not tell you what to wish for — for that, read Wish on NetHackWiki.

Assumptions and known gaps

Wizard mode is not modelled. Every rule below is the !wizard path. In debug mode the enchantment roll, the quantity test, the artifact roll and the object substitutions are all skipped.

Experience level. The random enchantment mksobj() rolls is rne(3), whose cap is (u.ulevel < 15) ? 5 : u.ulevel / 3. All probabilities here use the cap of 5. Above XL 17 that cap rises, so requests of +6 and higher stop being exactly impossible and become merely absurd — of order one in ten thousand.

Default beatitude is not quantified. When you do not say blessed, uncursed or cursed, the item keeps whatever blessorcurse() rolled inside mksobj(). That chance varies by object class and by object, and this tool does not enumerate it — it only tells you that the roll happened.

Not modelled at all: wizard-mode terrain and trap wishes, glob sizes, fruit names, corpses and statues of specific monsters, tin varieties, eroded and diluted items, box lock states, and the named / called / labeled suffixes. readobjnam() accepts all of them; this builder does not emit them.

Artifact counting. The failure roll uses nartifact_exist(), which counts every artifact that has come into existence — including ones generated on the floor, in a monster's inventory or in a bones file, which you may never have seen. The number you type in is a guess, and so is the answer.