fix!(lua.endpoints): cash_out fires before round-eval rows commit — rewards under-collected, sometimes $0
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 72/100
調査の方向性
src/lua/endpoints/cash_out.lua の requires_state と execute から始め、既存の SHOP 側の待機処理を round-eval フローと比較します。bot.py に影響を受ける ROUND_EVAL caller が示されています。報告された seed または differential-replay のトレースで検証し、cash_out が eval rows を待機し、期待される rewards を維持すれば issue は完了とみなします。
索引モデルが issue の本文から書いたものです。
説明
Description
Calling cash_out as soon as the game reaches ROUND_EVAL collects less money
than the game owes — usually short exactly one blind reward ($3/$4/$5), and
$0 in the worst case. A human cannot reproduce this: the game only spawns the
Cash Out button after the eval rows have finished paying out, but the endpoint
bypasses that gate.
Root Cause
src/lua/endpoints/cash_out.lua:
requires_state = { G.STATES.ROUND_EVAL }(line 22) passes the moment the
state flips, while the dollar rows (blind reward, interest, per-joker payouts)
are still being queued and committed by the event manager.executethen callsG.FUNCS.cash_out({ config = {} })immediately (line 28).
The endpoint carefully waits for the SHOP transition on the response side, but
does not wait for eval completion on the entry side.
Evidence
Found with a differential-replay harness that drives a vanilla-faithful simulator
and balatrobot with identical action traces and deep-diffs the full gamestate
after every action (~1,200 organic games).
- Signature: after cash-out, live money == expected money minus exactly one
blind reward. Confirmed 4× before we added a workaround. - Partial commits happen: one case committed interest but dropped the $5 boss
reward (seedLSOYQISY). - Zero-payout extreme: when
hands_left == 0and there is no interest (the
payout is only the reward row), cash-out commits $0. Reproduced
deterministically across bosses (Psychic, Pillar) and across game sessions
(seedsLSAZ99YB,LS88BC4Z). - Workaround that eliminates it completely: a flat 12s wait before calling
cash_out(normal speed,--no-audio).
The under-collection is irreversible once collected — the money is simply gone
for the rest of the run.
Impact
Any bot that auto-cashes on seeing ROUND_EVAL is systematically poorer than
the game intends. balatrollm does exactly this (bot.py:
case "ROUND_EVAL": ... call("cash_out")), so BalatroBench run economies — and
any result that turns on being a few dollars short in the shop — are affected.
Suggested Fix
Gate execution the way the game gates the button: add a condition event that
waits until the round-eval UI has finished creating its rows (e.g. the Cash Out
button exists), and only then call G.FUNCS.cash_out. This mirrors the
endpoint's existing SHOP-side wait.
We can provide full repro bundles (action trace + both gamestates + field diff
at the divergence step) for any of the seeds above.
- 主要言語
- Python
- スター
- 79
- フォーク
- 23
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
coder/balatrobot のほかの issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
coder/balatrobot#244 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
coder/balatrobot#243 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
coder/balatrobot#235 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
coder/balatrobot#234 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
coder/balatrobot#233 ·
coder/balatrobot の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
earthtojake/text-to-cad#758 ·
メンテナーはふだん 1 日以内に返信
-
domain:upgrades enhancement needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
gke-labs/kube-agents#4634 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
agardnerIT/opamp-server-py#116 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
elviskahoro/sdk-python-attio#144 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信