Skip to content

feat: add deepwolf replay command#23

Open
MichisGitIsKing wants to merge 1 commit into
JuneQQQ:mainfrom
MichisGitIsKing:feat/replay-command
Open

feat: add deepwolf replay command#23
MichisGitIsKing wants to merge 1 commit into
JuneQQQ:mainfrom
MichisGitIsKing:feat/replay-command

Conversation

@MichisGitIsKing

Copy link
Copy Markdown

Hey @JuneQQQ!

Here's the replay command you asked for in #16.

What's new

deepwolf replay PATH — loads a saved transcript JSON and re-renders the game to the terminal, same coloured event stream as simulate.

  • transcript.py: added Transcript class, load(), and _event_from_json() to reconstruct Event objects from saved transcripts
  • cli.py: new replay subcommand with optional --delay flag (seconds between events, default 0 = instant)
  • 4 new tests: load reconstruction, round-trip (simulate → save → load → verify), event type integrity, and CLI end-to-end

All three CI checks pass (ruff, mypy, pytest — 63/63).

The replay just re-emits stored events through the existing renderer — no GameState rebuild needed, exactly as you suggested.

Closes #16

Load a saved transcript JSON and re-render the game to the terminal,
using the same coloured event stream as `simulate`.

- `transcript.py`: add `Transcript` class, `load()`, and `_event_from_json()`
  to reconstruct Event objects from a saved transcript
- `cli.py`: add `replay PATH` subcommand with optional `--delay` between events
- Tests: round-trip (simulate → save → load → verify), CLI end-to-end

Closes JuneQQQ#16

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JuneQQQ

JuneQQQ commented May 20, 2026

Copy link
Copy Markdown
Owner

Thanks for picking this up @MichisGitIsKing — and great follow-through on #16. 🙏

The implementation is clean: reusing _print_event for the event stream is exactly right (no GameState rebuild needed, just re-emit through the renderer), and the four tests are well-scoped. Two real issues to address before this can merge, plus one small nit:

1. The bilingual invariant is dropped on the result panel

deepwolf has a strict bilingual invariant (en/zh via deepwolf.i18n, see #15) — every player-facing string goes through Translator so the whole game (event log, roles, result panel) renders in the chosen language. Your replay rebuilds the result panel inline and hardcodes English:

  • Transcript.winner_label returns "the Village" / "the Werewolves" (transcript.py)
  • cmd_replay writes "survived" / "died day N" and the panel title as English literals (cli.py)

A Chinese-language transcript replayed today would render its event log in Chinese (event .text is stored verbatim) but its result panel in English — that's the regression.

The cleanest fix is to store lang in the transcript itself and use the existing Translator for the panel. Concretely:

# transcript.py to_json — add one line:
"lang": ...   # I can point you at where to pull this from GameResult

# Transcript / cmd_replay:
from deepwolf.i18n import Translator, pick
tr = Translator(self.lang)
title = pick(self.lang, f"{tr.faction_label(self.winner)} win",
                       f"{tr.faction_label(self.winner)}获胜")
# and use pick(..., "survived", "存活") / pick(..., f"died day {d}", f"第 {d} 天死亡")

For the lang field on GameResult — currently it isn't stored on the result, only on GameConfig. Easiest path: thread it through to_json by also accepting (or reading from) the config, or add lang to GameResult. I'm fine with either; flag if you'd like guidance.

2. The branch is dirty against current main

Calibration follow-ups landed since you forked (#21, #22), so cli.py has new neighbours where you're inserting cmd_replay and the replay subparser. A rebase should resolve it without code changes — both additions are non-overlapping with the calibration code.

3. Tiny nit

A negative --delay (user typo) would raise from time.sleep. A max(0.0, args.delay) or a parser-level type= validator would be friendly.

Otherwise

  • _event_from_json correctly inverts event_to_json (frozenset reconstruction, EventType conversion). ✅
  • The CLI end-to-end test (test_replay_cli_runs_without_error) is a nice touch.
  • I've approved the workflow run so you can see the full CI go green on this branch.

Rebase + the bilingual fix and I'll merge promptly. Sorry for the moving target on cli.py — the calibration work landed in parallel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a deepwolf replay command

2 participants