Commit be18f2a
0.5.0 Merge (#476)
* chore(release): bump version to 0.4.1~DEV
* fixes (#462)
* Update standard.lua
WSOB Ruleset lets go
* Add WSOB as tournament ruleset; bump version (#470)
* feat(rulesets): add WSOB tournament ruleset; restore standard layer
The "WSOB Ruleset lets go" change had gutted the shared `standard`
layer, which silently rebalanced every standard-composed ruleset
(Blitz, Traditional, Ranked, SmallWorld, Speedlatro, Chaos). Revert
standard.lua to its pre-WSOB form and move those settings into a
dedicated WSOB ruleset instead.
- rulesets/wsob.lua: near-vanilla tournament pool (multiplayer_content
off, only Hanging Chad/Bloodstone/Glass reworked, Justice banned),
gated on the ranked layer for version locking
- objects/enhancements/mp_glass.lua: extend Glass rework to "wsob"
- en-us.lua: k_wsob name + description
- ruleset_selection.lua: wire WSOB into the Tournaments tab
* refactor(ui): drop dead ruleset_buttons_data
Orphaned since the tabbed-ruleset refactor (#419), which switched every
consumer to `rulesets_tabs` but left this file-local defined and unused.
Zero references; pure dead allocation.
* chore(release): bump version to 0.4.3~DEV
* feat(mutators): turn challenge effects into a wall of stackable run modifiers (#471)
* Extract challenge effects into toggleable mutator layers + Wraith rework
Move the runtime effects from the eeeee, balancing_act (score
instability), polymorph_spam, and shared_pockets challenges into
layers/, gated on their existing G.GAME.modifiers.mp_* flags. Each
layer sets its flag from on_apply_bans at run start, so the effect can
be toggled as a mutator on any ruleset; the challenges keep their
rules.custom and now share one hook implementation (deduped). Surface
each on the mutator wall.
Add a wraith_rework layer: new c_mp_wraith consumable (random Uncommon
joker + $5, vs vanilla's random Rare + money to $0), gated via
reworked_consumables with the vanilla c_wraith banned_silent.
Also a stylua normalization pass touched bacon/planet_tycoon.
* fix broken wraith
* Wire up custom ruleset editor Play button (Path 1)
Custom tab now launches a run with a chosen base ruleset + the mutators
wall's modifier stack. Maps content sets (Vanilla/Standard/Sandbox/
Experimental) to base rulesets, sets the ruleset directly without routing
through apply_default_modifiers (which would wipe MP.MODIFIERS), then
LoadReworks + the normal start flow. Modifiers sync to the guest via the
existing modifier_layers serialization.
Custom card bans are gated behind a coming-soon pill (not yet threaded into
ApplyBans or network sync). Removed the COMING SOON ribbon.
* Remove coming-soon line from mutators wall
Drop the 'coming soon · Reward Draft · Rubber Band · Score Tax' footer and
the unused SOON table that fed it. Stub layers in mutator_stubs.lua are
untouched.
* Add No Red Seals mutator layer
New no_red_seals layer: bans Deja Vu and wraps Card:set_seal to refuse Red
assignments (RNG-neutral, so both clients no-op the same seal and stay
synced; the slot just goes sealless). Wired into the HAZARDS column of the
mutators wall alongside No Easy Money / No Uncommons.
* Disable not-yet-working mutators + stub custom editor on lobby path
Mark Inflation, No Interest, Discard Tax, Frugal, and Blind Poker as
coming-soon: greyed/un-toggleable cells with a "Coming soon." hover, and
skipped by the Randomize / Blind Random rolls so they can never activate.
Gate the custom ruleset editor to a coming-soon panel on the lobby (mp)
path; sp/practice keep the full editor.
* Disable Spartan and Pricey Packs mutators (not yet working)
* Surface the three stub mutators on the wall as coming-soon cells
Reward Draft, Rubber Band and Score Tax (the unwired layers from
mutator_stubs.lua) now appear as disabled "Coming soon." cells instead of
being invisible.
* Disable Heavy Pockets + No Takebacks; keep desc on coming-soon tooltips
Disabled mutator cells now show their full description with a trailing
"(Coming soon)" line instead of replacing the text outright.
* Disable Cash Ceiling mutator (not yet working)
* Strip LLM-flavored comment noise from mutator layers
Drop the seam/contract/MP-safe explanatory essays and fake file:line
citations; keep the human voice. Also removes the dormant, unreferenced
sticker_shop layer.
* Add credit badges to mutator wall tooltips
Reuse the MULTIPLAYER credit-badge look (float DynaText pill) from
mod_badges.lua as a standalone builder, dropped into the cell tooltip via
create_popup_UIBox_tooltip's filler hook so it only shows on hover. Cells
opt in with a credits = { art/idea/code } field. Rotation skips the
MULTIPLAYER header — one credit shows static, multiple rotate.
Seeded credits for the cells we know: Kars (idea) on Inflation and No Easy
Money, plus a few code credits.
* Casjb/full replay (#473)
* feat(replay): dual-stream deterministic action log (MP.RLOG)
Add a fully-recreatable action logging system. Every state-affecting
player action emits two aligned streams from one record() call:
- Carbon-copy (replay) stream: positional opcodes (e.g. "buy 1 2") with
no card names, so it is indiscriminate and replays across mods. Written
to a dedicated ".carbon" sidecar next to the Lovely log (NOT the mod
folder, so version hotswaps don't disturb it).
- Human stream: mirrored into the carbon file; the player-facing Lovely
log is left byte-for-byte unchanged so the website parser is undisturbed.
Both streams are hashed at game end (joker_hash) and submitted to the
server via the new submitLogHashes action for cheap tamper detection.
Coverage: buy/open_pack/voucher, reroll, sell, use, play, discard,
pack_pick/skip, select/skip blind, ready, joker/hand reorder, the random
ante_key, and net_* opponent effects (phantom/magnet/pizza/asteroid).
Instrumentation extends existing overrides; reorder uses a Preview-
independent debounced CardArea:update detector.
This is the logging system only; the replay runner and server-side hash
storage are follow-ups.
Tests: tests/test_rlog_roundtrip.lua, tests/test_rlog_checksum.lua
(both pass on Lua 5.4).
🤖 Commit message generated by Claude Code (https://claude.com/claude-code)
* refactor(replay): emit both streams into the Lovely log, drop .carbon file
Per design change: keep the carbon (replay) and human-readable streams in the
same Lovely log, separated by prefix, instead of a dedicated .carbon sidecar.
- Carbon stream now logs under the "MP_RLOG:" prefix (MANIFEST / action lines /
CHK trailer); the human stream keeps the existing "Client sent message:" prefix.
- record() is now the sole emitter of both lines, so the instrumented overrides
(buy/sell/reroll/use) no longer log the human line themselves.
- Remove the .carbon file writer, path derivation, flush(), and the per-round
flush call. Both stream buffers are still hashed at end_run and re-derive from
the log by prefix.
- Rework the tests to capture sendTraceMessage output (no file) and update docs.
Tests: tests/test_rlog_roundtrip.lua, tests/test_rlog_checksum.lua pass on Lua 5.4.
🤖 Commit message generated by Claude Code (https://claude.com/claude-code)
* feat(replay): ship the full carbon log to the server, not just its hash
end_run now accumulates the full carbon block (manifest + action lines + END +
CHK) and sends it as a `log` field on submitLogHashes, so the server can store a
complete viewable/replayable record of every game without the player handing
over their log. Hashing is unchanged (still over the action/human buffers).
🤖 Commit message generated by Claude Code (https://claude.com/claude-code)
* feat(serialization): guard str_decode_and_unpack against zip-bomb payloads
Reject an encoded payload larger than MAX_ENCODED_BYTES (32 KB) before any
base64/gzip work, so a crafted magnetResponse / receiveEndGameJokers /
receiveNemesisDeck payload can't balloon to GBs and OOM the receiving client.
A legitimate saved joker / nemesis deck is a few KB; both callers already bail
cleanly on the nil return. Defense-in-depth — the relay also caps message size.
Adds tests/test_serialization_guard.lua.
🤖 Commit message generated by Claude Code (https://claude.com/claude-code)
* chore(mod): bump version to 0.4.3 for the replay-log pre-release build
🤖 Commit message generated by Claude Code (https://claude.com/claude-code)
* fix(replay): crash-proof area_enum (table index is nil on shop buy)
area_enum built a lookup table keyed by the CardArea globals, but several of
them are nil depending on game state (G.pack_cards only exists while a booster
is open, G.shop_* only in the shop). A table literal with a nil key throws
'table index is nil', so any buy/sell/use while one of those areas was absent
crashed the game — reproducibly on the first shop purchase. Compare the area
against each global directly instead (a live area vs a nil global is just
false), which is crash-safe and returns the same enum.
Commit message generated with Claude Code
* feat(replay): stream carbon lines live to the server in batches
While a game plays, MP.RLOG now batches its carbon lines and flushes them to the
server (new streamLogLines action) every ~25 lines or ~2s, under a per-game id
generated in begin_run. So a crashed/abandoned game still leaves a partial
record server-side; on a clean end, submit_log_hashes carries the same game id
so the server swaps the live stream for the complete hashed package. Flushing
falls back to the line-count trigger when love.timer is unavailable (tests), and
no-ops cleanly when there's no transport. Adds tests/test_rlog_stream.lua.
Commit message generated with Claude Code
* Hide opponent score until first hand played (#475)
* Show ??? for opponent score until first hand of a PvP blind
Display the opponent's score as "???" in the blind HUD until the local
player has played a hand in the current PvP blind, matching the server's
withholding of enemyInfo. Reset the stored opponent score at the start of
each blind so the first frame after playing shows 0 rather than the
previous blind's stale score.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LgfBstKG4gLVbu4JKUQFnn
* Add hide_score_until_played lobby option (default on for standard layer)
Expose the opponent-score hiding as a host-toggleable lobby option. It
defaults on only for standard-layer rulesets (start_lobby derives it from
MP.current_ruleset().standard) and off everywhere else; the baseline config
value is off. The blind HUD only masks the opponent score as "???" when the
option is enabled. The toggle lives in the lobby options tab, so it is
editable in non-forcing lobbies and locked at its default when a ruleset
forces options.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LgfBstKG4gLVbu4JKUQFnn
* Mask opponent hands as "?" until the first enemy info each blind
While the opponent's score is hidden, their hands count previously still
showed its stored value. Track an info_received flag on MP.GAME.enemy
(reset at blind start, set when an enemyInfo arrives) and drive a new
hands_text field, shown in place of the raw count. When the hide-score
option is on, the HUD shows "?" for opponent hands until the first enemy
info of the blind; otherwise it mirrors the real count as before. Ghost
replays mark info as received so replays are never masked.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LgfBstKG4gLVbu4JKUQFnn
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Various fixes (#472)
* Timer: prevent old timer tick when ready + more correct check when can timer opponent
* TheOrder: fix SMODS seals desync
* Networking: try-catch for server messages + resolve channel once
* UI: fix ko-fi message display & crash
* CardAreas: fix crash in Shared Pockets + make shared area move in place instantly
* fix old timer not tick when you timer opponent
* Update Phantom Edition Text (#464)
The current phantom edition text is somewhat confusing, this looks to
make it clear what this edition does.
* feat: update vietnamese's localization (wip) (#468)
* Season 7 changese
---------
Co-authored-by: Stephen Kirk <me@thestephen.net>
Co-authored-by: SleepyG11 <35398172+SleepyG11@users.noreply.github.com>
Co-authored-by: Fantom-Balatro <fantombalatro@gmail.com>
Co-authored-by: Casper JB <casper_jb@icloud.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: EchoHeli <emiliano.dorantest@gmail.com>
Co-authored-by: Trần Quốc Lân <62930566+minotour4869@users.noreply.github.com>1 parent 611c5a7 commit be18f2a
43 files changed
Lines changed: 1288 additions & 542 deletions
File tree
- layers
- lib
- localization
- lovely
- networking
- objects
- challenges
- consumables
- enhancements
- jokers/standard
- rulesets
- ui
- game
- lobby/_lobby_options
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
| 200 | + | |
| 201 | + | |
200 | 202 | | |
201 | 203 | | |
202 | 204 | | |
| |||
217 | 219 | | |
218 | 220 | | |
219 | 221 | | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
220 | 226 | | |
221 | 227 | | |
222 | 228 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
| 1 | + | |
12 | 2 | | |
13 | 3 | | |
14 | 4 | | |
| 5 | + | |
15 | 6 | | |
16 | 7 | | |
17 | 8 | | |
18 | 9 | | |
19 | | - | |
| 10 | + | |
20 | 11 | | |
21 | 12 | | |
22 | 13 | | |
23 | 14 | | |
24 | | - | |
| 15 | + | |
25 | 16 | | |
26 | 17 | | |
27 | 18 | | |
28 | 19 | | |
29 | | - | |
30 | | - | |
| 20 | + | |
31 | 21 | | |
32 | 22 | | |
33 | 23 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | 1 | | |
9 | 2 | | |
10 | 3 | | |
11 | 4 | | |
12 | | - | |
13 | | - | |
14 | 5 | | |
15 | 6 | | |
16 | 7 | | |
17 | 8 | | |
18 | | - | |
19 | | - | |
20 | 9 | | |
21 | 10 | | |
22 | 11 | | |
23 | 12 | | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | 13 | | |
38 | 14 | | |
39 | 15 | | |
40 | 16 | | |
41 | | - | |
42 | | - | |
43 | 17 | | |
44 | 18 | | |
45 | 19 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
| 1 | + | |
| 2 | + | |
13 | 3 | | |
14 | 4 | | |
15 | 5 | | |
16 | | - | |
| 6 | + | |
17 | 7 | | |
18 | 8 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
24 | 12 | | |
25 | 13 | | |
| 14 | + | |
26 | 15 | | |
27 | 16 | | |
28 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
| 1 | + | |
12 | 2 | | |
13 | 3 | | |
14 | | - | |
15 | | - | |
16 | | - | |
| 4 | + | |
17 | 5 | | |
18 | 6 | | |
19 | 7 | | |
20 | | - | |
21 | | - | |
22 | 8 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
0 commit comments