Skip to content

fix_moon_phase does not pin ubirthday — wall-clock still leaks into seeded games #129

Description

@kenforthewin

Summary

fix_moon_phase=True promises deterministic time-based game effects when seeds are set (per the option docstring: moon phase, friday 13th, night, midnight). The implementation pins the struct tm path via nle_getlt_maybe_fixed() in src/hacklib.c, but ubirthday is still assigned from raw time(NULL) in src/u_init.c, and NetHack hashes ubirthday to vary flavor between games without consuming game RNG:

  • src/shknam.c:517 — shopkeeper name selection (nseed = ubirthday / 257)
  • src/shk.c:2085 — shop surcharge parity (gameplay-relevant)
  • src/mkroom.c:492antholemon() ant species (gameplay-relevant)
  • src/read.c:72 — scroll label hash
  • src/files.c:752 — bones pool selection

getyear() in src/hacklib.c also calls raw getlt(), bypassing the fixed-tm wrapper.

Observed impact

Fully seeded runs (env.seed(core, disp, reseed=False), fix_moon_phase=True, NLE 1.3.0, NetHackChallenge-derived env) of the same seed differ across wall-clock sessions:

  • Shopkeeper names change between sessions (e.g. one seed produced "Ms. Possogroenoe" vs "Mr. Kabalebo" vs "Ms. Manlobbi" in sessions hours apart), while turns/score/deaths stay identical.
  • A longer/shorter name can push a game message across a display page boundary, changing the keypress sequence an agent needs (extra/missing Space), so byte-exact action-trace replay breaks across sessions. In a 1000-trace corpus we saw a ~1.8% cross-session replay-validation failure rate from this.
  • The price-parity and ant-species channels can in principle alter gameplay outcomes, not just cosmetics.

Suggested fix

Derive ubirthday from settings.time_seed when fix_moon_phase && time_seed_is_set, using the same ISAAC64 pattern as nle_fill_fixed_tm(), and route getyear() through nle_getlt_maybe_fixed(). No behavior change when fix_moon_phase is off.

Working patch (verified: same seed run in sessions 96s apart now yields identical action SHA-256 and identical shopkeeper name; no change to any seeded outcome in our regression fixtures): kenforthewin@c8ddc0a

Happy to open a PR from that branch if the approach looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions