G.FUNCS.evaluate_play wrapper install survive a load-order race. The install was previously a top-level if G.FUNCS and G.FUNCS.evaluate_play then …; if SMODS dofile'd the mod before state_events.lua defined evaluate_play, the wrapper silently never installed for the entire session — F2 and F4 still worked, but no miss was ever logged or captured. The install is now wrapped in an idempotent function, prints a WARNING on first-attempt failure, and re-tries from a Game:start_run override before any scoring happens.ability.forced_selection so fixtures round-trip through the offline harness.evaluate_play wrapper crashing with "attempt to get length of a number value" on debuffed-by-blind plays and on Psychic with <5 cards. Both score_combo short-circuits now return {} for the prob_arities slot to match the normal-path contract.hands_left after evaluate_play returns, not before, so the simulation made Acrobat fire when the live game still skipped it, over-predicting by ×3 on any final-hand fixture with Acrobat. Acrobat/Dusk now fire iff hands_left is already 0 at scoring time (the original 1.0.7 behavior).(or [tied alternate hand]) suffix from F2 prediction output — it was cluttering the line.G.GAME.current_round.hands_left == 0, but Balatro decrements hands_left before evaluate_play fires; at prediction time it still holds the pre-play value, so the condition failed and the predictor under-scored the last play. The analysis path now simulates the decrement when hands_left == 1.evaluate_play is invoked, so native crashes inside Balatro / SDL2 / love.dll (which bypass SMODS's love.errorhandler and leave no traceback in the lovely log) leave a crash_<ts>_N.lua behind with the exact inputs that triggered the fault. The file is deleted on normal return; only a true crash preserves it. batch_verify.lua ignores crash_*.lua since they have no actual_score.base.id / base.suit underneath the enhancement, and card_label was reading those directly. Scoring was unaffected — Stones now display as Stone.get_triggers reads retrigger joker counts from the per-call precomputed bundle instead of building a fresh joker_names list every call; straight detection drops a 14-element scratch array; eval_per_card_jokers' Bloodstone fallback skips a per-card allocation for non-Blueprint/Brainstorm jokers; Lucky Cat / Space Joker scans gated on presence flags. No effect on scoring — verified against 135 captures + 1000 synthetic fixtures.joker_main reads hands[name].played pre-bump, so each copy was scoring one play short.played_this_round > 1 reads the pre-bump value), so each copy was missing its X3.dollar_buffer, causing Bootstraps' joker_main to under-count by 2 mult per $5 of payout when that outcome was selected during enumeration.(1.0.3 was tagged but never shipped — BestHand.json was not bumped, so release.ps1 failed in CI. 1.0.4 contains the same fixes plus the version bump.)
prob_config now enumerates that outcome (3 per Lucky card: none / mult / dollars-only) and the EV lucky_trigger rate is corrected from 1/5 to 19/75.context.other_joker reaction once for the real card and once for each copy.G.GAME.dollars during analysis — vanilla get_p_dollars bumps dollar_buffer for Gold seals during the per-card phase, so the Phase-3 joker loop now mirrors that bump using the already-tracked scoring_dollars.Initial release.
Card:calculate_joker (context.before → per-card → context.joker_main), so each joker scores with the same code the game runs.best_hand_captures/ for offline regression.