Open
Conversation
Use position 2 for better alignment and give Jimbo a more in-character, playful hint message.
Match recording (snapshot_ante, init, finalize) was dead code — written but never read. Replays will come from Lovely log files instead. Removes the table, all methods, and all call sites in action_handlers and game_state.
Utility predicate doesn't belong in a UI monkey-patch file. Moved to lib/ where MP.GHOST lives, which loads before ui/.
More descriptive local name for the module table, consistent with how it's used by callers via pcall/load_mp_file.
The .json path is mainly for verifying the Lua log parser against the Python tool output. Extracted to load_json_replay() with a comment explaining its purpose. The .log branch is now checked first as the primary code path.
Moved is_ruleset_supported, format_score, and build_label from the picker UI file to MP.GHOST in the lib layer where they belong.
File no longer contains match recording — it's purely ghost replay load/playback logic now.
…eplay.lua Move inline ghost replay branching into focused helpers: - resolve_pvp_hands_exhausted, resolve_pvp_mid_hand, resolve_round_fail - get_blind_name_ui, current_target, _start_advance_sequence
All replay sources now emit per-hand data. The fallback path that set a static enemy score from ante-level aggregates was vestigial. Removes get_enemy_score(), the else-branch in init_playback(), and the current_target() wrapper — its sole callsite now uses current_target_big() directly.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Practice mode lets you replay past matches. Pick a recorded game, choose which side to play, and the other side's scoring plays back hand-by-hand while you play live. Same seed, same blinds, same ruleset — different you.
Replay sources are Lovely
.logfiles or exported.json. Drop them inreplays/and they show up in the picker.What's new
A full replay practice flow: browse recorded matches in a two-column picker (match list + detail panel with joker sprites), flip which side you play as, then run the game with MP rulesets and blind progression. Between rounds, open the collection and click to spawn cards. Toggle unlimited slots or edition cycling as needed.
Internals:
lib/practice_mode.lua—MP.SPstate,MP.is_practice_mode()lib/ghost_replay.lua— replay engine: per-ante hand playback, PvP resolution, advance animationlib/log_parser.lua— parses.logfiles into structured replay data; also accepts.jsonui/.../ghost_replay_picker.lua— two-column picker with match details and joker spriteslovely/practice.toml— key/click patches for card spawning (3/click) and edition cycling (Q)MP.is_mp_or_ghost()— replacesMP.LOBBY.codechecks across blind, HUD, round, and end-round paths; suppresses network actions behindnot MP.GHOST.is_active()guardsMP.get_active_gamemode()— centralized resolution (lobby → replay → ruleset). Fixes a prior bug where the replay's gamemode bled intoMP.LOBBY.configState isolation
Replay/practice state must never leak into real MP.
action_start_game()(both networking stacks),setup_run_singleplayer(),start_vanilla_sp(), andstart_lobby()all clear practice and replay state. Network actions are gated onnot MP.GHOST.is_active(). Gamemode reads from replay state, not lobby config.Known issues
should_use_the_order()returns true unconditionally for practice mode. Should check the active ruleset. Intentional deferral.Test plan
.log/.jsonintoreplays/, verify they appear in the picker3), toggle unlimited slots, cycle editions (Q)